blob: 9a5a42def5148e58c0f574e2a0f87f7a0046c1e2 [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"
Yushin Cho77bba8d2016-11-04 16:36:56 -070052#if CONFIG_PVQ
53#include "av1/encoder/pvq_encoder.h"
54#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070055#if CONFIG_DUAL_FILTER
56#if CONFIG_EXT_INTERP
57static const int filter_sets[25][2] = {
58 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 1, 0 }, { 1, 1 },
59 { 1, 2 }, { 1, 3 }, { 1, 4 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
60 { 2, 4 }, { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 4, 0 },
61 { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 4 },
62};
63#else
64static const int filter_sets[9][2] = {
65 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 },
66 { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 },
67};
68#endif
69#endif
70
71#if CONFIG_EXT_REFS
72
73#define LAST_FRAME_MODE_MASK \
74 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
75 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
76#define LAST2_FRAME_MODE_MASK \
77 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
78 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
79#define LAST3_FRAME_MODE_MASK \
80 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
81 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
82#define GOLDEN_FRAME_MODE_MASK \
83 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
84 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
85#define BWDREF_FRAME_MODE_MASK \
86 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
87 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
88#define ALTREF_FRAME_MODE_MASK \
89 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
90 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
91
92#else
93
94#define LAST_FRAME_MODE_MASK \
95 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
96#define GOLDEN_FRAME_MODE_MASK \
97 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
98#define ALTREF_FRAME_MODE_MASK \
99 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
100
101#endif // CONFIG_EXT_REFS
102
103#if CONFIG_EXT_REFS
104#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
105#else
106#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
107#endif // CONFIG_EXT_REFS
108
109#define MIN_EARLY_TERM_INDEX 3
110#define NEW_MV_DISCOUNT_FACTOR 8
111
112#if CONFIG_EXT_INTRA
113#define ANGLE_FAST_SEARCH 1
114#define ANGLE_SKIP_THRESH 10
115#define FILTER_FAST_SEARCH 1
116#endif // CONFIG_EXT_INTRA
117
118const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
119 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
120
121typedef struct {
122 PREDICTION_MODE mode;
123 MV_REFERENCE_FRAME ref_frame[2];
124} MODE_DEFINITION;
125
126typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
127
128struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700129 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700130 MACROBLOCK *x;
131 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
132 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800133 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700134 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};
140
141#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700142static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700143 { NEARESTMV, { LAST_FRAME, NONE } },
144#if CONFIG_EXT_REFS
145 { NEARESTMV, { LAST2_FRAME, NONE } },
146 { NEARESTMV, { LAST3_FRAME, NONE } },
147 { NEARESTMV, { BWDREF_FRAME, NONE } },
148#endif // CONFIG_EXT_REFS
149 { NEARESTMV, { ALTREF_FRAME, NONE } },
150 { NEARESTMV, { GOLDEN_FRAME, NONE } },
151
152 { DC_PRED, { INTRA_FRAME, NONE } },
153
154 { NEWMV, { LAST_FRAME, NONE } },
155#if CONFIG_EXT_REFS
156 { NEWMV, { LAST2_FRAME, NONE } },
157 { NEWMV, { LAST3_FRAME, NONE } },
158 { NEWMV, { BWDREF_FRAME, NONE } },
159#endif // CONFIG_EXT_REFS
160 { NEWMV, { ALTREF_FRAME, NONE } },
161 { NEWMV, { GOLDEN_FRAME, NONE } },
162
163 { NEARMV, { LAST_FRAME, NONE } },
164#if CONFIG_EXT_REFS
165 { NEARMV, { LAST2_FRAME, NONE } },
166 { NEARMV, { LAST3_FRAME, NONE } },
167 { NEARMV, { BWDREF_FRAME, NONE } },
168#endif // CONFIG_EXT_REFS
169 { NEARMV, { ALTREF_FRAME, NONE } },
170 { NEARMV, { GOLDEN_FRAME, NONE } },
171
172#if CONFIG_EXT_INTER
173 { NEWFROMNEARMV, { LAST_FRAME, NONE } },
174#if CONFIG_EXT_REFS
175 { NEWFROMNEARMV, { LAST2_FRAME, NONE } },
176 { NEWFROMNEARMV, { LAST3_FRAME, NONE } },
177 { NEWFROMNEARMV, { BWDREF_FRAME, NONE } },
178#endif // CONFIG_EXT_REFS
179 { NEWFROMNEARMV, { ALTREF_FRAME, NONE } },
180 { NEWFROMNEARMV, { GOLDEN_FRAME, NONE } },
181#endif // CONFIG_EXT_INTER
182
183 { ZEROMV, { LAST_FRAME, NONE } },
184#if CONFIG_EXT_REFS
185 { ZEROMV, { LAST2_FRAME, NONE } },
186 { ZEROMV, { LAST3_FRAME, NONE } },
187 { ZEROMV, { BWDREF_FRAME, NONE } },
188#endif // CONFIG_EXT_REFS
189 { ZEROMV, { GOLDEN_FRAME, NONE } },
190 { ZEROMV, { ALTREF_FRAME, NONE } },
191
192// TODO(zoeliu): May need to reconsider the order on the modes to check
193
194#if CONFIG_EXT_INTER
195 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
196#if CONFIG_EXT_REFS
197 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
198 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
199#endif // CONFIG_EXT_REFS
200 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
201#if CONFIG_EXT_REFS
202 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
203 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
204 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
205 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
206#endif // CONFIG_EXT_REFS
207
208#else // CONFIG_EXT_INTER
209
210 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
211#if CONFIG_EXT_REFS
212 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
213 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
214#endif // CONFIG_EXT_REFS
215 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
216#if CONFIG_EXT_REFS
217 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
218 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
219 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
220 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
221#endif // CONFIG_EXT_REFS
222#endif // CONFIG_EXT_INTER
223
224 { TM_PRED, { INTRA_FRAME, NONE } },
225
226#if CONFIG_EXT_INTER
227 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
228 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
229 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
230 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
231 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
232 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
233 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
234 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
235 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
236
237#if CONFIG_EXT_REFS
238 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
239 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
240 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
241 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
242 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
243 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
244 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
247
248 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
249 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
250 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
251 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
252 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
253 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
254 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
257#endif // CONFIG_EXT_REFS
258
259 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
260 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
261 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
262 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
263 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
264 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
265 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268
269#if CONFIG_EXT_REFS
270 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
271 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
272 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
273 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
274 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
275 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
276 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
277 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
278 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
279
280 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
281 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
282 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
283 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
284 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
285 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
286 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
287 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
289
290 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
291 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
292 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
293 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
294 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
295 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
296 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
297 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
299
300 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
301 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
302 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
303 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
304 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
305 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
306 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
307 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309#endif // CONFIG_EXT_REFS
310
311#else // CONFIG_EXT_INTER
312
313 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
314 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
315#if CONFIG_EXT_REFS
316 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
317 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
318 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
319 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
320#endif // CONFIG_EXT_REFS
321 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
322 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
323
324#if CONFIG_EXT_REFS
325 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
326 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
327 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
328 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
329 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
330 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
331 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
332 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
333#endif // CONFIG_EXT_REFS
334
335 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
336#if CONFIG_EXT_REFS
337 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
338 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
339#endif // CONFIG_EXT_REFS
340 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
341
342#if CONFIG_EXT_REFS
343 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
344 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
345 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
346 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
347#endif // CONFIG_EXT_REFS
348
349#endif // CONFIG_EXT_INTER
350
351 { H_PRED, { INTRA_FRAME, NONE } },
352 { V_PRED, { INTRA_FRAME, NONE } },
353 { D135_PRED, { INTRA_FRAME, NONE } },
354 { D207_PRED, { INTRA_FRAME, NONE } },
355 { D153_PRED, { INTRA_FRAME, NONE } },
356 { D63_PRED, { INTRA_FRAME, NONE } },
357 { D117_PRED, { INTRA_FRAME, NONE } },
358 { D45_PRED, { INTRA_FRAME, NONE } },
359
360#if CONFIG_EXT_INTER
361 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
362 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
363 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
364 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
365
366#if CONFIG_EXT_REFS
367 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
368 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
369 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
370 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
371
372 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
373 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
374 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
375 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
376#endif // CONFIG_EXT_REFS
377
378 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
379 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
380 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
381 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
382
383#if CONFIG_EXT_REFS
384 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
385 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
386 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
387 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
388#endif // CONFIG_EXT_REFS
389
390 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
391 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
392 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
393 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
394#endif // CONFIG_EXT_INTER
395};
396
Yaowu Xuf883b422016-08-30 14:01:10 -0700397static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700398 { { LAST_FRAME, NONE } },
399#if CONFIG_EXT_REFS
400 { { LAST2_FRAME, NONE } }, { { LAST3_FRAME, NONE } },
401 { { BWDREF_FRAME, NONE } },
402#endif // CONFIG_EXT_REFS
403 { { GOLDEN_FRAME, NONE } }, { { ALTREF_FRAME, NONE } },
404
405 { { LAST_FRAME, ALTREF_FRAME } },
406#if CONFIG_EXT_REFS
407 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
408#endif // CONFIG_EXT_REFS
409 { { GOLDEN_FRAME, ALTREF_FRAME } },
410
411#if CONFIG_EXT_REFS
412 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
413 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
414#endif // CONFIG_EXT_REFS
415
416 { { INTRA_FRAME, NONE } },
417};
418
hui su5db97432016-10-14 16:10:14 -0700419#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420static INLINE int write_uniform_cost(int n, int v) {
421 int l = get_unsigned_bits(n), m = (1 << l) - n;
422 if (l == 0) return 0;
423 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700424 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700425 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700426 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427}
hui su5db97432016-10-14 16:10:14 -0700428#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429
430// constants for prune 1 and prune 2 decision boundaries
431#define FAST_EXT_TX_CORR_MID 0.0
432#define FAST_EXT_TX_EDST_MID 0.1
433#define FAST_EXT_TX_CORR_MARGIN 0.5
434#define FAST_EXT_TX_EDST_MARGIN 0.3
435
436static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
437 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
438#if CONFIG_EXT_TX
439 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
440 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
441#endif // CONFIG_EXT_TX
442};
443
444static const TX_TYPE_1D htx_tab[TX_TYPES] = {
445 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
446#if CONFIG_EXT_TX
447 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
448 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
449#endif // CONFIG_EXT_TX
450};
451
Yaowu Xuf883b422016-08-30 14:01:10 -0700452static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700453 uint8_t *src, int src_stride,
454 uint8_t *dst, int dst_stride,
455 double *hordist, double *verdist) {
456 int bw = 4 << (b_width_log2_lookup[bsize]);
457 int bh = 4 << (b_height_log2_lookup[bsize]);
458 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
459 unsigned int var[16];
460 double total = 0;
461
462 const int f_index = bsize - BLOCK_16X16;
463 if (f_index < 0) {
464 int i, j, index;
465 int w_shift = bw == 8 ? 1 : 2;
466 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700467#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700468 if (cpi->common.use_highbitdepth) {
469 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
470 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
471 for (i = 0; i < bh; ++i)
472 for (j = 0; j < bw; ++j) {
473 index = (j >> w_shift) + ((i >> h_shift) << 2);
474 esq[index] +=
475 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
476 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
477 }
478 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700479#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700480
481 for (i = 0; i < bh; ++i)
482 for (j = 0; j < bw; ++j) {
483 index = (j >> w_shift) + ((i >> h_shift) << 2);
484 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
485 (src[j + i * src_stride] - dst[j + i * dst_stride]);
486 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700487#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700488 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700489#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700490 } else {
491 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
492 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
493 dst_stride, &esq[1]);
494 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
495 dst_stride, &esq[2]);
496 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
497 dst + 3 * bw / 4, dst_stride, &esq[3]);
498 src += bh / 4 * src_stride;
499 dst += bh / 4 * dst_stride;
500
501 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
502 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
503 dst_stride, &esq[5]);
504 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
505 dst_stride, &esq[6]);
506 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
507 dst + 3 * bw / 4, dst_stride, &esq[7]);
508 src += bh / 4 * src_stride;
509 dst += bh / 4 * dst_stride;
510
511 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
512 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
513 dst_stride, &esq[9]);
514 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
515 dst_stride, &esq[10]);
516 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
517 dst + 3 * bw / 4, dst_stride, &esq[11]);
518 src += bh / 4 * src_stride;
519 dst += bh / 4 * dst_stride;
520
521 var[12] =
522 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
523 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
524 dst_stride, &esq[13]);
525 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
526 dst_stride, &esq[14]);
527 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
528 dst + 3 * bw / 4, dst_stride, &esq[15]);
529 }
530
531 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
532 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
533 esq[14] + esq[15];
534 if (total > 0) {
535 const double e_recip = 1.0 / total;
536 hordist[0] =
537 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
538 e_recip;
539 hordist[1] =
540 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
541 e_recip;
542 hordist[2] =
543 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
544 e_recip;
545 verdist[0] =
546 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
547 e_recip;
548 verdist[1] =
549 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
550 e_recip;
551 verdist[2] =
552 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
553 e_recip;
554 } else {
555 hordist[0] = verdist[0] = 0.25;
556 hordist[1] = verdist[1] = 0.25;
557 hordist[2] = verdist[2] = 0.25;
558 }
559 (void)var[0];
560 (void)var[1];
561 (void)var[2];
562 (void)var[3];
563 (void)var[4];
564 (void)var[5];
565 (void)var[6];
566 (void)var[7];
567 (void)var[8];
568 (void)var[9];
569 (void)var[10];
570 (void)var[11];
571 (void)var[12];
572 (void)var[13];
573 (void)var[14];
574 (void)var[15];
575}
576
Yaowu Xuf883b422016-08-30 14:01:10 -0700577static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
578 int src_stride, uint8_t *dst, int dst_stride,
579 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700580 int prune_bitmask = 0;
581 double svm_proj_h = 0, svm_proj_v = 0;
582 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
583 hdist, vdist);
584
585 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
586 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
587 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
588 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
589 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
590 prune_bitmask |= 1 << FLIPADST_1D;
591 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
592 prune_bitmask |= 1 << ADST_1D;
593
594 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
595 prune_bitmask |= 1 << (FLIPADST_1D + 8);
596 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
597 prune_bitmask |= 1 << (ADST_1D + 8);
598
599 return prune_bitmask;
600}
601
602#if CONFIG_EXT_TX
603static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
604 double *hcorr, double *vcorr) {
605 // Returns hor/ver correlation coefficient
606 const int num = (h - 1) * (w - 1);
607 double num_r;
608 int i, j;
609 int64_t xy_sum = 0, xz_sum = 0;
610 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
611 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
612 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
613 *hcorr = *vcorr = 1;
614
615 assert(num > 0);
616 num_r = 1.0 / num;
617 for (i = 1; i < h; ++i) {
618 for (j = 1; j < w; ++j) {
619 const int16_t x = diff[i * stride + j];
620 const int16_t y = diff[i * stride + j - 1];
621 const int16_t z = diff[(i - 1) * stride + j];
622 xy_sum += x * y;
623 xz_sum += x * z;
624 x_sum += x;
625 y_sum += y;
626 z_sum += z;
627 x2_sum += x * x;
628 y2_sum += y * y;
629 z2_sum += z * z;
630 }
631 }
632 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
633 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
634 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
635 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
636 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
637 if (x_var_n > 0 && y_var_n > 0) {
638 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
639 *hcorr = *hcorr < 0 ? 0 : *hcorr;
640 }
641 if (x_var_n > 0 && z_var_n > 0) {
642 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
643 *vcorr = *vcorr < 0 ? 0 : *vcorr;
644 }
645}
646
647int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
648 double *vcorr) {
649 int prune_bitmask = 0;
650 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
651
652 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
653 prune_bitmask |= 1 << IDTX_1D;
654 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
655 prune_bitmask |= 1 << DCT_1D;
656
657 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
658 prune_bitmask |= 1 << (IDTX_1D + 8);
659 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
660 prune_bitmask |= 1 << (DCT_1D + 8);
661 return prune_bitmask;
662}
663
664// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700665static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
667 int dct_idtx) {
668 struct macroblock_plane *const p = &x->plane[0];
669 struct macroblockd_plane *const pd = &xd->plane[0];
670 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
671 const int bw = 4 << (b_width_log2_lookup[bs]);
672 const int bh = 4 << (b_height_log2_lookup[bs]);
673 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
674 double hcorr, vcorr;
675 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700676 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700677
678 if (adst_flipadst)
679 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
680 pd->dst.buf, pd->dst.stride, hdist, vdist);
681 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
682
683 return prune;
684}
685#endif // CONFIG_EXT_TX
686
687// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700688static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689 MACROBLOCK *x, MACROBLOCKD *xd) {
690 struct macroblock_plane *const p = &x->plane[0];
691 struct macroblockd_plane *const pd = &xd->plane[0];
692 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700693 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700694 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
695 pd->dst.stride, hdist, vdist);
696}
697
Yaowu Xuf883b422016-08-30 14:01:10 -0700698static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699 MACROBLOCKD *xd, int tx_set) {
700#if CONFIG_EXT_TX
701 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
702#else
703 const int tx_set_1D[TX_TYPES_1D] = { 0 };
704#endif
705
706 switch (cpi->sf.tx_type_search.prune_mode) {
707 case NO_PRUNE: return 0; break;
708 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700709 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700710 return 0;
711 return prune_one_for_sby(cpi, bsize, x, xd);
712 break;
713#if CONFIG_EXT_TX
714 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700715 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700716 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
717 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
718 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700719 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700720 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
721 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
722 break;
723#endif
724 }
725 assert(0);
726 return 0;
727}
728
729static int do_tx_type_search(TX_TYPE tx_type, int prune) {
730// TODO(sarahparker) implement for non ext tx
731#if CONFIG_EXT_TX
732 return !(((prune >> vtx_tab[tx_type]) & 1) |
733 ((prune >> (htx_tab[tx_type] + 8)) & 1));
734#else
735 // temporary to avoid compiler warnings
736 (void)vtx_tab;
737 (void)htx_tab;
738 (void)tx_type;
739 (void)prune;
740 return 1;
741#endif
742}
743
Yaowu Xuf883b422016-08-30 14:01:10 -0700744static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700745 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
746 int plane, int64_t sse, int *rate,
747 int64_t *dist) {
748 const struct macroblockd_plane *const pd = &xd->plane[plane];
749 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700750#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700751 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700752#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753 3;
754
755 // Fast approximate the modelling function.
756 if (cpi->sf.simple_model_rd_from_var) {
757 const int64_t square_error = sse;
758 int quantizer = (pd->dequant[1] >> dequant_shift);
759
760 if (quantizer < 120)
761 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700762 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700763 else
764 *rate = 0;
765 *dist = (square_error * quantizer) >> 8;
766 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700767 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
768 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 }
770
771 *dist <<= 4;
772}
773
Yaowu Xuf883b422016-08-30 14:01:10 -0700774static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
776 int plane_to, int *out_rate_sum,
777 int64_t *out_dist_sum, int *skip_txfm_sb,
778 int64_t *skip_sse_sb) {
779 // Note our transform coeffs are 8 times an orthogonal transform.
780 // Hence quantizer step is also 8 times. To get effective quantizer
781 // we need to divide by 8 before sending to modeling function.
782 int plane;
783 const int ref = xd->mi[0]->mbmi.ref_frame[0];
784
785 int64_t rate_sum = 0;
786 int64_t dist_sum = 0;
787 int64_t total_sse = 0;
788
789 x->pred_sse[ref] = 0;
790
791 for (plane = plane_from; plane <= plane_to; ++plane) {
792 struct macroblock_plane *const p = &x->plane[plane];
793 struct macroblockd_plane *const pd = &xd->plane[plane];
794 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
795
796 unsigned int sse;
797 int rate;
798 int64_t dist;
799
800 // TODO(geza): Write direct sse functions that do not compute
801 // variance as well.
802 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
803 &sse);
804
805 if (plane == 0) x->pred_sse[ref] = sse;
806
807 total_sse += sse;
808
809 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
810
811 rate_sum += rate;
812 dist_sum += dist;
813 }
814
815 *skip_txfm_sb = total_sse == 0;
816 *skip_sse_sb = total_sse << 4;
817 *out_rate_sum = (int)rate_sum;
818 *out_dist_sum = dist_sum;
819}
820
Yushin Cho77bba8d2016-11-04 16:36:56 -0700821#if CONFIG_PVQ
822// Without PVQ, av1_block_error_c() return two kind of errors,
823// 1) reconstruction (i.e. decoded) error and
824// 2) Squared sum of transformed residue (i.e. 'coeff')
825// However, if PVQ is enabled, coeff does not keep the transformed residue
826// but instead a transformed original is kept.
827// Hence, new parameter ref vector (i.e. transformed predicted signal)
828// is required to derive the residue signal,
829// i.e. coeff - ref = residue (all transformed).
830
831// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
832// a separate function that does not do the extra computations for ssz.
833int64_t av1_block_error2_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
834 const tran_low_t *ref, intptr_t block_size,
835 int64_t *ssz) {
836 int64_t error;
837
838 // Use the existing sse codes for calculating distortion of decoded signal:
839 // i.e. (orig - decoded)^2
840 error = av1_block_error_fp(coeff, dqcoeff, block_size);
841 // prediction residue^2 = (orig - ref)^2
842 *ssz = av1_block_error_fp(coeff, ref, block_size);
843
844 return error;
845}
846#endif
847
Yaowu Xuf883b422016-08-30 14:01:10 -0700848int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
849 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 int i;
851 int64_t error = 0, sqcoeff = 0;
852
853 for (i = 0; i < block_size; i++) {
854 const int diff = coeff[i] - dqcoeff[i];
855 error += diff * diff;
856 sqcoeff += coeff[i] * coeff[i];
857 }
858
859 *ssz = sqcoeff;
860 return error;
861}
862
Yaowu Xuf883b422016-08-30 14:01:10 -0700863int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
864 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865 int i;
866 int64_t error = 0;
867
868 for (i = 0; i < block_size; i++) {
869 const int diff = coeff[i] - dqcoeff[i];
870 error += diff * diff;
871 }
872
873 return error;
874}
875
Yaowu Xuf883b422016-08-30 14:01:10 -0700876#if CONFIG_AOM_HIGHBITDEPTH
877int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
878 const tran_low_t *dqcoeff, intptr_t block_size,
879 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700880 int i;
881 int64_t error = 0, sqcoeff = 0;
882 int shift = 2 * (bd - 8);
883 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
884
885 for (i = 0; i < block_size; i++) {
886 const int64_t diff = coeff[i] - dqcoeff[i];
887 error += diff * diff;
888 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
889 }
890 assert(error >= 0 && sqcoeff >= 0);
891 error = (error + rounding) >> shift;
892 sqcoeff = (sqcoeff + rounding) >> shift;
893
894 *ssz = sqcoeff;
895 return error;
896}
Yaowu Xuf883b422016-08-30 14:01:10 -0700897#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700898
Yushin Cho77bba8d2016-11-04 16:36:56 -0700899#if !CONFIG_PVQ
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700900/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -0700901 * decide whether to include cost of a trailing EOB node or not (i.e. we
902 * can skip this if the last coefficient in this transform block, e.g. the
903 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
904 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -0700905int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
906 int block, int coeff_ctx, TX_SIZE tx_size,
907 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -0700908 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700909 MACROBLOCKD *const xd = &x->e_mbd;
910 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
911 const struct macroblock_plane *p = &x->plane[plane];
912 const struct macroblockd_plane *pd = &xd->plane[plane];
913 const PLANE_TYPE type = pd->plane_type;
914 const uint16_t *band_count = &band_count_table[tx_size][1];
915 const int eob = p->eobs[block];
916 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
917 const int tx_size_ctx = txsize_sqr_map[tx_size];
918 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
919 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
920 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700921 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700922 int c, cost;
Yaowu Xuf883b422016-08-30 14:01:10 -0700923#if CONFIG_AOM_HIGHBITDEPTH
924 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700926 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927#endif
928
929#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
930 // Check for consistency of tx_size with mode info
931 assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
932 : get_uv_tx_size(mbmi, pd) == tx_size);
933#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -0700934 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935
936 if (eob == 0) {
937 // single eob token
938 cost = token_costs[0][0][pt][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 } else {
940 if (use_fast_coef_costing) {
941 int band_left = *band_count++;
942
943 // dc token
944 int v = qcoeff[0];
945 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -0700946 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947 cost += (*token_costs)[0][pt][prev_t];
948
Yaowu Xuf883b422016-08-30 14:01:10 -0700949 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700950 ++token_costs;
951
952 // ac tokens
953 for (c = 1; c < eob; c++) {
954 const int rc = scan[c];
955 int16_t t;
956
957 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700958 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700959 cost += (*token_costs)[!prev_t][!prev_t][t];
960 prev_t = t;
961 if (!--band_left) {
962 band_left = *band_count++;
963 ++token_costs;
964 }
965 }
966
967 // eob token
968 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
969
970 } else { // !use_fast_coef_costing
971 int band_left = *band_count++;
972
973 // dc token
974 int v = qcoeff[0];
975 int16_t tok;
976 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -0700977 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700978 cost += (*token_costs)[0][pt][tok];
979
Yaowu Xuf883b422016-08-30 14:01:10 -0700980 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700981 ++token_costs;
982
983 tok_cost_ptr = &((*token_costs)[!tok]);
984
985 // ac tokens
986 for (c = 1; c < eob; c++) {
987 const int rc = scan[c];
988
989 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700990 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991 pt = get_coef_context(nb, token_cache, c);
992 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -0700993 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700994 if (!--band_left) {
995 band_left = *band_count++;
996 ++token_costs;
997 }
998 tok_cost_ptr = &((*token_costs)[!tok]);
999 }
1000
1001 // eob token
1002 if (band_left) {
1003 pt = get_coef_context(nb, token_cache, c);
1004 cost += (*token_costs)[0][pt][EOB_TOKEN];
1005 }
1006 }
1007 }
1008
Yaowu Xuc27fc142016-08-22 16:08:15 -07001009 return cost;
1010}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001011#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001012
Yaowu Xuf883b422016-08-30 14:01:10 -07001013static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1014 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 int64_t *out_dist, int64_t *out_sse) {
1016 MACROBLOCKD *const xd = &x->e_mbd;
1017 const struct macroblock_plane *const p = &x->plane[plane];
1018 const struct macroblockd_plane *const pd = &xd->plane[plane];
1019 if (cpi->sf.use_transform_domain_distortion) {
1020 // Transform domain distortion computation is more accurate as it does
1021 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001022 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001023 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001024 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001025 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1026 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001027#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001028 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001029#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001030#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001031 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001032 *out_dist =
1033 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1034 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001035#elif CONFIG_PVQ
1036 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1037 &this_sse) >>
1038 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001039#else
1040 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001041 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001042#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043 *out_sse = this_sse >> shift;
1044 } else {
1045 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001046 const int bsw = block_size_wide[tx_bsize];
1047 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001048 const int src_stride = x->plane[plane].src.stride;
1049 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001050 // Scale the transform block index to pixel unit.
1051 const int src_idx = (blk_row * src_stride + blk_col)
1052 << tx_size_wide_log2[0];
1053 const int dst_idx = (blk_row * dst_stride + blk_col)
1054 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001055 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1056 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1057 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1058 const uint16_t eob = p->eobs[block];
1059
1060 unsigned int tmp;
1061
1062 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001063 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001064
1065 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1066 *out_sse = (int64_t)tmp * 16;
1067
1068 if (eob) {
1069 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001070#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001071 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1072 uint8_t *recon = (uint8_t *)recon16;
1073#else
1074 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001075#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001076
1077 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1078
1079 INV_TXFM_PARAM inv_txfm_param;
1080
1081 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1082 inv_txfm_param.tx_size = tx_size;
1083 inv_txfm_param.eob = eob;
1084 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1085
Yaowu Xuf883b422016-08-30 14:01:10 -07001086#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1088 recon = CONVERT_TO_BYTEPTR(recon);
1089 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001090 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001091 NULL, 0, bsw, bsh, xd->bd);
1092 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1093 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001094#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001095 {
Yushin Cho721868c2016-11-14 16:04:33 +09001096#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001097 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001099#else
1100 int i, j;
1101
1102 for (j = 0; j < bsh; j++)
1103 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
1104#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001105 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1106 }
1107
1108 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1109 }
1110
1111 *out_dist = (int64_t)tmp * 16;
1112 }
1113}
1114
Yushin Cho77bba8d2016-11-04 16:36:56 -07001115#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001116static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001117 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001118 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1119 tx_size, args->scan_order->scan,
1120 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001121 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001122}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001123#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001124
1125static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1126 TX_SIZE tx_size) {
1127 uint64_t sse;
1128 switch (tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001129 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001130 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1131 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001132 break;
1133 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001134 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1135 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 break;
1137 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001138 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1139 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140 break;
1141 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001142 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1143 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001144 break;
1145 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001146 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1147 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148 break;
1149 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001150 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1151 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001152 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153 default:
1154 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001155 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001156 break;
1157 }
1158 return sse;
1159}
1160
1161static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1162 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1163 struct rdcost_block_args *args = arg;
1164 MACROBLOCK *const x = args->x;
1165 MACROBLOCKD *const xd = &x->e_mbd;
1166 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001167 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001168 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001169 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1170 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001171 RD_STATS this_rd_stats;
1172 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001173
1174 if (args->exit_early) return;
1175
1176 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001177 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001178 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001180 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001181 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182
1183 if (args->cpi->sf.use_transform_domain_distortion) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001184 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1185 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 } else {
1187 // Note that the encode block_intra call above already calls
1188 // inv_txfm_add, so we can't just call dist_block here.
1189 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001190 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001191
1192 const struct macroblock_plane *const p = &x->plane[plane];
1193 const struct macroblockd_plane *const pd = &xd->plane[plane];
1194
1195 const int src_stride = p->src.stride;
1196 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001197 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198
1199 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1200 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1201 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1202
1203 unsigned int tmp;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001204 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205
Yaowu Xuf883b422016-08-30 14:01:10 -07001206#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001207 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001208 this_rd_stats.sse =
1209 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001210#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001211 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001212
1213 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001214 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001215 }
1216 } else {
1217// full forward transform and quantization
1218#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001219 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001220 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001221#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001222 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001223 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001225#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226 if (x->plane[plane].eobs[block])
Angie Chiangff6d8902016-10-21 11:02:09 -07001227 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yushin Cho721868c2016-11-14 16:04:33 +09001228#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001229 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1230 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231 }
1232
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001233 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234 if (args->this_rd + rd > args->best_rd) {
1235 args->exit_early = 1;
1236 return;
1237 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001238#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001239 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001240#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001241 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1242 this_rd_stats.rate);
1243#endif
Angie Chiang3963d632016-11-10 18:41:40 -08001244
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001245 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1246 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001247#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001248 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001249 args->t_above[blk_col] = !x->pvq_skip[plane];
1250 args->t_left[blk_row] = !x->pvq_skip[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001251#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001252 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1253 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254
1255 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001256 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001257
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001258#if !CONFIG_PVQ
1259 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1260#else
1261 this_rd_stats.skip &= x->pvq_skip[plane];
1262#endif
1263 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 args->this_rd += rd;
1265
1266 if (args->this_rd > args->best_rd) {
1267 args->exit_early = 1;
1268 return;
1269 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001270}
1271
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001272static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1273 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1274 BLOCK_SIZE bsize, TX_SIZE tx_size,
1275 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001276 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277 MACROBLOCKD *const xd = &x->e_mbd;
1278 const struct macroblockd_plane *const pd = &xd->plane[plane];
1279 TX_TYPE tx_type;
1280 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001281 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282 args.x = x;
1283 args.cpi = cpi;
1284 args.best_rd = ref_best_rd;
1285 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001286 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001287
1288 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1289
Yaowu Xuf883b422016-08-30 14:01:10 -07001290 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001291
1292 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001293 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001294 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001295
Yaowu Xuf883b422016-08-30 14:01:10 -07001296 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1297 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001298 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001299 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001300 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001301 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001302 }
1303}
1304
1305#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001306void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1307 int64_t *distortion, int *skippable,
1308 int64_t *sse, int64_t ref_best_rd, int plane,
1309 BLOCK_SIZE bsize, TX_SIZE tx_size,
1310 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001311 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001312 MACROBLOCKD *const xd = &x->e_mbd;
1313 const struct macroblockd_plane *const pd = &xd->plane[plane];
1314 struct rdcost_block_args args;
1315 TX_TYPE tx_type;
1316
Yaowu Xuf883b422016-08-30 14:01:10 -07001317 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001318 args.cpi = cpi;
1319 args.x = x;
1320 args.best_rd = ref_best_rd;
1321 args.use_fast_coef_costing = use_fast_coef_casting;
1322
1323#if CONFIG_EXT_TX
1324 assert(tx_size < TX_SIZES);
1325#endif // CONFIG_EXT_TX
1326
1327 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1328
Yaowu Xuf883b422016-08-30 14:01:10 -07001329 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330
1331 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001332 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001333 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001334
1335 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1336 &args);
1337
1338 if (args.exit_early) {
1339 *rate = INT_MAX;
1340 *distortion = INT64_MAX;
1341 *sse = INT64_MAX;
1342 *skippable = 0;
1343 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001344 *distortion = args.rd_stats.dist;
1345 *rate = args.rd_stats.rate;
1346 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001347 *skippable = !x->plane[plane].eobs[0];
1348 }
1349}
1350#endif // CONFIG_SUPERTX
1351
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001352static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1353 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1354 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001355 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356 MACROBLOCKD *const xd = &x->e_mbd;
1357 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1358 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001359 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360 int s0, s1;
1361 const int is_inter = is_inter_block(mbmi);
1362 const int tx_size_ctx = get_tx_size_context(xd);
1363 const int tx_size_cat =
1364 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1365 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Hanb0a71302016-10-25 16:28:49 -07001366 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Jingning Hanb0a71302016-10-25 16:28:49 -07001368 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001369
1370 assert(skip_prob > 0);
1371#if CONFIG_EXT_TX && CONFIG_RECT_TX
1372 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1373#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1374
Yaowu Xuf883b422016-08-30 14:01:10 -07001375 s0 = av1_cost_bit(skip_prob, 0);
1376 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001377
1378 mbmi->tx_type = tx_type;
1379 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001380 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001382 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383#if CONFIG_EXT_TX
1384 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1385 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1386 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1387 if (is_inter) {
1388 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001389 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001390 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1391 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001392 } else {
1393 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001394 rd_stats->rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1395 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001396 }
1397 }
1398#else
1399 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1400 !FIXED_TX_TYPE) {
1401 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001402 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001403 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001404 rd_stats->rate +=
1405 cpi->intra_tx_type_costs[mbmi->tx_size]
1406 [intra_mode_to_tx_type_context[mbmi->mode]]
1407 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001408 }
1409 }
1410#endif // CONFIG_EXT_TX
1411
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001412 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001413 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001414 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001416 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1417 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001418 }
1419 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001420 rd = RDCOST(x->rdmult, x->rddiv,
1421 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001422 }
1423
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001424 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001425
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001426 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1427 !(rd_stats->skip))
1428 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001429
1430 return rd;
1431}
1432
Urvang Joshi52648442016-10-13 17:27:51 -07001433static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001434 MACROBLOCK *x, RD_STATS *rd_stats,
1435 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001436#if CONFIG_PVQ
1437 od_rollback_buffer buf,
1438#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001439 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001440 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001441 MACROBLOCKD *const xd = &x->e_mbd;
1442 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001443 int64_t rd = INT64_MAX;
1444 int n;
1445 int start_tx, end_tx;
1446 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1447 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1448 TX_SIZE best_tx_size = max_tx_size;
1449 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1450 const int is_inter = is_inter_block(mbmi);
1451#if CONFIG_EXT_TX
1452#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001453 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001454#endif // CONFIG_RECT_TX
1455 int ext_tx_set;
1456#endif // CONFIG_EXT_TX
1457
1458 if (tx_select) {
1459#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001460 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1462 start_tx = max_tx_size;
Hui Sueafb2e62016-10-18 10:21:36 -07001463 end_tx = (max_tx_size == TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464 } else {
1465 const TX_SIZE chosen_tx_size =
1466 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1467#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001468 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1469 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001470#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1471 start_tx = chosen_tx_size;
1472 end_tx = chosen_tx_size;
1473 }
1474
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001475 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001476
1477 mbmi->tx_type = tx_type;
1478
1479#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001480 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001481 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001482 RD_STATS this_rd_stats;
Urvang Joshi368fbc92016-10-17 16:31:34 -07001483 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001484 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001485 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001486 rect_tx_size);
1487 best_tx_size = rect_tx_size;
1488 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001489 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001490 }
1491 }
1492#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1493
1494 last_rd = INT64_MAX;
1495 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001496 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497#if CONFIG_EXT_TX && CONFIG_RECT_TX
1498 if (is_rect_tx(n)) break;
1499#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1500 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1501 if (!is_inter && x->use_default_intra_tx_type &&
1502 tx_type != get_default_tx_type(0, xd, 0, n))
1503 continue;
1504 if (is_inter && x->use_default_inter_tx_type &&
1505 tx_type != get_default_tx_type(0, xd, 0, n))
1506 continue;
1507 if (max_tx_size == TX_32X32 && n == TX_4X4) continue;
1508#if CONFIG_EXT_TX
1509 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1510 if (is_inter) {
1511 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1512 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1513 if (!do_tx_type_search(tx_type, prune)) continue;
1514 }
1515 } else {
1516 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1517 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1518 }
1519 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1520 }
1521#else // CONFIG_EXT_TX
1522 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1523 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1524 !do_tx_type_search(tx_type, prune))
1525 continue;
1526#endif // CONFIG_EXT_TX
1527
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001528 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001529#if CONFIG_PVQ
1530 od_encode_rollback(&x->daala_enc, &buf);
1531#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001532 // Early termination in transform size search.
1533 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001534 (rd == INT64_MAX ||
1535 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001536 (n < (int)max_tx_size && rd > last_rd)))
1537 break;
1538
1539 last_rd = rd;
1540 if (rd < best_rd) {
1541 best_tx_size = n;
1542 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001543 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001544 }
1545 }
1546 mbmi->tx_size = best_tx_size;
1547
1548 return best_rd;
1549}
1550
1551#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001552static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1553 MACROBLOCK *x, int *r, int64_t *d, int *s,
1554 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001555 RD_STATS rd_stats;
1556 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1557 max_txsize_lookup[bs]);
1558 *r = rd_stats.rate;
1559 *d = rd_stats.dist;
1560 *s = rd_stats.skip;
1561 *sse = rd_stats.sse;
1562 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001563}
1564#endif // CONFIG_EXT_INTER
1565
Urvang Joshi52648442016-10-13 17:27:51 -07001566static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001567 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001568 BLOCK_SIZE bs) {
1569 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001570 MACROBLOCKD *const xd = &x->e_mbd;
1571 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1572 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001573 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001574 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1575 int s0 = av1_cost_bit(skip_prob, 0);
1576 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001577 const int is_inter = is_inter_block(mbmi);
1578 int prune = 0;
1579#if CONFIG_EXT_TX
1580 int ext_tx_set;
1581#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001582 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001583
1584 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001585#if CONFIG_VAR_TX
1586 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1587#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001588#if CONFIG_EXT_TX
1589 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1590#endif // CONFIG_EXT_TX
1591
1592 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1593#if CONFIG_EXT_TX
1594 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1595#else
1596 prune = prune_tx_types(cpi, bs, x, xd, 0);
1597#endif
1598#if CONFIG_EXT_TX
1599 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1600 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001601#if CONFIG_PVQ
1602 od_rollback_buffer pre_buf, post_buf;
1603
1604 od_encode_checkpoint(&x->daala_enc, &pre_buf);
1605 od_encode_checkpoint(&x->daala_enc, &post_buf);
1606#endif
1607
1608 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001609 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001610 if (is_inter) {
1611 if (x->use_default_inter_tx_type &&
1612 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1613 continue;
1614 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1615 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1616 if (!do_tx_type_search(tx_type, prune)) continue;
1617 }
1618 } else {
1619 if (x->use_default_intra_tx_type &&
1620 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1621 continue;
1622 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1623 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1624 }
1625 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1626 }
1627
1628 mbmi->tx_type = tx_type;
1629
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001630 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001631 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001632#if CONFIG_PVQ
1633 od_encode_rollback(&x->daala_enc, &pre_buf);
1634#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001635 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001636 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1637 if (is_inter) {
1638 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001639 this_rd_stats.rate +=
1640 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1641 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001642 } else {
1643 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001644 this_rd_stats.rate +=
1645 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1646 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001647 }
1648 }
1649
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001650 if (this_rd_stats.skip)
1651 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001652 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001653 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1654 this_rd_stats.dist);
1655 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
1656 !this_rd_stats.skip)
1657 this_rd =
1658 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001659
1660 if (this_rd < best_rd) {
1661 best_rd = this_rd;
1662 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001663 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001664#if CONFIG_PVQ
1665 od_encode_checkpoint(&x->daala_enc, &post_buf);
1666#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001667 }
1668 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001669#if CONFIG_PVQ
1670 od_encode_rollback(&x->daala_enc, &post_buf);
1671#endif
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001672 } else {
1673 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001674 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1675 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001676 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001677#else // CONFIG_EXT_TX
1678 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1679 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001680 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001681 if (!is_inter && x->use_default_intra_tx_type &&
1682 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1683 continue;
1684 if (is_inter && x->use_default_inter_tx_type &&
1685 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1686 continue;
1687 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001688 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001689 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001690 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001691 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001692 this_rd_stats.rate +=
1693 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001694 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1695 !do_tx_type_search(tx_type, prune))
1696 continue;
1697 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001698 this_rd_stats.rate +=
1699 cpi->intra_tx_type_costs[mbmi->tx_size]
1700 [intra_mode_to_tx_type_context[mbmi->mode]]
1701 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001703 if (this_rd_stats.skip)
1704 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001705 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001706 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1707 this_rd_stats.dist);
1708 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
1709 this_rd =
1710 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001711
1712 if (this_rd < best_rd) {
1713 best_rd = this_rd;
1714 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001715 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001716 }
1717 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001718 } else {
1719 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001720 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1721 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001722 }
1723#endif // CONFIG_EXT_TX
1724 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001725}
1726
Urvang Joshi52648442016-10-13 17:27:51 -07001727static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001728 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001729 BLOCK_SIZE bs) {
1730 MACROBLOCKD *const xd = &x->e_mbd;
1731 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1732
1733 mbmi->tx_size = TX_4X4;
1734 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07001735#if CONFIG_VAR_TX
1736 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
1737#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001738
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001739 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1740 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001741}
1742
Urvang Joshi52648442016-10-13 17:27:51 -07001743static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001744 MACROBLOCK *x, RD_STATS *rd_stats,
1745 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001746 MACROBLOCKD *const xd = &x->e_mbd;
1747 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001748 int64_t rd = INT64_MAX;
1749 int64_t best_rd = INT64_MAX;
1750 TX_SIZE best_tx = max_txsize_lookup[bs];
1751 const int is_inter = is_inter_block(mbmi);
1752 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1753 int prune = 0;
1754
Yushin Cho77bba8d2016-11-04 16:36:56 -07001755#if CONFIG_PVQ
1756 od_rollback_buffer buf;
1757#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001758 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1759 // passing -1 in for tx_type indicates that all 1D
1760 // transforms should be considered for pruning
1761 prune = prune_tx_types(cpi, bs, x, xd, -1);
1762
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001763 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001764
Yushin Cho77bba8d2016-11-04 16:36:56 -07001765#if CONFIG_PVQ
1766 od_encode_checkpoint(&x->daala_enc, &buf);
1767#endif
1768
Yaowu Xuc27fc142016-08-22 16:08:15 -07001769 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001770 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001771#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001772 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001773#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001774 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08001775 tx_type,
1776#if CONFIG_PVQ
1777 buf,
1778#endif
1779 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780 if (rd < best_rd) {
1781 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001782 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001783 best_tx_type = tx_type;
1784 best_tx = mbmi->tx_size;
1785 }
1786 }
1787
1788 mbmi->tx_size = best_tx;
1789 mbmi->tx_type = best_tx_type;
1790
Jingning Hane67b38a2016-11-04 10:30:00 -07001791#if CONFIG_VAR_TX
1792 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1793#endif
1794
Yaowu Xuc27fc142016-08-22 16:08:15 -07001795#if !CONFIG_EXT_TX
1796 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1797#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001798#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08001799 if (best_rd != INT64_MAX) {
1800 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, best_tx,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001801 cpi->sf.use_fast_coef_costing);
Yushin Cho05f540a2016-11-08 22:12:51 -08001802 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001803#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001804}
1805
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001806static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1807 RD_STATS *rd_stats, BLOCK_SIZE bs,
1808 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001809 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001810 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001811
1812 assert(bs == xd->mi[0]->mbmi.sb_type);
1813
1814 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001815 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001817 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001818 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001819 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820 }
1821}
1822
1823static int conditional_skipintra(PREDICTION_MODE mode,
1824 PREDICTION_MODE best_intra_mode) {
1825 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1826 best_intra_mode != D135_PRED)
1827 return 1;
1828 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1829 best_intra_mode != D45_PRED)
1830 return 1;
1831 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1832 best_intra_mode != D45_PRED)
1833 return 1;
1834 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1835 best_intra_mode != D135_PRED)
1836 return 1;
1837 return 0;
1838}
1839
Urvang Joshib100db72016-10-12 16:28:56 -07001840#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001841static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001842 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001843 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1844 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1845 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1846 int rate_overhead = 0;
1847 MACROBLOCKD *const xd = &x->e_mbd;
1848 MODE_INFO *const mic = xd->mi[0];
1849 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1850 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001851 int this_rate, colors, n;
1852 RD_STATS tokenonly_rd_stats;
1853 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001854 const int src_stride = x->plane[0].src.stride;
1855 const uint8_t *const src = x->plane[0].src.buf;
1856
1857 assert(cpi->common.allow_screen_content_tools);
1858
Yaowu Xuf883b422016-08-30 14:01:10 -07001859#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001860 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001861 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1862 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001863 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001864#endif // CONFIG_AOM_HIGHBITDEPTH
1865 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001867#if CONFIG_FILTER_INTRA
1868 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1869#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870
1871 if (colors > 1 && colors <= 64) {
1872 int r, c, i, j, k;
1873 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001874 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 float *const data = x->palette_buffer->kmeans_data_buf;
1876 float centroids[PALETTE_MAX_SIZE];
1877 uint8_t *const color_map = xd->plane[0].color_index_map;
1878 float lb, ub, val;
1879 MB_MODE_INFO *const mbmi = &mic->mbmi;
1880 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001881#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001882 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1883 if (cpi->common.use_highbitdepth)
1884 lb = ub = src16[0];
1885 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001886#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001887 lb = ub = src[0];
1888
Yaowu Xuf883b422016-08-30 14:01:10 -07001889#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001890 if (cpi->common.use_highbitdepth) {
1891 for (r = 0; r < rows; ++r) {
1892 for (c = 0; c < cols; ++c) {
1893 val = src16[r * src_stride + c];
1894 data[r * cols + c] = val;
1895 if (val < lb)
1896 lb = val;
1897 else if (val > ub)
1898 ub = val;
1899 }
1900 }
1901 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001902#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 for (r = 0; r < rows; ++r) {
1904 for (c = 0; c < cols; ++c) {
1905 val = src[r * src_stride + c];
1906 data[r * cols + c] = val;
1907 if (val < lb)
1908 lb = val;
1909 else if (val > ub)
1910 ub = val;
1911 }
1912 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001913#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001915#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001916
1917 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001918#if CONFIG_FILTER_INTRA
1919 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1920#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921
1922 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1923
1924 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1925 --n) {
1926 for (i = 0; i < n; ++i)
1927 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001928 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1929 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001930
Yaowu Xuf883b422016-08-30 14:01:10 -07001931#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001932 if (cpi->common.use_highbitdepth)
1933 for (i = 0; i < k; ++i)
1934 pmi->palette_colors[i] =
1935 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1936 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001937#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001938 for (i = 0; i < k; ++i)
1939 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1940 pmi->palette_size[0] = k;
1941
Yaowu Xuf883b422016-08-30 14:01:10 -07001942 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001943
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001944 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
1945 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001946
1947 this_rate =
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001948 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001949 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001950 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1951 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001952 av1_cost_bit(
1953 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001954 1);
1955 for (i = 0; i < rows; ++i) {
1956 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001957 int color_idx;
1958 const int color_ctx = av1_get_palette_color_context(
1959 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001960 assert(color_idx >= 0 && color_idx < k);
1961 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1962 }
1963 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001964 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001965
1966 if (this_rd < *best_rd) {
1967 *best_rd = this_rd;
1968 *palette_mode_info = *pmi;
1969 memcpy(best_palette_color_map, color_map,
1970 rows * cols * sizeof(color_map[0]));
1971 *mode_selected = DC_PRED;
1972 *best_tx = mbmi->tx_size;
1973 *best_tx_type = mbmi->tx_type;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001974 rate_overhead = this_rate - tokenonly_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975 }
1976 }
1977 }
1978 return rate_overhead;
1979}
Urvang Joshib100db72016-10-12 16:28:56 -07001980#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981
Urvang Joshi52648442016-10-13 17:27:51 -07001982static int64_t rd_pick_intra4x4block(
1983 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
1984 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
1985 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
1986 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001987#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07001988 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001989#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001990 PREDICTION_MODE mode;
1991 MACROBLOCKD *const xd = &x->e_mbd;
1992 int64_t best_rd = rd_thresh;
1993 struct macroblock_plane *p = &x->plane[0];
1994 struct macroblockd_plane *pd = &xd->plane[0];
1995 const int src_stride = p->src.stride;
1996 const int dst_stride = pd->dst.stride;
1997 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1998 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
1999 ENTROPY_CONTEXT ta[2], tempa[2];
2000 ENTROPY_CONTEXT tl[2], templ[2];
2001 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2002 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2003 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002004 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002005 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07002006#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002007 uint16_t best_dst16[8 * 8];
2008#endif
2009
Yushin Cho77bba8d2016-11-04 16:36:56 -07002010#if CONFIG_PVQ
2011 od_rollback_buffer pre_buf, post_buf;
2012 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2013 od_encode_checkpoint(&x->daala_enc, &post_buf);
2014#endif
2015
Yaowu Xuc27fc142016-08-22 16:08:15 -07002016 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
2017 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
2018 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002019#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002020 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002021#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002022
Yaowu Xuf883b422016-08-30 14:01:10 -07002023#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002024 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2025 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2026 int64_t this_rd;
2027 int ratey = 0;
2028 int64_t distortion = 0;
2029 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002030 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031
2032 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2033
2034 // Only do the oblique modes if the best so far is
2035 // one of the neighboring directional modes
2036 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2037 if (conditional_skipintra(mode, *best_mode)) continue;
2038 }
2039
2040 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2041 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2042
2043 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2044 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2045 const int block = (row + idy) * 2 + (col + idx);
2046 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2047 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2048 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002049 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002050 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002051 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2052 dst_stride, dst, dst_stride, col + idx,
2053 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002054 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055 dst_stride, xd->bd);
2056 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2057 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002058 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002059 const int coeff_ctx =
2060 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002062 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2063 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002064#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002065 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002066 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002067#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002068 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002069 scan_order->scan, scan_order->neighbors,
2070 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002071 *(tempa + idx) = !(p->eobs[block] == 0);
2072 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002073 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002074 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2075 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002076 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2077 dst_stride, p->eobs[block], xd->bd,
2078 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002079 } else {
2080 int64_t dist;
2081 unsigned int tmp;
2082 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002083 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002084 const int coeff_ctx =
2085 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2086#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002087 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2088 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002089#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002090 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002091 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002092#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002093 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002094 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002095 scan_order->scan, scan_order->neighbors,
2096 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002097 *(tempa + idx) = !(p->eobs[block] == 0);
2098 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002099 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002100 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2101 dst_stride, p->eobs[block], xd->bd,
2102 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002103 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2104 dist = (int64_t)tmp << 4;
2105 distortion += dist;
2106 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2107 goto next_highbd;
2108 }
2109 }
2110 }
2111
2112 rate += ratey;
2113 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2114
2115 if (this_rd < best_rd) {
2116 *bestrate = rate;
2117 *bestratey = ratey;
2118 *bestdistortion = distortion;
2119 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002120 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121 *best_mode = mode;
2122 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2123 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2124 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2125 memcpy(best_dst16 + idy * 8,
2126 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2127 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2128 }
2129 }
2130 next_highbd : {}
2131 }
2132
2133 if (best_rd >= rd_thresh) return best_rd;
2134
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002135 if (y_skip) *y_skip &= best_can_skip;
2136
Yaowu Xuc27fc142016-08-22 16:08:15 -07002137 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2138 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2139 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2140 }
2141
2142 return best_rd;
2143 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002144#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145
Yushin Cho77bba8d2016-11-04 16:36:56 -07002146#if CONFIG_PVQ
2147 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2148#endif
2149
Yaowu Xuc27fc142016-08-22 16:08:15 -07002150 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2151 int64_t this_rd;
2152 int ratey = 0;
2153 int64_t distortion = 0;
2154 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002155 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002156
2157 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2158
2159 // Only do the oblique modes if the best so far is
2160 // one of the neighboring directional modes
2161 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2162 if (conditional_skipintra(mode, *best_mode)) continue;
2163 }
2164
2165 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2166 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2167
2168 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2169 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2170 const int block = (row + idy) * 2 + (col + idx);
2171 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2172 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002173#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002174 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002175 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002176#else
2177 int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2178 const int diff_stride = 8;
2179 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
2180 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[0].dqcoeff, block);
2181 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
2182 int16_t *pred = &pd->pred[4 * (row * diff_stride + col)];
2183 int16_t *src_int16 = &p->src_int16[4 * (row * diff_stride + col)];
2184 int i, j, tx_blk_size;
2185 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
2186 int rate_pvq;
2187 int skip;
2188#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002189 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002190 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2191 dst_stride, dst, dst_stride, col + idx,
2192 row + idy, 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002193#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07002194 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002195#else
2196 if (lossless) tx_type = DCT_DCT;
2197 // transform block size in pixels
2198 tx_blk_size = 4;
2199
2200 // copy uint8 orig and predicted block to int16 buffer
2201 // in order to use existing VP10 transform functions
2202 for (j = 0; j < tx_blk_size; j++)
2203 for (i = 0; i < tx_blk_size; i++) {
2204 src_int16[diff_stride * j + i] = src[src_stride * j + i];
2205 pred[diff_stride * j + i] = dst[dst_stride * j + i];
2206 }
2207 {
2208 FWD_TXFM_PARAM fwd_txfm_param;
2209 fwd_txfm_param.tx_type = tx_type;
2210 fwd_txfm_param.tx_size = TX_4X4;
2211 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
2212 fwd_txfm_param.rd_transform = 0;
2213 fwd_txfm_param.lossless = lossless;
2214 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
2215 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
2216 }
2217#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002218
2219 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002220#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002221 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002222 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002223 const int coeff_ctx =
2224 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002225#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002226 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2227 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002228#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002229 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2230 TX_4X4, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002231#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002232 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002233 scan_order->scan, scan_order->neighbors,
2234 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002235 *(tempa + idx) = !(p->eobs[block] == 0);
2236 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002237 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002238#else
2239 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2240 &p->eobs[block], pd->dequant, 0, TX_4X4,
2241 tx_type, &rate_pvq, x->pvq_speed, NULL);
2242 ratey += rate_pvq;
2243#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002244 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2245 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002246#if CONFIG_PVQ
2247 if (!skip) {
2248 for (j = 0; j < tx_blk_size; j++)
2249 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2250#endif
2251 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2252 dst_stride, p->eobs[block], DCT_DCT, 1);
2253#if CONFIG_PVQ
2254 }
2255#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256 } else {
2257 int64_t dist;
2258 unsigned int tmp;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002259#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002260 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002261 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002262 const int coeff_ctx =
2263 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2264#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002265 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2266 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002267#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002268 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2269 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002270#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002271 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002272 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002273 scan_order->scan, scan_order->neighbors,
2274 cpi->sf.use_fast_coef_costing);
Jingning Han3d45c0e2016-11-08 12:35:04 -08002275 *(tempa + idx) = !(p->eobs[block] == 0);
2276 *(templ + idy) = !(p->eobs[block] == 0);
2277 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002278#else
2279 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2280 &p->eobs[block], pd->dequant, 0, TX_4X4,
2281 tx_type, &rate_pvq, x->pvq_speed, NULL);
2282 ratey += rate_pvq;
2283#endif
2284 // No need for av1_block_error2_c because the ssz is unused
Yaowu Xuf883b422016-08-30 14:01:10 -07002285 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2286 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002287 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2288 dist = (int64_t)tmp << 4;
2289 distortion += dist;
2290 // To use the pixel domain distortion, the step below needs to be
2291 // put behind the inv txfm. Compared to calculating the distortion
2292 // in the frequency domain, the overhead of encoding effort is low.
2293 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2294 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002295#if CONFIG_PVQ
2296 if (!skip) {
2297 for (j = 0; j < tx_blk_size; j++)
2298 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2299#endif
2300#if CONFIG_PVQ
2301 }
2302#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002303 }
2304 }
2305 }
2306
2307 rate += ratey;
2308 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2309
2310 if (this_rd < best_rd) {
2311 *bestrate = rate;
2312 *bestratey = ratey;
2313 *bestdistortion = distortion;
2314 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002315 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002316 *best_mode = mode;
2317 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2318 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07002319#if CONFIG_PVQ
2320 od_encode_checkpoint(&x->daala_enc, &post_buf);
2321#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002322 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2323 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2324 num_4x4_blocks_wide * 4);
2325 }
2326 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07002327#if CONFIG_PVQ
2328 od_encode_rollback(&x->daala_enc, &pre_buf);
2329#endif
2330 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331
2332 if (best_rd >= rd_thresh) return best_rd;
2333
Yushin Cho77bba8d2016-11-04 16:36:56 -07002334#if CONFIG_PVQ
2335 od_encode_rollback(&x->daala_enc, &post_buf);
2336#endif
2337
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002338 if (y_skip) *y_skip &= best_can_skip;
2339
Yaowu Xuc27fc142016-08-22 16:08:15 -07002340 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2341 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2342 num_4x4_blocks_wide * 4);
2343
2344 return best_rd;
2345}
2346
Urvang Joshi52648442016-10-13 17:27:51 -07002347static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2348 MACROBLOCK *mb, int *rate,
2349 int *rate_y, int64_t *distortion,
2350 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351 int i, j;
2352 const MACROBLOCKD *const xd = &mb->e_mbd;
2353 MODE_INFO *const mic = xd->mi[0];
2354 const MODE_INFO *above_mi = xd->above_mi;
2355 const MODE_INFO *left_mi = xd->left_mi;
2356 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2357 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2358 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2359 int idx, idy;
2360 int cost = 0;
2361 int64_t total_distortion = 0;
2362 int tot_rate_y = 0;
2363 int64_t total_rd = 0;
2364 const int *bmode_costs = cpi->mbmode_cost[0];
2365
2366#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002367 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
2368#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002369#if CONFIG_FILTER_INTRA
2370 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2371#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002372
2373 // TODO(any): Add search of the tx_type to improve rd performance at the
2374 // expense of speed.
2375 mic->mbmi.tx_type = DCT_DCT;
2376 mic->mbmi.tx_size = TX_4X4;
2377
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002378 if (y_skip) *y_skip = 1;
2379
Yaowu Xuc27fc142016-08-22 16:08:15 -07002380 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2381 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2382 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2383 PREDICTION_MODE best_mode = DC_PRED;
2384 int r = INT_MAX, ry = INT_MAX;
2385 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2386 i = idy * 2 + idx;
2387 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002388 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2389 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002390
2391 bmode_costs = cpi->y_mode_costs[A][L];
2392 }
2393
2394 this_rd = rd_pick_intra4x4block(
2395 cpi, mb, idy, idx, &best_mode, bmode_costs,
2396 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002397 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002398 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2399
2400 total_rd += this_rd;
2401 cost += r;
2402 total_distortion += d;
2403 tot_rate_y += ry;
2404
2405 mic->bmi[i].as_mode = best_mode;
2406 for (j = 1; j < num_4x4_blocks_high; ++j)
2407 mic->bmi[i + j * 2].as_mode = best_mode;
2408 for (j = 1; j < num_4x4_blocks_wide; ++j)
2409 mic->bmi[i + j].as_mode = best_mode;
2410
2411 if (total_rd >= best_rd) return INT64_MAX;
2412 }
2413 }
2414 mic->mbmi.mode = mic->bmi[3].as_mode;
2415
2416 // Add in the cost of the transform type
2417 if (!xd->lossless[mic->mbmi.segment_id]) {
2418 int rate_tx_type = 0;
2419#if CONFIG_EXT_TX
2420 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2421 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002422 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2423 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002424 }
2425#else
clang-format67948d32016-09-07 22:40:40 -07002426 rate_tx_type =
2427 cpi->intra_tx_type_costs[TX_4X4]
2428 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2429 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002430#endif
2431 assert(mic->mbmi.tx_size == TX_4X4);
2432 cost += rate_tx_type;
2433 tot_rate_y += rate_tx_type;
2434 }
2435
2436 *rate = cost;
2437 *rate_y = tot_rate_y;
2438 *distortion = total_distortion;
2439
2440 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2441}
2442
hui su5db97432016-10-14 16:10:14 -07002443#if CONFIG_FILTER_INTRA
2444// Return 1 if an filter intra mode is selected; return 0 otherwise.
2445static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2446 int *rate, int *rate_tokenonly,
2447 int64_t *distortion, int *skippable,
2448 BLOCK_SIZE bsize, int mode_cost,
2449 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450 MACROBLOCKD *const xd = &x->e_mbd;
2451 MODE_INFO *const mic = xd->mi[0];
2452 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002453 int this_rate;
2454 RD_STATS tokenonly_rd_stats;
hui su5db97432016-10-14 16:10:14 -07002455 int filter_intra_selected_flag = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002456 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07002457 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002458 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002459 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460 TX_TYPE best_tx_type;
2461
hui su5db97432016-10-14 16:10:14 -07002462 av1_zero(filter_intra_mode_info);
2463 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002464 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002465#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002466 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002467#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002468
2469 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2470 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002471 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002472 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2473 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002474
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002475 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07002476 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002477 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002478 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002479
2480 if (this_rd < *best_rd) {
2481 *best_rd = this_rd;
2482 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002483 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002484 best_tx_type = mic->mbmi.tx_type;
2485 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002486 *rate_tokenonly = tokenonly_rd_stats.rate;
2487 *distortion = tokenonly_rd_stats.dist;
2488 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07002489 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002490 }
2491 }
2492
hui su5db97432016-10-14 16:10:14 -07002493 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494 mbmi->mode = DC_PRED;
2495 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002496 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2497 filter_intra_mode_info.use_filter_intra_mode[0];
2498 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2499 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002500 mbmi->tx_type = best_tx_type;
2501 return 1;
2502 } else {
2503 return 0;
2504 }
2505}
hui su5db97432016-10-14 16:10:14 -07002506#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002507
hui su5db97432016-10-14 16:10:14 -07002508#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002509static void pick_intra_angle_routine_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07002510 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002511 int64_t *distortion, int *skippable, int *best_angle_delta,
2512 TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter,
2513 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002514 int this_rate;
2515 RD_STATS tokenonly_rd_stats;
2516 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002517 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002518 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2519 if (tokenonly_rd_stats.rate == INT_MAX) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002520
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002521 this_rate = tokenonly_rd_stats.rate + rate_overhead;
2522 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002523
2524 if (this_rd < *best_rd) {
2525 *best_rd = this_rd;
2526 *best_angle_delta = mbmi->angle_delta[0];
2527 *best_tx_size = mbmi->tx_size;
2528 *best_filter = mbmi->intra_filter;
2529 *best_tx_type = mbmi->tx_type;
2530 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002531 *rate_tokenonly = tokenonly_rd_stats.rate;
2532 *distortion = tokenonly_rd_stats.dist;
2533 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002534 }
2535}
2536
Urvang Joshi52648442016-10-13 17:27:51 -07002537static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2538 int *rate, int *rate_tokenonly,
2539 int64_t *distortion, int *skippable,
2540 BLOCK_SIZE bsize, int rate_overhead,
2541 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002542 MACROBLOCKD *const xd = &x->e_mbd;
2543 MODE_INFO *const mic = xd->mi[0];
2544 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002545 int this_rate;
2546 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002547 int angle_delta, best_angle_delta = 0, p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002548 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
2550 const double rd_adjust = 1.2;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002551 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002552 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2553 TX_TYPE best_tx_type = mbmi->tx_type;
2554
2555 if (ANGLE_FAST_SEARCH) {
2556 int deltas_level1[3] = { 0, -2, 2 };
2557 int deltas_level2[3][2] = {
2558 { -1, 1 }, { -3, -1 }, { 1, 3 },
2559 };
2560 const int level1 = 3, level2 = 2;
2561 int i, j, best_i = -1;
2562
2563 for (i = 0; i < level1; ++i) {
2564 mic->mbmi.angle_delta[0] = deltas_level1[i];
2565 p_angle =
2566 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2567 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2568 int64_t tmp_best_rd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002569 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570 filter != INTRA_FILTER_LINEAR)
2571 continue;
2572 mic->mbmi.intra_filter = filter;
2573 tmp_best_rd =
2574 (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX)
2575 ? (int64_t)(best_rd * rd_adjust)
2576 : best_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002577 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd);
2578 if (tokenonly_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002579 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2580 return best_rd;
2581 else
2582 continue;
2583 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002584 this_rate = tokenonly_rd_stats.rate + rate_overhead +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002585 cpi->intra_filter_cost[intra_filter_ctx][filter];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002586 this_rd =
2587 RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX &&
2589 this_rd > best_rd * rd_adjust)
2590 return best_rd;
2591 if (this_rd < best_rd) {
2592 best_i = i;
2593 best_rd = this_rd;
2594 best_angle_delta = mbmi->angle_delta[0];
2595 best_tx_size = mbmi->tx_size;
2596 best_filter = mbmi->intra_filter;
2597 best_tx_type = mbmi->tx_type;
2598 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002599 *rate_tokenonly = tokenonly_rd_stats.rate;
2600 *distortion = tokenonly_rd_stats.dist;
2601 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002602 }
2603 }
2604 }
2605
2606 if (best_i >= 0) {
2607 for (j = 0; j < level2; ++j) {
2608 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2609 p_angle =
2610 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2611 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2612 mic->mbmi.intra_filter = filter;
2613 if ((FILTER_FAST_SEARCH ||
Yaowu Xuf883b422016-08-30 14:01:10 -07002614 !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615 filter != INTRA_FILTER_LINEAR)
2616 continue;
2617 pick_intra_angle_routine_sby(
2618 cpi, x, rate, rate_tokenonly, distortion, skippable,
2619 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2620 bsize,
2621 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2622 &best_rd);
2623 }
2624 }
2625 }
2626 } else {
2627 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2628 ++angle_delta) {
2629 mbmi->angle_delta[0] = angle_delta;
2630 p_angle =
2631 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2632 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2633 mic->mbmi.intra_filter = filter;
Yaowu Xuf883b422016-08-30 14:01:10 -07002634 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002635 filter != INTRA_FILTER_LINEAR)
2636 continue;
2637 pick_intra_angle_routine_sby(
2638 cpi, x, rate, rate_tokenonly, distortion, skippable,
2639 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2640 bsize,
2641 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2642 &best_rd);
2643 }
2644 }
2645 }
2646
2647 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2648 mbmi->angle_delta[0] = best_angle_delta;
2649 p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002650 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002651 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2652 mic->mbmi.intra_filter = filter;
2653 pick_intra_angle_routine_sby(
2654 cpi, x, rate, rate_tokenonly, distortion, skippable,
2655 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2656 bsize,
2657 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2658 &best_rd);
2659 }
2660 }
2661 }
2662
2663 mbmi->tx_size = best_tx_size;
2664 mbmi->angle_delta[0] = best_angle_delta;
2665 mic->mbmi.intra_filter = best_filter;
2666 mbmi->tx_type = best_tx_type;
2667 return best_rd;
2668}
2669
2670// Indices are sign, integer, and fractional part of the gradient value
2671static const uint8_t gradient_to_angle_bin[2][7][16] = {
2672 {
2673 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2674 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
2675 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2676 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2677 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2678 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2679 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2680 },
2681 {
2682 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2683 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
2684 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2685 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2686 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2687 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2688 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2689 },
2690};
2691
2692static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2693 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2694};
2695
2696static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2697 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002698 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002699 uint64_t hist[DIRECTIONAL_MODES];
2700 uint64_t hist_sum = 0;
2701
2702 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2703 src += src_stride;
2704 for (r = 1; r < rows; ++r) {
2705 for (c = 1; c < cols; ++c) {
2706 dx = src[c] - src[c - 1];
2707 dy = src[c] - src[c - src_stride];
2708 temp = dx * dx + dy * dy;
2709 if (dy == 0) {
2710 index = 2;
2711 } else {
2712 sn = (dx > 0) ^ (dy > 0);
2713 dx = abs(dx);
2714 dy = abs(dy);
2715 remd = dx % dy;
2716 quot = dx / dy;
2717 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002718 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002719 }
2720 hist[index] += temp;
2721 }
2722 src += src_stride;
2723 }
2724
2725 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2726 for (i = 0; i < INTRA_MODES; ++i) {
2727 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002728 const uint8_t angle_bin = mode_to_angle_bin[i];
2729 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002730 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002731 if (angle_bin > 0) {
2732 score += hist[angle_bin - 1];
2733 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002734 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002735 if (angle_bin < DIRECTIONAL_MODES - 1) {
2736 score += hist[angle_bin + 1];
2737 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002738 }
2739 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2740 directional_mode_skip_mask[i] = 1;
2741 }
2742 }
2743}
2744
Yaowu Xuf883b422016-08-30 14:01:10 -07002745#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002746static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2747 int rows, int cols,
2748 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002749 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002750 uint64_t hist[DIRECTIONAL_MODES];
2751 uint64_t hist_sum = 0;
2752 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2753
2754 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2755 src += src_stride;
2756 for (r = 1; r < rows; ++r) {
2757 for (c = 1; c < cols; ++c) {
2758 dx = src[c] - src[c - 1];
2759 dy = src[c] - src[c - src_stride];
2760 temp = dx * dx + dy * dy;
2761 if (dy == 0) {
2762 index = 2;
2763 } else {
2764 sn = (dx > 0) ^ (dy > 0);
2765 dx = abs(dx);
2766 dy = abs(dy);
2767 remd = dx % dy;
2768 quot = dx / dy;
2769 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002770 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002771 }
2772 hist[index] += temp;
2773 }
2774 src += src_stride;
2775 }
2776
2777 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2778 for (i = 0; i < INTRA_MODES; ++i) {
2779 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002780 const uint8_t angle_bin = mode_to_angle_bin[i];
2781 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002782 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002783 if (angle_bin > 0) {
2784 score += hist[angle_bin - 1];
2785 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002786 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002787 if (angle_bin < DIRECTIONAL_MODES - 1) {
2788 score += hist[angle_bin + 1];
2789 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 }
2791 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2792 directional_mode_skip_mask[i] = 1;
2793 }
2794 }
2795}
Yaowu Xuf883b422016-08-30 14:01:10 -07002796#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002797#endif // CONFIG_EXT_INTRA
2798
2799// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002800static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2801 int *rate, int *rate_tokenonly,
2802 int64_t *distortion, int *skippable,
2803 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002804 uint8_t mode_idx;
2805 PREDICTION_MODE mode_selected = DC_PRED;
2806 MACROBLOCKD *const xd = &x->e_mbd;
2807 MODE_INFO *const mic = xd->mi[0];
2808 int this_rate, this_rate_tokenonly, s;
2809 int64_t this_distortion, this_rd;
2810 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002811#if CONFIG_EXT_INTRA || CONFIG_PALETTE
2812 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2813 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2814#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002815#if CONFIG_EXT_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07002816 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002817 int is_directional_mode, rate_overhead, best_angle_delta = 0;
2818 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
2819 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002820 const int src_stride = x->plane[0].src.stride;
2821 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002823#if CONFIG_FILTER_INTRA
2824 int beat_best_rd = 0;
2825 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2826 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2827#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002828 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002829 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002830#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002831 PALETTE_MODE_INFO palette_mode_info;
2832 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2833 uint8_t *best_palette_color_map =
2834 cpi->common.allow_screen_content_tools
2835 ? x->palette_buffer->best_palette_color_map
2836 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002837 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002838#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002839 const MODE_INFO *above_mi = xd->above_mi;
2840 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002841 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2842 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002843 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2844 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002845#if CONFIG_PVQ
2846 od_rollback_buffer pre_buf, post_buf;
2847
2848 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2849 od_encode_checkpoint(&x->daala_enc, &post_buf);
2850#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002851 bmode_costs = cpi->y_mode_costs[A][L];
2852
2853#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002854 mic->mbmi.angle_delta[0] = 0;
2855 memset(directional_mode_skip_mask, 0,
2856 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002857#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002858 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2859 highbd_angle_estimation(src, src_stride, rows, cols,
2860 directional_mode_skip_mask);
2861 else
2862#endif
2863 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2864#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002865#if CONFIG_FILTER_INTRA
2866 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2867 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2868#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002869#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002870 palette_mode_info.palette_size[0] = 0;
2871 pmi->palette_size[0] = 0;
2872 if (above_mi)
2873 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2874 if (left_mi)
2875 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002876#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877
2878 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2879 x->use_default_intra_tx_type = 1;
2880 else
2881 x->use_default_intra_tx_type = 0;
2882
2883 /* Y Search for intra prediction mode */
2884 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002885 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002886 if (mode_idx == FINAL_MODE_SEARCH) {
2887 if (x->use_default_intra_tx_type == 0) break;
2888 mic->mbmi.mode = mode_selected;
2889 x->use_default_intra_tx_type = 0;
2890 } else {
2891 mic->mbmi.mode = mode_idx;
2892 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002893#if CONFIG_PVQ
2894 od_encode_rollback(&x->daala_enc, &pre_buf);
2895#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002896#if CONFIG_EXT_INTRA
2897 is_directional_mode =
2898 (mic->mbmi.mode != DC_PRED && mic->mbmi.mode != TM_PRED);
2899 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2900 continue;
2901 if (is_directional_mode) {
2902 rate_overhead = bmode_costs[mic->mbmi.mode] +
2903 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2904 this_rate_tokenonly = INT_MAX;
2905 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate,
2906 &this_rate_tokenonly, &this_distortion,
2907 &s, bsize, rate_overhead, best_rd);
2908 } else {
2909 mic->mbmi.angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002910 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2911 this_rate_tokenonly = this_rd_stats.rate;
2912 this_distortion = this_rd_stats.dist;
2913 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002914 }
2915#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002916 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2917 this_rate_tokenonly = this_rd_stats.rate;
2918 this_distortion = this_rd_stats.dist;
2919 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002920#endif // CONFIG_EXT_INTRA
2921
2922 if (this_rate_tokenonly == INT_MAX) continue;
2923
2924 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2925
2926 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2927 // super_block_yrd above includes the cost of the tx_size in the
2928 // tokenonly rate, but for intra blocks, tx_size is always coded
2929 // (prediction granularity), so we account for it in the full rate,
2930 // not the tokenonly rate.
2931 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002932 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07002933 [tx_size_to_depth(mic->mbmi.tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002934 }
Urvang Joshib100db72016-10-12 16:28:56 -07002935#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002936 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002937 this_rate += av1_cost_bit(
2938 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002939#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002940#if CONFIG_FILTER_INTRA
2941 if (mic->mbmi.mode == DC_PRED)
2942 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2943#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002944#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002945 if (is_directional_mode) {
2946 int p_angle;
2947 this_rate +=
2948 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2949 MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]);
2950 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2951 mic->mbmi.angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002952 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953 this_rate +=
2954 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2955 }
2956#endif // CONFIG_EXT_INTRA
2957 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07002958#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07002959 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002960 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
2961 }
hui su5db97432016-10-14 16:10:14 -07002962#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002963
2964 if (this_rd < best_rd) {
2965 mode_selected = mic->mbmi.mode;
2966 best_rd = this_rd;
2967 best_tx = mic->mbmi.tx_size;
2968#if CONFIG_EXT_INTRA
2969 best_angle_delta = mic->mbmi.angle_delta[0];
2970 best_filter = mic->mbmi.intra_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002971#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002972#if CONFIG_FILTER_INTRA
2973 beat_best_rd = 1;
2974#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002975 best_tx_type = mic->mbmi.tx_type;
2976 *rate = this_rate;
2977 *rate_tokenonly = this_rate_tokenonly;
2978 *distortion = this_distortion;
2979 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002980#if CONFIG_PVQ
2981 od_encode_checkpoint(&x->daala_enc, &post_buf);
2982#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002983 }
2984 }
2985
Yushin Cho77bba8d2016-11-04 16:36:56 -07002986#if CONFIG_PVQ
2987 od_encode_rollback(&x->daala_enc, &post_buf);
2988#endif
2989
Urvang Joshib100db72016-10-12 16:28:56 -07002990#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002991 if (cpi->common.allow_screen_content_tools)
2992 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2993 &palette_mode_info, best_palette_color_map,
2994 &best_tx, &best_tx_type, &mode_selected,
2995 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07002996#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002997
hui su5db97432016-10-14 16:10:14 -07002998#if CONFIG_FILTER_INTRA
2999 if (beat_best_rd) {
3000 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3001 skippable, bsize, bmode_costs[DC_PRED],
3002 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003003 mode_selected = mic->mbmi.mode;
3004 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003005 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003006 best_tx_type = mic->mbmi.tx_type;
3007 }
3008 }
3009
hui su5db97432016-10-14 16:10:14 -07003010 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
3011 filter_intra_mode_info.use_filter_intra_mode[0];
3012 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
3013 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
3014 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07003015#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003017#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003018 }
hui su5db97432016-10-14 16:10:14 -07003019#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003020
3021 mic->mbmi.mode = mode_selected;
3022 mic->mbmi.tx_size = best_tx;
3023#if CONFIG_EXT_INTRA
3024 mic->mbmi.angle_delta[0] = best_angle_delta;
3025 mic->mbmi.intra_filter = best_filter;
3026#endif // CONFIG_EXT_INTRA
3027 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07003028#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003029 pmi->palette_size[0] = palette_mode_info.palette_size[0];
3030 if (palette_mode_info.palette_size[0] > 0) {
3031 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
3032 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3033 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
3034 rows * cols * sizeof(best_palette_color_map[0]));
3035 }
Urvang Joshib100db72016-10-12 16:28:56 -07003036#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003037
3038 return best_rd;
3039}
3040
Yue Chena1e48dc2016-08-29 17:29:33 -07003041// Return value 0: early termination triggered, no valid rd cost available;
3042// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003043static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3044 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3045 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003046 MACROBLOCKD *const xd = &x->e_mbd;
3047 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3048 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3049 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003050 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003051 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003052
3053 if (ref_best_rd < 0) is_cost_valid = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003054#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003055 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003056 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3057 av1_subtract_plane(x, bsize, plane);
3058 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003059#endif
Yue Chena1e48dc2016-08-29 17:29:33 -07003060
Yushin Cho09de28b2016-06-21 14:51:23 -07003061 if (is_cost_valid) {
3062 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003063 RD_STATS pn_rd_stats;
3064 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3065 uv_tx_size, cpi->sf.use_fast_coef_costing);
3066 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003067 is_cost_valid = 0;
3068 break;
3069 }
Angie Chiang284d7772016-11-08 11:06:45 -08003070 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3071 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003072 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003073 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003074 is_cost_valid = 0;
3075 break;
3076 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003077 }
3078 }
3079
3080 if (!is_cost_valid) {
3081 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003082 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003083 }
3084
3085 return is_cost_valid;
3086}
3087
Yaowu Xuc27fc142016-08-22 16:08:15 -07003088#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003089void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3090 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003091 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003092 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003093 MACROBLOCKD *xd = &x->e_mbd;
3094 const struct macroblock_plane *const p = &x->plane[plane];
3095 struct macroblockd_plane *const pd = &xd->plane[plane];
3096 int64_t tmp;
3097 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
3098 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
3099 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003100 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003101 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003102 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003103 int bh = block_size_high[txm_bsize];
3104 int bw = block_size_wide[txm_bsize];
3105 int txb_h = tx_size_high_unit[tx_size];
3106 int txb_w = tx_size_wide_unit[tx_size];
3107
Yaowu Xuc27fc142016-08-22 16:08:15 -07003108 int src_stride = p->src.stride;
3109 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
3110 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07003111#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003112 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3113 uint8_t *rec_buffer;
3114#else
3115 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003116#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003117 int max_blocks_high = block_size_high[plane_bsize];
3118 int max_blocks_wide = block_size_wide[plane_bsize];
3119 const int diff_stride = max_blocks_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003120 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003121 int txb_coeff_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003122#if CONFIG_EXT_TX
3123 assert(tx_size < TX_SIZES);
3124#endif // CONFIG_EXT_TX
3125
3126 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003127 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003128 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003129 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3130
3131 max_blocks_high >>= tx_size_wide_log2[0];
3132 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003133
3134#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07003135 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07003136 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003137#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003138 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07003139 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003140#endif // CONFIG_NEW_QUANT
3141
Yushin Cho721868c2016-11-14 16:04:33 +09003142 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003143 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003144
3145// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003146#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003147 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3148 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003149 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003150 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003151 } else {
3152 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003153 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003154 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003155 }
3156#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003157 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003158 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003159#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003160
Jingning Han9fdc4222016-10-27 21:32:19 -07003161 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003162 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003163 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3164 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003165 tmp = 0;
3166 for (idy = 0; idy < blocks_height; idy += 2) {
3167 for (idx = 0; idx < blocks_width; idx += 2) {
3168 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07003169 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003170 }
3171 }
3172 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003173 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003174 }
3175
Yaowu Xuf883b422016-08-30 14:01:10 -07003176#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3178 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003179#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003180 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003181
3182 if (p->eobs[block] > 0) {
3183 INV_TXFM_PARAM inv_txfm_param;
3184 inv_txfm_param.tx_type = tx_type;
3185 inv_txfm_param.tx_size = tx_size;
3186 inv_txfm_param.eob = p->eobs[block];
3187 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003188// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003189#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003190 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3191 inv_txfm_param.bd = xd->bd;
3192 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3193 } else {
3194 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3195 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003196#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003197 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003198#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003199
Jingning Han4b47c932016-11-03 09:20:08 -07003200 if (txb_w + blk_col > max_blocks_wide ||
3201 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003202 int idx, idy;
3203 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003204 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3205 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003206 tmp = 0;
3207 for (idy = 0; idy < blocks_height; idy += 2) {
3208 for (idx = 0; idx < blocks_width; idx += 2) {
3209 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3210 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3211 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3212 tmp += this_dist;
3213 }
3214 }
3215 } else {
3216 uint32_t this_dist;
3217 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3218 &this_dist);
3219 tmp = this_dist;
3220 }
3221 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003222 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003223 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3224 scan_order->scan, scan_order->neighbors, 0);
3225 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003226 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003227
Angie Chiangd81fdb42016-11-03 12:20:58 -07003228#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003229 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3230 txb_coeff_cost);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003231#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003232}
3233
Yaowu Xuf883b422016-08-30 14:01:10 -07003234static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003235 int blk_col, int plane, int block, int block32,
3236 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003237 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3238 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003239 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003240 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003241 MACROBLOCKD *const xd = &x->e_mbd;
3242 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3243 struct macroblock_plane *const p = &x->plane[plane];
3244 struct macroblockd_plane *const pd = &xd->plane[plane];
3245 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3246 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003247 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003248 [MAX_MIB_SIZE] =
3249 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003250 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3251 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003252 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253 int64_t this_rd = INT64_MAX;
3254 ENTROPY_CONTEXT *pta = ta + blk_col;
3255 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003256 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003257 int ctx =
3258 txfm_partition_context(tx_above + (blk_col >> 1),
3259 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003260
Yaowu Xuc27fc142016-08-22 16:08:15 -07003261 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262 int tmp_eob = 0;
3263 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003264 RD_STATS sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003265
Jingning Han63cbf342016-11-09 15:37:48 -08003266 av1_init_rd_stats(&sum_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003267#if CONFIG_EXT_TX
3268 assert(tx_size < TX_SIZES);
3269#endif // CONFIG_EXT_TX
3270
3271 if (ref_best_rd < 0) {
3272 *is_cost_valid = 0;
3273 return;
3274 }
3275
Jingning Hance059e82016-10-31 16:27:28 -07003276 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003277
Angie Chiangc0feea82016-11-03 15:36:18 -07003278 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003279
3280 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3281
3282 zero_blk_rate =
3283 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
3284
3285 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3286 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003287
3288 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3289 rd_stats_stack[block32].rate != INT_MAX) {
3290 *rd_stats = rd_stats_stack[block32];
3291 p->eobs[block] = !rd_stats->skip;
3292 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3293 } else {
3294 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3295 plane_bsize, coeff_ctx, rd_stats);
3296 if (tx_size == TX_32X32) {
3297 rd_stats_stack[block32] = *rd_stats;
3298 }
3299 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003300
Angie Chiangb5dda482016-11-02 16:19:58 -07003301 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
3302 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
3303 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003304 !xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003305 rd_stats->rate = zero_blk_rate;
3306 rd_stats->dist = rd_stats->sse;
3307 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003308 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3309 p->eobs[block] = 0;
3310 } else {
3311 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003312 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003313 }
3314
Jingning Han571189c2016-10-24 10:38:43 -07003315 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07003316 rd_stats->rate +=
3317 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
3318 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003319 tmp_eob = p->eobs[block];
3320 }
3321
Jingning Han571189c2016-10-24 10:38:43 -07003322 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07003323 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3324 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003325 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07003326 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003327 int this_cost_valid = 1;
3328 int64_t tmp_rd = 0;
3329
Angie Chiangd7246172016-11-03 11:49:15 -07003330 sum_rd_stats.rate =
3331 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332#if CONFIG_EXT_TX
3333 assert(tx_size < TX_SIZES);
3334#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003335 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003336 int offsetr = blk_row + (i >> 1) * bsl;
3337 int offsetc = blk_col + (i & 0x01) * bsl;
3338
3339 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3340
Jingning Han63cbf342016-11-09 15:37:48 -08003341 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07003342 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08003343 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
3344 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003345
Angie Chiangc0feea82016-11-03 15:36:18 -07003346 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003347
Angie Chiangd7246172016-11-03 11:49:15 -07003348 tmp_rd =
3349 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003350 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07003351 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003352 }
3353 if (this_cost_valid) sum_rd = tmp_rd;
3354 }
3355
3356 if (this_rd < sum_rd) {
3357 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07003358 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
3359 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003360 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3361 tx_size);
3362 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003363 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
3364 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003365 inter_tx_size[idy][idx] = tx_size;
3366 mbmi->tx_size = tx_size;
3367 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003368 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003369 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07003370 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003371 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3372 }
3373}
3374
Angie Chiangb5dda482016-11-02 16:19:58 -07003375static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3376 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003377 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003378 MACROBLOCKD *const xd = &x->e_mbd;
3379 int is_cost_valid = 1;
3380 int64_t this_rd = 0;
3381
3382 if (ref_best_rd < 0) is_cost_valid = 0;
3383
Angie Chiangc0feea82016-11-03 15:36:18 -07003384 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003385
3386 if (is_cost_valid) {
3387 const struct macroblockd_plane *const pd = &xd->plane[0];
3388 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3389 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3390 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003391 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003392 const int bh = tx_size_high_unit[max_tx_size];
3393 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003394 int idx, idy;
3395 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003396 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003397 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003398 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3399 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3400 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3401 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3402
Angie Chiangb5dda482016-11-02 16:19:58 -07003403 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003404 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003405
Yaowu Xuf883b422016-08-30 14:01:10 -07003406 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003407 memcpy(tx_above, xd->above_txfm_context,
3408 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3409 memcpy(tx_left, xd->left_txfm_context,
3410 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3411
3412 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003413 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08003414 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07003415 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07003416 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003417 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07003418 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07003419 this_rd += AOMMIN(
3420 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
3421 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003422 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08003423 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003424 }
3425 }
3426 }
3427
Angie Chiangb5dda482016-11-02 16:19:58 -07003428 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3429 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003430 if (this_rd > ref_best_rd) is_cost_valid = 0;
3431
3432 if (!is_cost_valid) {
3433 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003434 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003435 }
3436}
3437
Yaowu Xuf883b422016-08-30 14:01:10 -07003438static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07003439 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003440 int64_t ref_best_rd, TX_TYPE tx_type,
3441 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003442 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003443 MACROBLOCKD *const xd = &x->e_mbd;
3444 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003445 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003446 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3447 int s0 = av1_cost_bit(skip_prob, 0);
3448 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003449 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07003450 int row, col;
3451 const int max_blocks_high = max_block_high(xd, bsize, 0);
3452 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003453
3454 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07003455 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08003456 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yue Chena1e48dc2016-08-29 17:29:33 -07003457#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07003458 if (is_rect_tx_allowed(xd, mbmi)) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003459 RD_STATS rect_rd_stats;
3460 int64_t rd_rect_tx;
Yue Chena1e48dc2016-08-29 17:29:33 -07003461 int tx_size_cat = inter_tx_size_cat_lookup[bsize];
3462 TX_SIZE tx_size = max_txsize_rect_lookup[bsize];
3463 TX_SIZE var_tx_size = mbmi->tx_size;
3464
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003465 txfm_rd_in_plane(x, cpi, &rect_rd_stats, ref_best_rd, 0, bsize, tx_size,
3466 cpi->sf.use_fast_coef_costing);
Yue Chena1e48dc2016-08-29 17:29:33 -07003467
Angie Chiangb5dda482016-11-02 16:19:58 -07003468 if (rd_stats->rate != INT_MAX) {
3469 rd_stats->rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 0);
3470 if (rd_stats->skip) {
3471 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yue Chena1e48dc2016-08-29 17:29:33 -07003472 } else {
Angie Chiangb5dda482016-11-02 16:19:58 -07003473 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yue Chena1e48dc2016-08-29 17:29:33 -07003474 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
Angie Chiangb5dda482016-11-02 16:19:58 -07003475 !rd_stats->skip)
3476 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yue Chena1e48dc2016-08-29 17:29:33 -07003477 }
3478 } else {
3479 rd = INT64_MAX;
3480 }
3481
Angie Chiangb5dda482016-11-02 16:19:58 -07003482 if (rect_rd_stats.rate != INT_MAX) {
3483 rect_rd_stats.rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 1);
3484 if (rect_rd_stats.skip) {
3485 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, s1, rect_rd_stats.sse);
Yue Chena1e48dc2016-08-29 17:29:33 -07003486 } else {
Angie Chiangb5dda482016-11-02 16:19:58 -07003487 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, rect_rd_stats.rate + s0,
3488 rect_rd_stats.dist);
Yue Chena1e48dc2016-08-29 17:29:33 -07003489 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
Angie Chiangb5dda482016-11-02 16:19:58 -07003490 !(rect_rd_stats.skip))
3491 rd_rect_tx = AOMMIN(
3492 rd_rect_tx, RDCOST(x->rdmult, x->rddiv, s1, rect_rd_stats.sse));
Yue Chena1e48dc2016-08-29 17:29:33 -07003493 }
3494 } else {
3495 rd_rect_tx = INT64_MAX;
3496 }
3497
3498 if (rd_rect_tx < rd) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003499 *rd_stats = rect_rd_stats;
3500 if (!xd->lossless[mbmi->segment_id]) x->blk_skip[0][0] = rd_stats->skip;
Yue Chena1e48dc2016-08-29 17:29:33 -07003501 mbmi->tx_size = tx_size;
3502 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
3503 } else {
3504 mbmi->tx_size = var_tx_size;
3505 }
3506 }
3507#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003508
Angie Chiangb5dda482016-11-02 16:19:58 -07003509 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003510
Jingning Hane67b38a2016-11-04 10:30:00 -07003511 for (row = 0; row < max_blocks_high / 2; ++row)
3512 for (col = 0; col < max_blocks_wide / 2; ++col)
3513 mbmi->min_tx_size = AOMMIN(
3514 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
3515
Yaowu Xuc27fc142016-08-22 16:08:15 -07003516#if CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003517 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003518 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07003519 int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 if (is_inter) {
3521 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07003522 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07003523 cpi->inter_tx_type_costs[ext_tx_set]
3524 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003525 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003526 } else {
3527 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07003528 rd_stats->rate +=
3529 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
3530 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003531 }
3532 }
3533#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003534 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
3535 rd_stats->rate +=
3536 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003537#endif // CONFIG_EXT_TX
3538
Angie Chiangb5dda482016-11-02 16:19:58 -07003539 if (rd_stats->skip)
3540 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003541 else
Angie Chiangb5dda482016-11-02 16:19:58 -07003542 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003543
Angie Chiangb5dda482016-11-02 16:19:58 -07003544 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3545 !(rd_stats->skip))
3546 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003547
3548 return rd;
3549}
3550
Angie Chiangb5dda482016-11-02 16:19:58 -07003551static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3552 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003553 int64_t ref_best_rd) {
3554 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3555 MACROBLOCKD *const xd = &x->e_mbd;
3556 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3557 int64_t rd = INT64_MAX;
3558 int64_t best_rd = INT64_MAX;
3559 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3560 const int is_inter = is_inter_block(mbmi);
3561 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003562 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07003563 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003564 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3565 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3566 int idx, idy;
3567 int prune = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003568 RD_STATS rd_stats_stack[4];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569#if CONFIG_EXT_TX
3570 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3571#endif // CONFIG_EXT_TX
3572
3573 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3574#if CONFIG_EXT_TX
3575 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3576#else
3577 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3578#endif
3579
Angie Chiangc0feea82016-11-03 15:36:18 -07003580 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003581
Jingning Han63cbf342016-11-09 15:37:48 -08003582 for (idx = 0; idx < 4; ++idx) av1_invalid_rd_stats(&rd_stats_stack[idx]);
3583
Yaowu Xuc27fc142016-08-22 16:08:15 -07003584 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003585 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003586 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003587#if CONFIG_EXT_TX
3588 if (is_inter) {
3589 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3590 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3591 if (!do_tx_type_search(tx_type, prune)) continue;
3592 }
3593 } else {
3594 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3595 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3596 }
3597 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3598 }
3599#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003600 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3601 !do_tx_type_search(tx_type, prune))
3602 continue;
3603#endif // CONFIG_EXT_TX
3604 if (is_inter && x->use_default_inter_tx_type &&
3605 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3606 continue;
3607
Jingning Hane67b38a2016-11-04 10:30:00 -07003608 if (xd->lossless[mbmi->segment_id])
3609 if (tx_type != DCT_DCT) continue;
3610
Angie Chiangb5dda482016-11-02 16:19:58 -07003611 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003612 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003613
3614 if (rd < best_rd) {
3615 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07003616 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003617 best_tx_type = mbmi->tx_type;
3618 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07003619 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3621 for (idy = 0; idy < xd->n8_h; ++idy)
3622 for (idx = 0; idx < xd->n8_w; ++idx)
3623 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3624 }
3625 }
3626
3627 mbmi->tx_type = best_tx_type;
3628 for (idy = 0; idy < xd->n8_h; ++idy)
3629 for (idx = 0; idx < xd->n8_w; ++idx)
3630 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3631 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07003632 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003633 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3634}
3635
Yaowu Xuf883b422016-08-30 14:01:10 -07003636static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003637 int blk_col, int plane, int block, TX_SIZE tx_size,
3638 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07003639 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003640 MACROBLOCKD *const xd = &x->e_mbd;
3641 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3642 struct macroblock_plane *const p = &x->plane[plane];
3643 struct macroblockd_plane *const pd = &xd->plane[plane];
3644 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3645 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3646 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3647 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07003648 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3649 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003650
3651#if CONFIG_EXT_TX
3652 assert(tx_size < TX_SIZES);
3653#endif // CONFIG_EXT_TX
3654
Yaowu Xuc27fc142016-08-22 16:08:15 -07003655 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3656
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003657 plane_tx_size =
3658 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3659 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003660
3661 if (tx_size == plane_tx_size) {
3662 int coeff_ctx, i;
3663 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3664 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07003665 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07003666 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003667 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07003668
Jingning Han58224042016-10-27 16:35:32 -07003669 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003670 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07003671 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003672 tl[i] = !(p->eobs[block] == 0);
3673 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07003674 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3675 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003676 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 int i;
3678
3679 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003680
3681 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003682 int offsetr = blk_row + (i >> 1) * bsl;
3683 int offsetc = blk_col + (i & 0x01) * bsl;
3684
3685 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3686
3687 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
3688 above_ctx, left_ctx, rd_stats);
3689 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003690 }
3691 }
3692}
3693
3694// Return value 0: early termination triggered, no valid rd cost available;
3695// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07003696static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
3697 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3698 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699 MACROBLOCKD *const xd = &x->e_mbd;
3700 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3701 int plane;
3702 int is_cost_valid = 1;
3703 int64_t this_rd;
3704
3705 if (ref_best_rd < 0) is_cost_valid = 0;
3706
Angie Chiangc0feea82016-11-03 15:36:18 -07003707 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003708
3709#if CONFIG_EXT_TX && CONFIG_RECT_TX
3710 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08003711 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003712 }
3713#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3714
Yaowu Xuc27fc142016-08-22 16:08:15 -07003715 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003716 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003717 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003718 }
3719
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3721 const struct macroblockd_plane *const pd = &xd->plane[plane];
3722 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3723 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3724 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003725 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003726 const int bh = tx_size_high_unit[max_tx_size];
3727 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003728 int idx, idy;
3729 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003730 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003731 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3732 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07003733 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003734 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003735
Yaowu Xuf883b422016-08-30 14:01:10 -07003736 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003737
3738 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003739 for (idx = 0; idx < mi_width; idx += bw) {
3740 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07003741 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003742 block += step;
3743 }
3744 }
3745
Angie Chiangb5dda482016-11-02 16:19:58 -07003746 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003747 is_cost_valid = 0;
3748 break;
3749 }
3750
Angie Chiang628d7c92016-11-03 16:24:56 -07003751 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752
Angie Chiangb5dda482016-11-02 16:19:58 -07003753 this_rd =
3754 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3755 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003756
3757 if (this_rd > ref_best_rd) {
3758 is_cost_valid = 0;
3759 break;
3760 }
3761 }
3762
3763 if (!is_cost_valid) {
3764 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003765 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003766 }
3767
3768 return is_cost_valid;
3769}
3770#endif // CONFIG_VAR_TX
3771
Urvang Joshib100db72016-10-12 16:28:56 -07003772#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003773static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003774 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003775 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3776 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3777 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3778 MACROBLOCKD *const xd = &x->e_mbd;
3779 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3780 const BLOCK_SIZE bsize = mbmi->sb_type;
3781 const int rows =
3782 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3783 const int cols =
3784 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
Angie Chiang284d7772016-11-08 11:06:45 -08003785 int this_rate;
3786 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003787 int colors_u, colors_v, colors;
3788 const int src_stride = x->plane[1].src.stride;
3789 const uint8_t *const src_u = x->plane[1].src.buf;
3790 const uint8_t *const src_v = x->plane[2].src.buf;
Angie Chiang284d7772016-11-08 11:06:45 -08003791 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003792
3793 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3794
hui su5db97432016-10-14 16:10:14 -07003795#if CONFIG_FILTER_INTRA
3796 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3797#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003798
Yaowu Xuf883b422016-08-30 14:01:10 -07003799#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003800 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003801 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3802 cpi->common.bit_depth);
3803 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3804 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003805 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003806#endif // CONFIG_AOM_HIGHBITDEPTH
3807 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3808 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3809#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003810 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003811#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003812
3813 colors = colors_u > colors_v ? colors_u : colors_v;
3814 if (colors > 1 && colors <= 64) {
3815 int r, c, n, i, j;
3816 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003817 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003818 float lb_u, ub_u, val_u;
3819 float lb_v, ub_v, val_v;
3820 float *const data = x->palette_buffer->kmeans_data_buf;
3821 float centroids[2 * PALETTE_MAX_SIZE];
3822 uint8_t *const color_map = xd->plane[1].color_index_map;
3823 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3824
Yaowu Xuf883b422016-08-30 14:01:10 -07003825#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003826 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3827 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3828 if (cpi->common.use_highbitdepth) {
3829 lb_u = src_u16[0];
3830 ub_u = src_u16[0];
3831 lb_v = src_v16[0];
3832 ub_v = src_v16[0];
3833 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003834#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835 lb_u = src_u[0];
3836 ub_u = src_u[0];
3837 lb_v = src_v[0];
3838 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003839#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003841#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003842
3843 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003844#if CONFIG_FILTER_INTRA
3845 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3846#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847 for (r = 0; r < rows; ++r) {
3848 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003849#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003850 if (cpi->common.use_highbitdepth) {
3851 val_u = src_u16[r * src_stride + c];
3852 val_v = src_v16[r * src_stride + c];
3853 data[(r * cols + c) * 2] = val_u;
3854 data[(r * cols + c) * 2 + 1] = val_v;
3855 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003856#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 val_u = src_u[r * src_stride + c];
3858 val_v = src_v[r * src_stride + c];
3859 data[(r * cols + c) * 2] = val_u;
3860 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003861#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003862 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003863#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003864 if (val_u < lb_u)
3865 lb_u = val_u;
3866 else if (val_u > ub_u)
3867 ub_u = val_u;
3868 if (val_v < lb_v)
3869 lb_v = val_v;
3870 else if (val_v > ub_v)
3871 ub_v = val_v;
3872 }
3873 }
3874
3875 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3876 --n) {
3877 for (i = 0; i < n; ++i) {
3878 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3879 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3880 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003881 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003882 pmi->palette_size[1] = n;
3883 for (i = 1; i < 3; ++i) {
3884 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003885#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886 if (cpi->common.use_highbitdepth)
3887 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3888 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3889 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003890#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3892 clip_pixel((int)centroids[j * 2 + i - 1]);
3893 }
3894 }
3895
Angie Chiang284d7772016-11-08 11:06:45 -08003896 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3897 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08003899 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003900 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003901 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3902 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003903 av1_cost_bit(
3904 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905
3906 for (i = 0; i < rows; ++i) {
3907 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003908 int color_idx;
3909 const int color_ctx = av1_get_palette_color_context(
3910 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003911 assert(color_idx >= 0 && color_idx < n);
3912 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3913 }
3914 }
3915
Angie Chiang284d7772016-11-08 11:06:45 -08003916 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003917 if (this_rd < *best_rd) {
3918 *best_rd = this_rd;
3919 *palette_mode_info = *pmi;
3920 memcpy(best_palette_color_map, color_map,
3921 rows * cols * sizeof(best_palette_color_map[0]));
3922 *mode_selected = DC_PRED;
3923 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003924 *distortion = tokenonly_rd_stats.dist;
3925 *rate_tokenonly = tokenonly_rd_stats.rate;
3926 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003927 }
3928 }
3929 }
3930}
Urvang Joshib100db72016-10-12 16:28:56 -07003931#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003932
hui su5db97432016-10-14 16:10:14 -07003933#if CONFIG_FILTER_INTRA
3934// Return 1 if an filter intra mode is selected; return 0 otherwise.
3935static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3936 int *rate, int *rate_tokenonly,
3937 int64_t *distortion, int *skippable,
3938 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003939 MACROBLOCKD *const xd = &x->e_mbd;
3940 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003941 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08003942 int this_rate;
3943 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07003944 FILTER_INTRA_MODE mode;
3945 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08003946 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947
hui su5db97432016-10-14 16:10:14 -07003948 av1_zero(filter_intra_mode_info);
3949 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003950 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003951#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003952 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003953#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954
3955 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003956 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08003957 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003958 continue;
3959
Angie Chiang284d7772016-11-08 11:06:45 -08003960 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003961 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003962 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3963 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08003964 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965 if (this_rd < *best_rd) {
3966 *best_rd = this_rd;
3967 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003968 *rate_tokenonly = tokenonly_rd_stats.rate;
3969 *distortion = tokenonly_rd_stats.dist;
3970 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003971 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3972 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003973 }
3974 }
3975
hui su5db97432016-10-14 16:10:14 -07003976 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003977 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003978 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3979 filter_intra_mode_info.use_filter_intra_mode[1];
3980 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3981 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982 return 1;
3983 } else {
3984 return 0;
3985 }
3986}
hui su5db97432016-10-14 16:10:14 -07003987#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003988
hui su5db97432016-10-14 16:10:14 -07003989#if CONFIG_EXT_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003990static void pick_intra_angle_routine_sbuv(
3991 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
3992 int64_t *distortion, int *skippable, int *best_angle_delta,
3993 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003994 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08003995 int this_rate;
3996 int64_t this_rd;
3997 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003998
Angie Chiang284d7772016-11-08 11:06:45 -08003999 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004000
Angie Chiang284d7772016-11-08 11:06:45 -08004001 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4002 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004003 if (this_rd < *best_rd) {
4004 *best_rd = this_rd;
4005 *best_angle_delta = mbmi->angle_delta[1];
4006 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004007 *rate_tokenonly = tokenonly_rd_stats.rate;
4008 *distortion = tokenonly_rd_stats.dist;
4009 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004010 }
4011}
4012
Urvang Joshi52648442016-10-13 17:27:51 -07004013static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4014 int *rate, int *rate_tokenonly,
4015 int64_t *distortion, int *skippable,
4016 BLOCK_SIZE bsize, int rate_overhead,
4017 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004018 MACROBLOCKD *const xd = &x->e_mbd;
4019 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004020 int this_rate;
4021 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004022 int angle_delta, best_angle_delta = 0;
4023 const double rd_adjust = 1.2;
Angie Chiang284d7772016-11-08 11:06:45 -08004024 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004025
4026 *rate_tokenonly = INT_MAX;
4027 if (ANGLE_FAST_SEARCH) {
4028 int deltas_level1[3] = { 0, -2, 2 };
4029 int deltas_level2[3][2] = {
4030 { -1, 1 }, { -3, -1 }, { 1, 3 },
4031 };
4032 const int level1 = 3, level2 = 2;
4033 int i, j, best_i = -1;
4034
4035 for (i = 0; i < level1; ++i) {
4036 int64_t tmp_best_rd;
4037 mbmi->angle_delta[1] = deltas_level1[i];
4038 tmp_best_rd = (i == 0 && best_rd < INT64_MAX)
4039 ? (int64_t)(best_rd * rd_adjust)
4040 : best_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004041 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004042 if (i == 0)
4043 break;
4044 else
4045 continue;
4046 }
Angie Chiang284d7772016-11-08 11:06:45 -08004047 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4048 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004049 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) break;
4050 if (this_rd < best_rd) {
4051 best_i = i;
4052 best_rd = this_rd;
4053 best_angle_delta = mbmi->angle_delta[1];
4054 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004055 *rate_tokenonly = tokenonly_rd_stats.rate;
4056 *distortion = tokenonly_rd_stats.dist;
4057 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004058 }
4059 }
4060
4061 if (best_i >= 0) {
4062 for (j = 0; j < level2; ++j) {
4063 mbmi->angle_delta[1] = deltas_level2[best_i][j];
4064 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4065 skippable, &best_angle_delta, bsize,
4066 rate_overhead, &best_rd);
4067 }
4068 }
4069 } else {
4070 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
4071 ++angle_delta) {
4072 mbmi->angle_delta[1] = angle_delta;
4073 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4074 skippable, &best_angle_delta, bsize,
4075 rate_overhead, &best_rd);
4076 }
4077 }
4078
4079 mbmi->angle_delta[1] = best_angle_delta;
4080 return *rate_tokenonly != INT_MAX;
4081}
4082#endif // CONFIG_EXT_INTRA
4083
Urvang Joshi52648442016-10-13 17:27:51 -07004084static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4085 int *rate, int *rate_tokenonly,
4086 int64_t *distortion, int *skippable,
4087 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004088 MACROBLOCKD *xd = &x->e_mbd;
4089 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4090 PREDICTION_MODE mode;
4091 PREDICTION_MODE mode_selected = DC_PRED;
4092 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004093 int this_rate;
4094 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004095#if CONFIG_PVQ
4096 od_rollback_buffer buf;
4097
4098 od_encode_checkpoint(&x->daala_enc, &buf);
4099#endif
Urvang Joshib100db72016-10-12 16:28:56 -07004100#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004101 const int rows =
4102 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
4103 const int cols =
4104 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
4105 PALETTE_MODE_INFO palette_mode_info;
4106 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
4107 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004108#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004109#if CONFIG_EXT_INTRA
4110 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004111#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004112#if CONFIG_FILTER_INTRA
4113 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
4114
4115 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4116 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4117#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004118#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004119 palette_mode_info.palette_size[1] = 0;
4120 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004121#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004122 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
4123 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
4124
4125 mbmi->uv_mode = mode;
4126#if CONFIG_EXT_INTRA
4127 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
4128 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4129 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
4130 mbmi->angle_delta[1] = 0;
4131 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
Angie Chiang284d7772016-11-08 11:06:45 -08004132 if (!rd_pick_intra_angle_sbuv(
4133 cpi, x, &this_rate, &tokenonly_rd_stats.rate,
4134 &tokenonly_rd_stats.dist, &tokenonly_rd_stats.skip, bsize,
4135 rate_overhead, best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004136 continue;
4137 } else {
Angie Chiang284d7772016-11-08 11:06:45 -08004138 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004139#if CONFIG_PVQ
4140 od_encode_rollback(&x->daala_enc, &buf);
4141#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004143 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144 }
Angie Chiang284d7772016-11-08 11:06:45 -08004145 this_rate =
4146 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
4148 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
4149 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004150#else
Angie Chiang284d7772016-11-08 11:06:45 -08004151 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004152#if CONFIG_PVQ
4153 od_encode_rollback(&x->daala_enc, &buf);
4154#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004155 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004156 }
Angie Chiang284d7772016-11-08 11:06:45 -08004157 this_rate =
4158 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004159#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004160#if CONFIG_FILTER_INTRA
4161 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4162 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4163#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004164#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004165 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4166 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004167 this_rate += av1_cost_bit(
4168 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004169#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004170
Yushin Cho77bba8d2016-11-04 16:36:56 -07004171#if CONFIG_PVQ
4172 // For chroma channels, multiply lambda by 0.5 when doing intra prediction
4173 // NOTE: Chroma intra prediction itself has a separate RDO,
4174 // though final chroma intra mode's D and R is simply added to
4175 // those of luma then global RDO is performed to decide the modes of SB.
4176 // Also, for chroma, the RDO cannot decide tx_size (follow luma's decision)
4177 // or tx_type (DCT only), then only the intra prediction is
4178 // chroma's own mode decision based on separate RDO.
4179 // TODO(yushin) : Seek for more reasonable solution than this.
4180 this_rd = RDCOST(x->rdmult >> (1 * PVQ_CHROMA_RD), x->rddiv, this_rate,
Angie Chiang284d7772016-11-08 11:06:45 -08004181 tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004182 od_encode_rollback(&x->daala_enc, &buf);
4183#else
Angie Chiang284d7772016-11-08 11:06:45 -08004184 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004185#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186
4187 if (this_rd < best_rd) {
4188 mode_selected = mode;
4189#if CONFIG_EXT_INTRA
4190 best_angle_delta = mbmi->angle_delta[1];
4191#endif // CONFIG_EXT_INTRA
4192 best_rd = this_rd;
4193 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004194 *rate_tokenonly = tokenonly_rd_stats.rate;
4195 *distortion = tokenonly_rd_stats.dist;
4196 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197 }
4198 }
4199
Urvang Joshib100db72016-10-12 16:28:56 -07004200#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004201 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4202 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4203 rd_pick_palette_intra_sbuv(
4204 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4205 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4206 rate, rate_tokenonly, distortion, skippable);
4207 }
Urvang Joshib100db72016-10-12 16:28:56 -07004208#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209
hui su5db97432016-10-14 16:10:14 -07004210#if CONFIG_FILTER_INTRA
4211 if (mbmi->sb_type >= BLOCK_8X8) {
4212 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4213 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004214 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004215 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004216 }
4217 }
4218
hui su5db97432016-10-14 16:10:14 -07004219 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4220 filter_intra_mode_info.use_filter_intra_mode[1];
4221 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4222 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4223 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004224#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004226#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004227 }
hui su5db97432016-10-14 16:10:14 -07004228#endif // CONFIG_FILTER_INTRA
4229
4230#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231 mbmi->angle_delta[1] = best_angle_delta;
4232#endif // CONFIG_EXT_INTRA
4233 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004234#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004235 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4236 if (palette_mode_info.palette_size[1] > 0) {
4237 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4238 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4239 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4240 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4241 rows * cols * sizeof(best_palette_color_map[0]));
4242 }
Urvang Joshib100db72016-10-12 16:28:56 -07004243#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004244
4245 return best_rd;
4246}
4247
Urvang Joshi52648442016-10-13 17:27:51 -07004248static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004249 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4250 TX_SIZE max_tx_size, int *rate_uv,
4251 int *rate_uv_tokenonly, int64_t *dist_uv,
4252 int *skip_uv, PREDICTION_MODE *mode_uv) {
4253 // Use an estimated rd for uv_intra based on DC_PRED if the
4254 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004255 (void)ctx;
4256 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4257 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004258 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4259}
4260
Urvang Joshi52648442016-10-13 17:27:51 -07004261static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004262#if CONFIG_REF_MV && CONFIG_EXT_INTER
4263 int is_compound,
4264#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4265 int16_t mode_context) {
4266#if CONFIG_REF_MV
4267 int mode_cost = 0;
4268#if CONFIG_EXT_INTER
4269 int16_t mode_ctx =
4270 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4271#else
4272 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4273#endif // CONFIG_EXT_INTER
4274 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4275
4276 assert(is_inter_mode(mode));
4277
4278#if CONFIG_EXT_INTER
4279 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004280 return cpi->inter_compound_mode_cost[mode_context]
4281 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 } else {
4283 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4284#else
4285 if (mode == NEWMV) {
4286#endif // CONFIG_EXT_INTER
4287 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4288#if CONFIG_EXT_INTER
4289 if (!is_compound)
4290 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4291#endif // CONFIG_EXT_INTER
4292 return mode_cost;
4293 } else {
4294 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4295 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4296
4297 if (is_all_zero_mv) return mode_cost;
4298
4299 if (mode == ZEROMV) {
4300 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4301 return mode_cost;
4302 } else {
4303 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4304 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4305
4306 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4307 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4308 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4309
4310 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4311 return mode_cost;
4312 }
4313 }
4314#if CONFIG_EXT_INTER
4315 }
4316#endif // CONFIG_EXT_INTER
4317#else
4318 assert(is_inter_mode(mode));
4319#if CONFIG_EXT_INTER
4320 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004321 return cpi->inter_compound_mode_cost[mode_context]
4322 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323 } else {
4324#endif // CONFIG_EXT_INTER
4325 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4326#if CONFIG_EXT_INTER
4327 }
4328#endif // CONFIG_EXT_INTER
4329#endif
4330}
4331
Sarah Parkere5299862016-08-16 14:57:37 -07004332#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004333#define GLOBAL_MOTION_COST_AMORTIZATION_BLKS 8
4334
4335#if GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
David Barkercf3d0b02016-11-10 10:14:49 +00004336static int get_gmbitcost(const WarpedMotionParams *gm, const aom_prob *probs) {
4337 int gmtype_cost[TRANS_TYPES];
Sarah Parkere5299862016-08-16 14:57:37 -07004338 int bits;
David Barkercf3d0b02016-11-10 10:14:49 +00004339 TransformationType type = gm->wmtype;
Sarah Parkere5299862016-08-16 14:57:37 -07004340 av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
David Barkercf3d0b02016-11-10 10:14:49 +00004341 switch (type) {
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004342 case HOMOGRAPHY:
4343 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4 +
4344 (GM_ABS_ROW3HOMO_BITS + 1) * 2;
4345 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004346 case AFFINE:
4347 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004348 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004349 case ROTZOOM:
4350 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 2;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004351 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004352 case TRANSLATION: bits = (GM_ABS_TRANS_BITS + 1) * 2; break;
4353 case IDENTITY: bits = 0; break;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004354 default: assert(0); return 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004355 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004356 assert(type < GLOBAL_TRANS_TYPES);
David Barkercf3d0b02016-11-10 10:14:49 +00004357 return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[type] : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004358}
4359
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004360#define GLOBAL_MOTION_RATE(ref) \
4361 (cpi->global_motion_used[ref] >= GLOBAL_MOTION_COST_AMORTIZATION_BLKS \
4362 ? 0 \
4363 : get_gmbitcost(&cm->global_motion[(ref)], \
4364 cm->fc->global_motion_types_prob) / \
Debargha Mukherjeeb2a0cfd2016-11-15 12:22:48 -08004365 GLOBAL_MOTION_COST_AMORTIZATION_BLKS)
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004366#else
4367#define GLOBAL_MOTION_RATE(ref) 0
4368#endif // GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
Sarah Parkere5299862016-08-16 14:57:37 -07004369#endif // CONFIG_GLOBAL_MOTION
4370
Urvang Joshi52648442016-10-13 17:27:51 -07004371static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4372 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4373 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004374 int_mv frame_mv[MB_MODE_COUNT]
4375 [TOTAL_REFS_PER_FRAME],
4376 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004377#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004378 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004380 int_mv *best_ref_mv[2], const int *mvjcost,
4381 int *mvcost[2]) {
Sarah Parkere5299862016-08-16 14:57:37 -07004382#if CONFIG_GLOBAL_MOTION
4383 const AV1_COMMON *cm = &cpi->common;
4384#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385 MODE_INFO *const mic = xd->mi[0];
4386 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4387 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4388 int thismvcost = 0;
4389 int idx, idy;
4390 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4391 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4392 const int is_compound = has_second_ref(mbmi);
4393 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4394
4395 switch (mode) {
4396 case NEWMV:
4397#if CONFIG_EXT_INTER
4398 case NEWFROMNEARMV:
4399#endif // CONFIG_EXT_INTER
4400 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4401#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07004402 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004403 lower_mv_precision(&this_mv[0].as_mv, 0);
4404#endif // CONFIG_EXT_INTER
4405
4406#if CONFIG_REF_MV
4407 for (idx = 0; idx < 1 + is_compound; ++idx) {
4408 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004409 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004411 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4412 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004413 }
4414 (void)mvjcost;
4415 (void)mvcost;
4416#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004417 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4418 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419#if !CONFIG_EXT_INTER
4420 if (is_compound) {
4421 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004422 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4423 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424 }
4425#endif // !CONFIG_EXT_INTER
4426#endif
4427 break;
4428 case NEARMV:
4429 case NEARESTMV:
4430 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4431 if (is_compound)
4432 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4433 break;
4434 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004435#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004436 this_mv[0].as_int =
4437 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]])
4438 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004439 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
4440 if (is_compound) {
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004441 this_mv[1].as_int =
4442 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]])
4443 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004444 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
4445 }
4446#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004447 this_mv[0].as_int = 0;
4448 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004449#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004450 break;
4451#if CONFIG_EXT_INTER
4452 case NEW_NEWMV:
4453 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4454 compound_seg_newmvs[1].as_int == INVALID_MV) {
4455 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4456 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4457 } else {
4458 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4459 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4460 }
Alex Converse6317c882016-09-29 14:21:37 -07004461 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004462 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07004463 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004464 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004465 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4466 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4467 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4468 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004469 break;
4470 case NEW_NEARMV:
4471 case NEW_NEARESTMV:
4472 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004473 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004474 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004475 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4476 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004477 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4478 break;
4479 case NEAR_NEWMV:
4480 case NEAREST_NEWMV:
4481 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4482 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004483 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004484 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004485 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4486 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004487 break;
4488 case NEAREST_NEARMV:
4489 case NEAR_NEARESTMV:
4490 case NEAREST_NEARESTMV:
4491 case NEAR_NEARMV:
4492 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4493 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4494 break;
4495 case ZERO_ZEROMV:
4496 this_mv[0].as_int = 0;
4497 this_mv[1].as_int = 0;
4498 break;
4499#endif // CONFIG_EXT_INTER
4500 default: break;
4501 }
4502
4503 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4504 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4505
4506 mic->bmi[i].as_mode = mode;
4507
4508#if CONFIG_REF_MV
4509 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004510 mic->bmi[i].pred_mv[0].as_int =
4511 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4512 if (is_compound)
4513 mic->bmi[i].pred_mv[1].as_int =
4514 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004515 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004516 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4517 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004518 }
4519#endif
4520
4521 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4522 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4523 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4524
4525#if CONFIG_REF_MV
4526#if CONFIG_EXT_INTER
4527 if (is_compound)
4528 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4529 else
4530#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004531 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4532 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533#endif
4534#if CONFIG_REF_MV && CONFIG_EXT_INTER
4535 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4536#else
4537 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4538#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4539}
4540
Urvang Joshi52648442016-10-13 17:27:51 -07004541static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004542 int64_t best_yrd, int i, int *labelyrate,
4543 int64_t *distortion, int64_t *sse,
4544 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4545 int ir, int ic, int mi_row, int mi_col) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004546#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07004547 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004548#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004549 int k;
4550 MACROBLOCKD *xd = &x->e_mbd;
4551 struct macroblockd_plane *const pd = &xd->plane[0];
4552 struct macroblock_plane *const p = &x->plane[0];
4553 MODE_INFO *const mi = xd->mi[0];
4554 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanc4049db2016-10-27 14:44:13 -07004555 const int width = block_size_wide[plane_bsize];
4556 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557 int idx, idy;
4558 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004559 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004560 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004561 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004562 int64_t thisdistortion = 0, thissse = 0;
4563 int thisrate = 0;
4564 TX_SIZE tx_size = mi->mbmi.tx_size;
4565
4566 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07004567 const int num_4x4_w = tx_size_wide_unit[tx_size];
4568 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004569#if !CONFIG_PVQ
4570 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
4571#else
4572 (void)cpi;
4573 (void)ta;
4574 (void)tl;
4575#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004576
4577#if CONFIG_EXT_TX && CONFIG_RECT_TX
4578 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4579 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4580 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4581#else
4582 assert(tx_size == TX_4X4);
4583#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4584 assert(tx_type == DCT_DCT);
4585
Yaowu Xuf883b422016-08-30 14:01:10 -07004586 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004587
Yushin Cho77bba8d2016-11-04 16:36:56 -07004588#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07004589#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004590 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004591 aom_highbd_subtract_block(
4592 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4593 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004594 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004595 aom_subtract_block(height, width,
4596 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004597 8, src, p->src.stride, dst, pd->dst.stride);
4598 }
4599#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004600 aom_subtract_block(height, width,
4601 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004602 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004603#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -07004604#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004605
4606 k = i;
4607 for (idy = 0; idy < height / 4; idy += num_4x4_h) {
4608 for (idx = 0; idx < width / 4; idx += num_4x4_w) {
4609 int64_t dist, ssz, rd, rd1, rd2;
4610 int block;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004611#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004612 int coeff_ctx;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004613#else
Yushin Cho77bba8d2016-11-04 16:36:56 -07004614 const int src_stride = p->src.stride;
4615 const int dst_stride = pd->dst.stride;
4616 const int diff_stride = 8;
4617 tran_low_t *coeff;
4618 tran_low_t *dqcoeff;
4619 tran_low_t *ref_coeff;
4620 int16_t *pred = &pd->pred[4 * (ir * diff_stride + ic)];
4621 int16_t *src_int16 = &p->src_int16[4 * (ir * diff_stride + ic)];
4622 int ii, j, tx_blk_size;
4623 int rate_pvq;
4624#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004625 k += (idy * 2 + idx);
4626 if (tx_size == TX_4X4)
4627 block = k;
4628 else
4629 block = (i ? 2 : 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004630#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004631 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
4632#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07004633 av1_xform_quant_fp_nuq(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Yaowu Xuf883b422016-08-30 14:01:10 -07004634 BLOCK_8X8, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004636 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4637 BLOCK_8X8, tx_size, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638#endif // CONFIG_NEW_QUANT
4639 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004640 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004641#else
4642 coeff = BLOCK_OFFSET(p->coeff, k);
4643 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, k);
4644 ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, k);
4645
4646 // transform block size in pixels
4647 tx_blk_size = 4;
4648
4649 // copy uint8 orig and predicted block to int16 buffer
4650 // in order to use existing VP10 transform functions
4651 for (j = 0; j < tx_blk_size; j++)
4652 for (ii = 0; ii < tx_blk_size; ii++) {
4653 src_int16[diff_stride * j + ii] =
4654 src[src_stride * (j + 4 * idy) + (ii + 4 * idx)];
4655 pred[diff_stride * j + ii] =
4656 dst[dst_stride * (j + 4 * idy) + (ii + 4 * idx)];
4657 }
4658
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004659 {
4660 FWD_TXFM_PARAM fwd_txfm_param;
4661 fwd_txfm_param.tx_type = DCT_DCT;
4662 fwd_txfm_param.tx_size = TX_4X4;
4663 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
4664 fwd_txfm_param.rd_transform = 0;
4665 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004666
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004667 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
4668 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
4669 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004670 av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
4671 &p->eobs[k], pd->dequant, 0, TX_4X4, tx_type,
4672 &rate_pvq, x->pvq_speed, NULL);
4673#endif
4674
Yaowu Xuc27fc142016-08-22 16:08:15 -07004675 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4676 &dist, &ssz);
4677 thisdistortion += dist;
4678 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004679#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004680 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004681 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004682 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004683#else
4684 thisrate += rate_pvq;
4685#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004686 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4687 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004688#if CONFIG_EXT_TX
4689 if (tx_size == TX_8X4) {
4690 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4691 }
4692 if (tx_size == TX_4X8) {
4693 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4694 }
4695#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004696 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4697 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004698 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004699 if (rd >= best_yrd) return INT64_MAX;
4700 }
4701 }
4702
4703 *distortion = thisdistortion;
4704 *labelyrate = thisrate;
4705 *sse = thissse;
4706
4707 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4708}
4709
4710typedef struct {
4711 int eobs;
4712 int brate;
4713 int byrate;
4714 int64_t bdist;
4715 int64_t bsse;
4716 int64_t brdcost;
4717 int_mv mvs[2];
4718#if CONFIG_REF_MV
4719 int_mv pred_mv[2];
4720#endif
4721#if CONFIG_EXT_INTER
4722 int_mv ref_mv[2];
4723#endif // CONFIG_EXT_INTER
4724 ENTROPY_CONTEXT ta[2];
4725 ENTROPY_CONTEXT tl[2];
4726} SEG_RDSTAT;
4727
4728typedef struct {
4729 int_mv *ref_mv[2];
4730 int_mv mvp;
4731
4732 int64_t segment_rd;
4733 int r;
4734 int64_t d;
4735 int64_t sse;
4736 int segment_yrate;
4737 PREDICTION_MODE modes[4];
4738#if CONFIG_EXT_INTER
4739 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4740#else
4741 SEG_RDSTAT rdstat[4][INTER_MODES];
4742#endif // CONFIG_EXT_INTER
4743 int mvthresh;
4744} BEST_SEG_INFO;
4745
4746static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4747 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4748 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4749}
4750
4751static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4752 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4753 struct macroblock_plane *const p = &x->plane[0];
4754 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4755
4756 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004757 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004758 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4759 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004760 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004761 if (has_second_ref(mbmi))
4762 pd->pre[1].buf =
4763 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004764 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004765}
4766
4767static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4768 struct buf_2d orig_pre[2]) {
4769 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4770 x->plane[0].src = orig_src;
4771 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4772 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4773}
4774
4775// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4776// TODO(aconverse): Find out if this is still productive then clean up or remove
4777static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004778 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004779#if CONFIG_REF_MV && CONFIG_EXT_INTER
4780 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4781#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4782 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4783 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4784
4785#if !CONFIG_EXT_INTER
4786 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4787#endif
4788
4789 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4790 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4791 (ref_frames[1] <= INTRA_FRAME ||
4792 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4793#if CONFIG_REF_MV
4794 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004795 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004796#else
4797 int16_t rfc = mode_context[ref_frames[0]];
4798#endif
4799#if CONFIG_REF_MV && CONFIG_EXT_INTER
4800 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4801 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4802 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4803#else
4804 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4805 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4806 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4807#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4808
4809#if !CONFIG_REF_MV
4810 (void)bsize;
4811 (void)block;
4812#endif
4813
4814 if (this_mode == NEARMV) {
4815 if (c1 > c3) return 0;
4816 } else if (this_mode == NEARESTMV) {
4817 if (c2 > c3) return 0;
4818 } else {
4819 assert(this_mode == ZEROMV);
4820 if (ref_frames[1] <= INTRA_FRAME) {
4821 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4822 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4823 return 0;
4824 } else {
4825 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4826 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4827 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4828 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4829 return 0;
4830 }
4831 }
4832 }
4833#if CONFIG_EXT_INTER
4834 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4835 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4836 this_mode == ZERO_ZEROMV) &&
4837 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4838 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4839#if CONFIG_REF_MV
4840 int16_t rfc = compound_mode_context[ref_frames[0]];
4841 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4842 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4843 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4844 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4845 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4846#else
4847 int16_t rfc = mode_context[ref_frames[0]];
4848 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4849 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4850 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4851 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4852 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4853#endif
4854
4855 if (this_mode == NEAREST_NEARMV) {
4856 if (c1 > c3) return 0;
4857 } else if (this_mode == NEAREST_NEARESTMV) {
4858 if (c2 > c3) return 0;
4859 } else if (this_mode == NEAR_NEARESTMV) {
4860 if (c4 > c3) return 0;
4861 } else if (this_mode == NEAR_NEARMV) {
4862 if (c5 > c3) return 0;
4863 } else {
4864 assert(this_mode == ZERO_ZEROMV);
4865 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4866 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4867 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4868 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4869 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4870 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4871 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4872 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4873 return 0;
4874 }
4875 }
4876#endif // CONFIG_EXT_INTER
4877 return 1;
4878}
4879
Urvang Joshi52648442016-10-13 17:27:51 -07004880static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4881 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4882 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004883#if CONFIG_EXT_INTER
4884 int_mv *ref_mv_sub8x8[2],
4885#endif
4886 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4887 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004888 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004889 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4890 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4891 MACROBLOCKD *xd = &x->e_mbd;
4892 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4893 const int refs[2] = { mbmi->ref_frame[0],
4894 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4895 int_mv ref_mv[2];
4896 int ite, ref;
4897#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004898 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004899 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4900 mbmi->interp_filter[3],
4901 };
4902#else
James Zern7b9407a2016-05-18 23:48:05 -07004903 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004904#endif
4905 struct scale_factors sf;
4906
4907 // Do joint motion search in compound mode to get more accurate mv.
4908 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4909 int last_besterr[2] = { INT_MAX, INT_MAX };
4910 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004911 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4912 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004913 };
4914
4915// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004916#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004917 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4918 uint8_t *second_pred;
4919#else
4920 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004921#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004922
4923 for (ref = 0; ref < 2; ++ref) {
4924#if CONFIG_EXT_INTER
4925 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4926 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4927 else
4928#endif // CONFIG_EXT_INTER
4929 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4930
4931 if (scaled_ref_frame[ref]) {
4932 int i;
4933 // Swap out the reference frame for a version that's been scaled to
4934 // match the resolution of the current frame, allowing the existing
4935 // motion search code to be used without additional modifications.
4936 for (i = 0; i < MAX_MB_PLANE; i++)
4937 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004938 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4939 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004940 }
4941
4942 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4943 }
4944
4945// Since we have scaled the reference frames to match the size of the current
4946// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004947#if CONFIG_AOM_HIGHBITDEPTH
4948 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4949 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004950#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004951 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4952 cm->height);
4953#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004954
4955 // Allow joint search multiple times iteratively for each reference frame
4956 // and break out of the search loop if it couldn't find a better mv.
4957 for (ite = 0; ite < 4; ite++) {
4958 struct buf_2d ref_yv12[2];
4959 int bestsme = INT_MAX;
4960 int sadpb = x->sadperbit16;
4961 MV *const best_mv = &x->best_mv.as_mv;
4962 int search_range = 3;
4963
4964 int tmp_col_min = x->mv_col_min;
4965 int tmp_col_max = x->mv_col_max;
4966 int tmp_row_min = x->mv_row_min;
4967 int tmp_row_max = x->mv_row_max;
4968 int id = ite % 2; // Even iterations search in the first reference frame,
4969 // odd iterations search in the second. The predictor
4970 // found for the 'other' reference frame is factored in.
4971
4972 // Initialized here because of compiler problem in Visual Studio.
4973 ref_yv12[0] = xd->plane[0].pre[0];
4974 ref_yv12[1] = xd->plane[0].pre[1];
4975
4976#if CONFIG_DUAL_FILTER
4977 // reload the filter types
4978 interp_filter[0] =
4979 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4980 interp_filter[1] =
4981 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4982#endif
4983
4984// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004985#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004986 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4987 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004988 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004989 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4990 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4991 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4992 } else {
4993 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004994 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4995 second_pred, pw, &frame_mv[refs[!id]].as_mv,
4996 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4997 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004998 }
4999#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005000 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
5001 second_pred, pw, &frame_mv[refs[!id]].as_mv, &sf,
5002 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
5003 mi_col * MI_SIZE, mi_row * MI_SIZE);
5004#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005005
5006 // Do compound motion search on the current reference frame.
5007 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005008 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005009
5010 // Use the mv result from the single mode as mv predictor.
5011 *best_mv = frame_mv[refs[id]].as_mv;
5012
5013 best_mv->col >>= 3;
5014 best_mv->row >>= 3;
5015
5016#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005017 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005018#endif
5019
5020 // Small-range full-pixel motion search.
5021 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005022 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5023 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005024 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005025 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5026 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005027
5028 x->mv_col_min = tmp_col_min;
5029 x->mv_col_max = tmp_col_max;
5030 x->mv_row_min = tmp_row_min;
5031 x->mv_row_max = tmp_row_max;
5032
5033 if (bestsme < INT_MAX) {
5034 int dis; /* TODO: use dis in distortion calculation later. */
5035 unsigned int sse;
5036 if (cpi->sf.use_upsampled_references) {
5037 // Use up-sampled reference frames.
5038 struct macroblockd_plane *const pd = &xd->plane[0];
5039 struct buf_2d backup_pred = pd->pre[0];
5040 const YV12_BUFFER_CONFIG *upsampled_ref =
5041 get_upsampled_ref(cpi, refs[id]);
5042
5043 // Set pred for Y plane
5044 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5045 upsampled_ref->y_crop_width,
5046 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5047 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5048 pd->subsampling_y);
5049
5050 // If bsize < BLOCK_8X8, adjust pred pointer for this block
5051 if (bsize < BLOCK_8X8)
5052 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005053 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5054 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005055 << 3];
5056
5057 bestsme = cpi->find_fractional_mv_step(
5058 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5059 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5060 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5061 &dis, &sse, second_pred, pw, ph, 1);
5062
5063 // Restore the reference frames.
5064 pd->pre[0] = backup_pred;
5065 } else {
5066 (void)block;
5067 bestsme = cpi->find_fractional_mv_step(
5068 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5069 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5070 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5071 &dis, &sse, second_pred, pw, ph, 0);
5072 }
5073 }
5074
5075 // Restore the pointer to the first (possibly scaled) prediction buffer.
5076 if (id) xd->plane[0].pre[0] = ref_yv12[0];
5077
5078 if (bestsme < last_besterr[id]) {
5079 frame_mv[refs[id]].as_mv = *best_mv;
5080 last_besterr[id] = bestsme;
5081 } else {
5082 break;
5083 }
5084 }
5085
5086 *rate_mv = 0;
5087
5088 for (ref = 0; ref < 2; ++ref) {
5089 if (scaled_ref_frame[ref]) {
5090 // Restore the prediction frame pointers to their unscaled versions.
5091 int i;
5092 for (i = 0; i < MAX_MB_PLANE; i++)
5093 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5094 }
5095#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005096 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005097#endif
5098#if CONFIG_EXT_INTER
5099 if (bsize >= BLOCK_8X8)
5100#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005101 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5102 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5103 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005104#if CONFIG_EXT_INTER
5105 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005106 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5107 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5108 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005109#endif // CONFIG_EXT_INTER
5110 }
5111}
5112
5113static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005114 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005115 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5116 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5117 int mvthresh,
5118#if CONFIG_EXT_INTER
5119 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5120 int_mv compound_seg_newmvs[4][2],
5121#else
5122 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5123#endif // CONFIG_EXT_INTER
5124 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5125 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5126#if CONFIG_REF_MV
5127 int_mv tmp_ref_mv[2];
5128#endif
5129 MACROBLOCKD *xd = &x->e_mbd;
5130 MODE_INFO *mi = xd->mi[0];
5131 MB_MODE_INFO *mbmi = &mi->mbmi;
5132 int mode_idx;
5133 int k, br = 0, idx, idy;
5134 int64_t bd = 0, block_sse = 0;
5135 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005136 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137 struct macroblock_plane *const p = &x->plane[0];
5138 struct macroblockd_plane *const pd = &xd->plane[0];
5139 const int label_count = 4;
5140 int64_t this_segment_rd = 0;
5141 int label_mv_thresh;
5142 int segmentyrate = 0;
5143 const BLOCK_SIZE bsize = mbmi->sb_type;
5144 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5145 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
5146 ENTROPY_CONTEXT t_above[2], t_left[2];
5147 int subpelmv = 1, have_ref = 0;
5148 const int has_second_rf = has_second_ref(mbmi);
5149 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5150 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005151#if CONFIG_PVQ
5152 od_rollback_buffer pre_buf;
5153
5154 od_encode_checkpoint(&x->daala_enc, &pre_buf);
5155#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005156#if CONFIG_EXT_TX && CONFIG_RECT_TX
5157 mbmi->tx_size =
5158 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5159#else
5160 mbmi->tx_size = TX_4X4;
5161#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5162
Yaowu Xuf883b422016-08-30 14:01:10 -07005163 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005164
5165 bsi->segment_rd = best_rd;
5166 bsi->ref_mv[0] = best_ref_mv;
5167 bsi->ref_mv[1] = second_best_ref_mv;
5168 bsi->mvp.as_int = best_ref_mv->as_int;
5169 bsi->mvthresh = mvthresh;
5170
5171 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5172
5173#if CONFIG_REFMV
5174 for (idx = 0; idx < 4; ++idx) {
5175 for (k = NEARESTMV; k <= NEWMV; ++k) {
5176 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5177 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5178
5179 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5180 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5181 }
5182 }
5183#endif
5184
5185 memcpy(t_above, pd->above_context, sizeof(t_above));
5186 memcpy(t_left, pd->left_context, sizeof(t_left));
5187
5188 // 64 makes this threshold really big effectively
5189 // making it so that we very rarely check mvs on
5190 // segments. setting this to 1 would make mv thresh
5191 // roughly equal to what it is for macroblocks
5192 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5193
5194 // Segmentation method overheads
5195 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5196 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5197 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5198 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5199 int_mv mode_mv[MB_MODE_COUNT][2];
5200 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5201 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005202 int64_t new_best_rd = INT64_MAX;
5203 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005204 int ref;
5205#if CONFIG_REF_MV
5206 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5207 uint8_t ref_mv_count[2];
5208#endif
5209#if CONFIG_EXT_INTER
5210 int mv_idx;
5211 int_mv ref_mvs_sub8x8[2][2];
5212#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005213#if CONFIG_PVQ
5214 od_rollback_buffer idx_buf, post_buf;
5215 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5216 od_encode_checkpoint(&x->daala_enc, &post_buf);
5217#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005218
5219 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5220 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5221#if CONFIG_EXT_INTER
5222 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07005223 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005224 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005225#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005226#if CONFIG_GLOBAL_MOTION
5227 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005228 gm_get_motion_vector(&cm->global_motion[frame]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005229#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005230 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005231#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005232 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005233#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005234 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005235#endif
5236#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005237 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005238#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005239 &frame_mv[NEARESTMV][frame],
5240 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005241
5242#if CONFIG_REF_MV
5243 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5244 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5245 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5246 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5247#endif
5248
5249#if CONFIG_EXT_INTER
5250 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5251 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005252 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5253 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005254
5255 if (has_second_rf) {
5256 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
5257 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5258 frame_mv[NEARESTMV][frame].as_int;
5259
5260 if (ref == 0) {
5261 frame_mv[NEAREST_NEARMV][frame].as_int =
5262 frame_mv[NEARESTMV][frame].as_int;
5263 frame_mv[NEAR_NEARESTMV][frame].as_int =
5264 frame_mv[NEARMV][frame].as_int;
5265 frame_mv[NEAREST_NEWMV][frame].as_int =
5266 frame_mv[NEARESTMV][frame].as_int;
5267 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5268 frame_mv[NEAR_NEARMV][frame].as_int =
5269 frame_mv[NEARMV][frame].as_int;
5270 } else if (ref == 1) {
5271 frame_mv[NEAREST_NEARMV][frame].as_int =
5272 frame_mv[NEARMV][frame].as_int;
5273 frame_mv[NEAR_NEARESTMV][frame].as_int =
5274 frame_mv[NEARESTMV][frame].as_int;
5275 frame_mv[NEW_NEARESTMV][frame].as_int =
5276 frame_mv[NEARESTMV][frame].as_int;
5277 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5278 frame_mv[NEAR_NEARMV][frame].as_int =
5279 frame_mv[NEARMV][frame].as_int;
5280 }
5281 }
5282#endif // CONFIG_EXT_INTER
5283 }
5284
5285// search for the best motion vector on this segment
5286#if CONFIG_EXT_INTER
5287 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5288 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5289 ++this_mode)
5290#else
5291 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5292#endif // CONFIG_EXT_INTER
5293 {
5294 const struct buf_2d orig_src = x->plane[0].src;
5295 struct buf_2d orig_pre[2];
5296 // This flag controls if the motion estimation will kick off. When it
5297 // is set to a non-zero value, the encoder will force motion estimation.
5298 int run_mv_search = 0;
5299
5300 mode_idx = INTER_OFFSET(this_mode);
5301#if CONFIG_EXT_INTER
5302 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5303
5304 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5305 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5306#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005307 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 if (!(inter_mode_mask & (1 << this_mode))) continue;
5309
5310#if CONFIG_REF_MV
5311 run_mv_search = 2;
5312#if !CONFIG_EXT_INTER
5313 if (filter_idx > 0 && this_mode == NEWMV) {
5314 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005315 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005316
5317 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005318 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005319 ref_rdstat->mvs[0].as_int &&
5320 ref_rdstat->mvs[0].as_int != INVALID_MV)
5321 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5322 --run_mv_search;
5323
Urvang Joshi454280d2016-10-14 16:51:44 -07005324 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005325 ref_rdstat->mvs[1].as_int &&
5326 ref_rdstat->mvs[1].as_int != INVALID_MV)
5327 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5328 --run_mv_search;
5329 } else {
5330 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5331 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5332 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005333 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5334 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335 }
5336 }
5337
5338 if (run_mv_search != 0 && filter_idx > 1) {
5339 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005340 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005341 run_mv_search = 2;
5342
5343 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005344 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005345 ref_rdstat->mvs[0].as_int &&
5346 ref_rdstat->mvs[0].as_int != INVALID_MV)
5347 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5348 --run_mv_search;
5349
Urvang Joshi454280d2016-10-14 16:51:44 -07005350 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005351 ref_rdstat->mvs[1].as_int &&
5352 ref_rdstat->mvs[1].as_int != INVALID_MV)
5353 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5354 --run_mv_search;
5355 } else {
5356 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5357 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5358 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005359 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005360 ref_rdstat->mvs[0].as_int;
5361 }
5362 }
5363 }
5364 }
5365#endif // CONFIG_EXT_INTER
5366#endif // CONFIG_REF_MV
5367
Sarah Parkere5299862016-08-16 14:57:37 -07005368#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005369 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005370 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005371 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005372#endif // CONFIG_GLOBAL_MOTION
5373
5374 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005375#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005376 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005377#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005378 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005379 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005380 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005381
5382 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005383 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5384 sizeof(bsi->rdstat[index][mode_idx].ta));
5385 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5386 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005387#if CONFIG_PVQ
5388 od_encode_rollback(&x->daala_enc, &idx_buf);
5389#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005390
5391 // motion search for newmv (single predictor case only)
5392 if (!has_second_rf &&
5393#if CONFIG_EXT_INTER
5394 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07005395 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005396#else
5397 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005398 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399 run_mv_search)
5400#endif // CONFIG_EXT_INTER
5401 ) {
5402 int step_param = 0;
5403 int bestsme = INT_MAX;
5404 int sadpb = x->sadperbit4;
5405 MV mvp_full;
5406 int max_mv;
5407 int cost_list[5];
5408 int tmp_col_min = x->mv_col_min;
5409 int tmp_col_max = x->mv_col_max;
5410 int tmp_row_min = x->mv_row_min;
5411 int tmp_row_max = x->mv_row_max;
5412
5413 /* Is the best so far sufficiently good that we cant justify doing
5414 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005415 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005416
5417 if (cpi->oxcf.mode != BEST) {
5418#if CONFIG_EXT_INTER
5419 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5420#else
5421// use previous block's result as next block's MV predictor.
5422#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005423 if (index > 0) {
5424 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5425 if (index == 2)
5426 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005427 }
5428#endif
5429#endif // CONFIG_EXT_INTER
5430 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005431 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5432 : AOMMAX(abs(bsi->mvp.as_mv.row),
5433 abs(bsi->mvp.as_mv.col)) >>
5434 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005435
5436 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5437 // Take wtd average of the step_params based on the last frame's
5438 // max mv magnitude and the best ref mvs of the current block for
5439 // the given reference.
5440 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005441 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442 } else {
5443 step_param = cpi->mv_step_param;
5444 }
5445
5446#if CONFIG_REF_MV
5447 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5448 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5449#else
5450 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5451 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5452#endif
5453
5454 if (cpi->sf.adaptive_motion_search) {
5455 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5456 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005457 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458 }
5459
5460 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005461 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005462
Yaowu Xuf883b422016-08-30 14:01:10 -07005463 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005464
5465 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5466
5467#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005468 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005469#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005470 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 cpi, x, bsize, &mvp_full, step_param, sadpb,
5472 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5473 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5474
5475 x->mv_col_min = tmp_col_min;
5476 x->mv_col_max = tmp_col_max;
5477 x->mv_row_min = tmp_row_min;
5478 x->mv_row_max = tmp_row_max;
5479
5480 if (bestsme < INT_MAX) {
5481 int distortion;
5482 if (cpi->sf.use_upsampled_references) {
5483 int best_mv_var;
5484 const int try_second =
5485 x->second_best_mv.as_int != INVALID_MV &&
5486 x->second_best_mv.as_int != x->best_mv.as_int;
5487 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5488 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5489 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005490 struct buf_2d backup_pred = pd->pre[0];
5491 const YV12_BUFFER_CONFIG *upsampled_ref =
5492 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5493
5494 // Set pred for Y plane
5495 setup_pred_plane(
5496 &pd->pre[0], upsampled_ref->y_buffer,
5497 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5498 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5499 pd->subsampling_x, pd->subsampling_y);
5500
5501 // adjust pred pointer for this block
5502 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005503 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005504 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005505 << 3];
5506
5507 best_mv_var = cpi->find_fractional_mv_step(
5508 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5509 x->errorperbit, &cpi->fn_ptr[bsize],
5510 cpi->sf.mv.subpel_force_stop,
5511 cpi->sf.mv.subpel_iters_per_step,
5512 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5513 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5514 1);
5515
5516 if (try_second) {
5517 int this_var;
5518 MV best_mv = x->best_mv.as_mv;
5519 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005520 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5521 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5522 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5523 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005524
5525 x->best_mv = x->second_best_mv;
5526 if (x->best_mv.as_mv.row * 8 <= maxr &&
5527 x->best_mv.as_mv.row * 8 >= minr &&
5528 x->best_mv.as_mv.col * 8 <= maxc &&
5529 x->best_mv.as_mv.col * 8 >= minc) {
5530 this_var = cpi->find_fractional_mv_step(
5531 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5532 x->errorperbit, &cpi->fn_ptr[bsize],
5533 cpi->sf.mv.subpel_force_stop,
5534 cpi->sf.mv.subpel_iters_per_step,
5535 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5536 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5537 NULL, pw, ph, 1);
5538 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5539 x->best_mv.as_mv = best_mv;
5540 }
5541 }
5542
5543 // Restore the reference frames.
5544 pd->pre[0] = backup_pred;
5545 } else {
5546 cpi->find_fractional_mv_step(
5547 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5548 x->errorperbit, &cpi->fn_ptr[bsize],
5549 cpi->sf.mv.subpel_force_stop,
5550 cpi->sf.mv.subpel_iters_per_step,
5551 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5552 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5553 }
5554
5555// save motion search result for use in compound prediction
5556#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005557 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005558#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005559 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005560#endif // CONFIG_EXT_INTER
5561 }
5562
5563 if (cpi->sf.adaptive_motion_search)
5564 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5565
5566#if CONFIG_EXT_INTER
5567 mode_mv[this_mode][0] = x->best_mv;
5568#else
5569 mode_mv[NEWMV][0] = x->best_mv;
5570#endif // CONFIG_EXT_INTER
5571
5572 // restore src pointers
5573 mi_buf_restore(x, orig_src, orig_pre);
5574 }
5575
5576 if (has_second_rf) {
5577#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005578 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5579 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005580#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005581 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5582 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583#endif // CONFIG_EXT_INTER
5584 continue;
5585 }
5586
5587#if CONFIG_DUAL_FILTER
5588 (void)run_mv_search;
5589#endif
5590
5591 if (has_second_rf &&
5592#if CONFIG_EXT_INTER
5593 this_mode == NEW_NEWMV &&
5594#else
5595 this_mode == NEWMV &&
5596#endif // CONFIG_EXT_INTER
5597#if CONFIG_DUAL_FILTER
5598 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5599#else
5600 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5601#endif
5602 {
5603 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005604 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5606 int rate_mv;
5607 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5608 mi_col,
5609#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005610 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005612 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005614 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005615#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005616 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005618 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005619 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5620#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005621 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005622 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005623 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5625#endif // CONFIG_EXT_INTER
5626 }
5627 // restore src pointers
5628 mi_buf_restore(x, orig_src, orig_pre);
5629 }
5630
Urvang Joshi454280d2016-10-14 16:51:44 -07005631 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5632 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005633#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005634 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005636 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637#endif // CONFIG_EXT_INTER
5638 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5639
5640 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005641 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005642 mode_mv[this_mode][ref].as_int;
5643 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005644 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005645 mode_mv[this_mode][ref].as_int;
5646 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005647 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005648 mode_mv[this_mode][ref].as_int;
5649#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005650 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5651 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005652 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005653 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5654 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005656 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5657 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658#endif
5659#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005660 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661 bsi->ref_mv[ref]->as_int;
5662 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005663 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664 bsi->ref_mv[ref]->as_int;
5665 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005666 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005667 bsi->ref_mv[ref]->as_int;
5668#endif // CONFIG_EXT_INTER
5669 }
5670
5671 // Trap vectors that reach beyond the UMV borders
5672 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5673 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5674 continue;
5675
5676 if (filter_idx > 0) {
5677 BEST_SEG_INFO *ref_bsi = bsi_buf;
5678 subpelmv = 0;
5679 have_ref = 1;
5680
5681 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5682 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5683#if CONFIG_EXT_INTER
5684 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005685 have_ref &=
5686 ((mode_mv[this_mode][ref].as_int ==
5687 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5688 (bsi->ref_mv[ref]->as_int ==
5689 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005690 else
5691#endif // CONFIG_EXT_INTER
5692 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005693 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005694 }
5695
Urvang Joshi454280d2016-10-14 16:51:44 -07005696 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005697
5698 if (filter_idx > 1 && !subpelmv && !have_ref) {
5699 ref_bsi = bsi_buf + 1;
5700 have_ref = 1;
5701 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5702#if CONFIG_EXT_INTER
5703 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005704 have_ref &=
5705 ((mode_mv[this_mode][ref].as_int ==
5706 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5707 (bsi->ref_mv[ref]->as_int ==
5708 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005709 else
5710#endif // CONFIG_EXT_INTER
5711 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005712 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713
Urvang Joshi454280d2016-10-14 16:51:44 -07005714 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005715 }
5716
5717 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005718 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005719#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005720 bsi->rdstat[index][mode_idx].byrate =
5721 ref_bsi->rdstat[index][mode_idx].byrate;
5722 bsi->rdstat[index][mode_idx].bdist =
5723 ref_bsi->rdstat[index][mode_idx].bdist;
5724 bsi->rdstat[index][mode_idx].bsse =
5725 ref_bsi->rdstat[index][mode_idx].bsse;
5726 bsi->rdstat[index][mode_idx].brate +=
5727 ref_bsi->rdstat[index][mode_idx].byrate;
5728 bsi->rdstat[index][mode_idx].eobs =
5729 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005730
Urvang Joshi454280d2016-10-14 16:51:44 -07005731 bsi->rdstat[index][mode_idx].brdcost =
5732 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5733 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734
Urvang Joshi454280d2016-10-14 16:51:44 -07005735 memcpy(bsi->rdstat[index][mode_idx].ta,
5736 ref_bsi->rdstat[index][mode_idx].ta,
5737 sizeof(bsi->rdstat[index][mode_idx].ta));
5738 memcpy(bsi->rdstat[index][mode_idx].tl,
5739 ref_bsi->rdstat[index][mode_idx].tl,
5740 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005741#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005742 memcpy(&bsi->rdstat[index][mode_idx],
5743 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005744#endif
5745 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005746 bsi->rdstat[index + 1][mode_idx].eobs =
5747 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005748 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005749 bsi->rdstat[index + 2][mode_idx].eobs =
5750 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005751
Urvang Joshi454280d2016-10-14 16:51:44 -07005752 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005753#if CONFIG_REF_MV
5754 // If the NEWMV mode is using the same motion vector as the
5755 // NEARESTMV mode, skip the rest rate-distortion calculations
5756 // and use the inferred motion vector modes.
5757 if (this_mode == NEWMV) {
5758 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005759 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005760 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005761 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005762 bsi->ref_mv[1]->as_int)
5763 continue;
5764 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005765 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766 bsi->ref_mv[0]->as_int)
5767 continue;
5768 }
5769 }
5770#endif
5771 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005772 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005773#if CONFIG_PVQ
5774 od_encode_checkpoint(&x->daala_enc, &post_buf);
5775#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005776 }
5777 continue;
5778 }
5779 }
5780
Urvang Joshi454280d2016-10-14 16:51:44 -07005781 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5782 cpi, x, bsi->segment_rd - this_segment_rd, index,
5783 &bsi->rdstat[index][mode_idx].byrate,
5784 &bsi->rdstat[index][mode_idx].bdist,
5785 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5786 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005787
Urvang Joshi454280d2016-10-14 16:51:44 -07005788 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5789 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5790 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5791 bsi->rdstat[index][mode_idx].brate +=
5792 bsi->rdstat[index][mode_idx].byrate;
5793 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005794 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005795 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005796 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005797 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005798 }
5799
Urvang Joshi454280d2016-10-14 16:51:44 -07005800 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005801#if CONFIG_REF_MV
5802 // If the NEWMV mode is using the same motion vector as the
5803 // NEARESTMV mode, skip the rest rate-distortion calculations
5804 // and use the inferred motion vector modes.
5805 if (this_mode == NEWMV) {
5806 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005807 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005808 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005809 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005810 bsi->ref_mv[1]->as_int)
5811 continue;
5812 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005813 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005814 bsi->ref_mv[0]->as_int)
5815 continue;
5816 }
5817 }
5818#endif
5819 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005820 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005821
5822#if CONFIG_PVQ
5823 od_encode_checkpoint(&x->daala_enc, &post_buf);
5824#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005825 }
5826 } /*for each 4x4 mode*/
5827
Urvang Joshi454280d2016-10-14 16:51:44 -07005828 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005829 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005830 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005831#if CONFIG_EXT_INTER
5832 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5833#else
5834 for (midx = 0; midx < INTER_MODES; ++midx)
5835#endif // CONFIG_EXT_INTER
5836 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5837 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005838#if CONFIG_PVQ
5839 od_encode_rollback(&x->daala_enc, &pre_buf);
5840#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005841 return INT64_MAX;
5842 }
5843
5844 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005845 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5846 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005847#if CONFIG_PVQ
5848 od_encode_rollback(&x->daala_enc, &post_buf);
5849#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005850
5851#if CONFIG_EXT_INTER
5852 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005853 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005854 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005855 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005856#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005857 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5858 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005859#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005860 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005861#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005862 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863#endif // CONFIG_EXT_INTER
5864 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5865
Urvang Joshi454280d2016-10-14 16:51:44 -07005866 br += bsi->rdstat[index][mode_idx].brate;
5867 bd += bsi->rdstat[index][mode_idx].bdist;
5868 block_sse += bsi->rdstat[index][mode_idx].bsse;
5869 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5870 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005871
5872 if (this_segment_rd > bsi->segment_rd) {
5873 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005874 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005875#if CONFIG_EXT_INTER
5876 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5877#else
5878 for (midx = 0; midx < INTER_MODES; ++midx)
5879#endif // CONFIG_EXT_INTER
5880 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5881 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005882#if CONFIG_PVQ
5883 od_encode_rollback(&x->daala_enc, &pre_buf);
5884#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005885 return INT64_MAX;
5886 }
5887 }
5888 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07005889#if CONFIG_PVQ
5890 od_encode_rollback(&x->daala_enc, &pre_buf);
5891#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005892
5893 bsi->r = br;
5894 bsi->d = bd;
5895 bsi->segment_yrate = segmentyrate;
5896 bsi->segment_rd = this_segment_rd;
5897 bsi->sse = block_sse;
5898
5899 // update the coding decisions
5900 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5901
5902 if (bsi->segment_rd > best_rd) return INT64_MAX;
5903 /* set it to the best */
5904 for (idx = 0; idx < 4; idx++) {
5905 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5906 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5907 if (has_second_ref(mbmi))
5908 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5909#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005910 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005911 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005912 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005913#endif
5914#if CONFIG_EXT_INTER
5915 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5916 if (has_second_rf)
5917 mi->bmi[idx].ref_mv[1].as_int =
5918 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5919#endif // CONFIG_EXT_INTER
5920 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5921 mi->bmi[idx].as_mode = bsi->modes[idx];
5922 }
5923
5924 /*
5925 * used to set mbmi->mv.as_int
5926 */
5927 *returntotrate = bsi->r;
5928 *returndistortion = bsi->d;
5929 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005930 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005931 *psse = bsi->sse;
5932 mbmi->mode = bsi->modes[3];
5933
5934 return bsi->segment_rd;
5935}
5936
Yaowu Xuf883b422016-08-30 14:01:10 -07005937static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005938 const MACROBLOCKD *xd, int segment_id,
5939 unsigned int *ref_costs_single,
5940 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005941 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005942 int seg_ref_active =
5943 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5944 if (seg_ref_active) {
5945 memset(ref_costs_single, 0,
5946 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5947 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5948 *comp_mode_p = 128;
5949 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005950 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5951 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005952
5953 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005954 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005955 *comp_mode_p = comp_inter_p;
5956 } else {
5957 *comp_mode_p = 128;
5958 }
5959
Yaowu Xuf883b422016-08-30 14:01:10 -07005960 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005961
5962 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005963 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5964 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005966 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5967 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5968 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005969#endif // CONFIG_EXT_REFS
5970
Yaowu Xuf883b422016-08-30 14:01:10 -07005971 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005972
5973 ref_costs_single[LAST_FRAME] =
5974#if CONFIG_EXT_REFS
5975 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5976 ref_costs_single[BWDREF_FRAME] =
5977#endif // CONFIG_EXT_REFS
5978 ref_costs_single[GOLDEN_FRAME] =
5979 ref_costs_single[ALTREF_FRAME] = base_cost;
5980
5981#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005982 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5983 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5984 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5985 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5986 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5987 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005988
Yaowu Xuf883b422016-08-30 14:01:10 -07005989 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5990 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5991 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5992 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005993
Yaowu Xuf883b422016-08-30 14:01:10 -07005994 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5995 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005996
Yaowu Xuf883b422016-08-30 14:01:10 -07005997 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5998 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005999
Yaowu Xuf883b422016-08-30 14:01:10 -07006000 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6001 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006002#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006003 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6004 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6005 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006006
Yaowu Xuf883b422016-08-30 14:01:10 -07006007 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6008 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009#endif // CONFIG_EXT_REFS
6010 } else {
6011 ref_costs_single[LAST_FRAME] = 512;
6012#if CONFIG_EXT_REFS
6013 ref_costs_single[LAST2_FRAME] = 512;
6014 ref_costs_single[LAST3_FRAME] = 512;
6015 ref_costs_single[BWDREF_FRAME] = 512;
6016#endif // CONFIG_EXT_REFS
6017 ref_costs_single[GOLDEN_FRAME] = 512;
6018 ref_costs_single[ALTREF_FRAME] = 512;
6019 }
6020
6021 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006022 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006023#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006024 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6025 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6026 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006027#endif // CONFIG_EXT_REFS
6028
Yaowu Xuf883b422016-08-30 14:01:10 -07006029 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006030
6031 ref_costs_comp[LAST_FRAME] =
6032#if CONFIG_EXT_REFS
6033 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6034#endif // CONFIG_EXT_REFS
6035 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6036
6037#if CONFIG_EXT_REFS
6038 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6039#endif // CONFIG_EXT_REFS
6040
6041#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006042 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6043 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6044 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6045 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006046
Yaowu Xuf883b422016-08-30 14:01:10 -07006047 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6048 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049
Yaowu Xuf883b422016-08-30 14:01:10 -07006050 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6051 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006052
6053 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6054 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006055 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6056 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006058 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6059 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060#endif // CONFIG_EXT_REFS
6061 } else {
6062 ref_costs_comp[LAST_FRAME] = 512;
6063#if CONFIG_EXT_REFS
6064 ref_costs_comp[LAST2_FRAME] = 512;
6065 ref_costs_comp[LAST3_FRAME] = 512;
6066 ref_costs_comp[BWDREF_FRAME] = 512;
6067 ref_costs_comp[ALTREF_FRAME] = 512;
6068#endif // CONFIG_EXT_REFS
6069 ref_costs_comp[GOLDEN_FRAME] = 512;
6070 }
6071 }
6072}
6073
6074static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6075 int mode_index,
6076 int64_t comp_pred_diff[REFERENCE_MODES],
6077 int skippable) {
6078 MACROBLOCKD *const xd = &x->e_mbd;
6079
6080 // Take a snapshot of the coding context so it can be
6081 // restored if we decide to encode this way
6082 ctx->skip = x->skip;
6083 ctx->skippable = skippable;
6084 ctx->best_mode_index = mode_index;
6085 ctx->mic = *xd->mi[0];
6086 ctx->mbmi_ext = *x->mbmi_ext;
6087 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6088 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6089 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6090}
6091
Urvang Joshi52648442016-10-13 17:27:51 -07006092static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07006093 MV_REFERENCE_FRAME ref_frame,
6094 BLOCK_SIZE block_size, int mi_row, int mi_col,
6095 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6096 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6097 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
6098 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006099 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006100 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6101 MACROBLOCKD *const xd = &x->e_mbd;
6102 MODE_INFO *const mi = xd->mi[0];
6103 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6104 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6105 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6106
6107 assert(yv12 != NULL);
6108
6109 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6110 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006111 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006112
6113 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006114 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006115 cm, xd, mi, ref_frame,
6116#if CONFIG_REF_MV
6117 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6118#if CONFIG_EXT_INTER
6119 mbmi_ext->compound_mode_context,
6120#endif // CONFIG_EXT_INTER
6121#endif
6122 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6123
6124 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006125 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6126 &frame_nearest_mv[ref_frame],
6127 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006128
6129 // Further refinement that is encode side only to test the top few candidates
6130 // in full and choose the best as the centre point for subsequent searches.
6131 // The current implementation doesn't support scaling.
Yaowu Xuf883b422016-08-30 14:01:10 -07006132 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6133 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6134 block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006135}
6136
Urvang Joshi52648442016-10-13 17:27:51 -07006137static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6138 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006139#if CONFIG_EXT_INTER
6140 int ref_idx, int mv_idx,
6141#endif // CONFIG_EXT_INTER
6142 int *rate_mv) {
6143 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006144 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6146 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6147 int bestsme = INT_MAX;
6148 int step_param;
6149 int sadpb = x->sadperbit16;
6150 MV mvp_full;
6151#if CONFIG_EXT_INTER
6152 int ref = mbmi->ref_frame[ref_idx];
6153 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6154#else
6155 int ref = mbmi->ref_frame[0];
6156 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6157 int ref_idx = 0;
6158#endif // CONFIG_EXT_INTER
6159
6160 int tmp_col_min = x->mv_col_min;
6161 int tmp_col_max = x->mv_col_max;
6162 int tmp_row_min = x->mv_row_min;
6163 int tmp_row_max = x->mv_row_max;
6164 int cost_list[5];
6165
6166 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006167 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168
6169 MV pred_mv[3];
6170 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6171 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6172 pred_mv[2] = x->pred_mv[ref];
6173
Yaowu Xuc27fc142016-08-22 16:08:15 -07006174 if (scaled_ref_frame) {
6175 int i;
6176 // Swap out the reference frame for a version that's been scaled to
6177 // match the resolution of the current frame, allowing the existing
6178 // motion search code to be used without additional modifications.
6179 for (i = 0; i < MAX_MB_PLANE; i++)
6180 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6181
Yaowu Xuf883b422016-08-30 14:01:10 -07006182 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006183 }
6184
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006185 av1_set_mv_search_range(x, &ref_mv);
6186
6187#if CONFIG_REF_MV
6188 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6189#endif
6190
Yaowu Xuc27fc142016-08-22 16:08:15 -07006191 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006192 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6194 // Take wtd average of the step_params based on the last frame's
6195 // max mv magnitude and that based on the best ref mvs of the current
6196 // block for the given reference.
6197 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006198 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006199 2;
6200 } else {
6201 step_param = cpi->mv_step_param;
6202 }
6203
6204 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6205 int boffset =
6206 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006207 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6208 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209 }
6210
6211 if (cpi->sf.adaptive_motion_search) {
6212 int bwl = b_width_log2_lookup[bsize];
6213 int bhl = b_height_log2_lookup[bsize];
6214 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6215
6216 if (tlevel < 5) step_param += 2;
6217
6218 // prev_mv_sad is not setup for dynamically scaled frames.
6219 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6220 int i;
6221 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6222 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6223 x->pred_mv[ref].row = 0;
6224 x->pred_mv[ref].col = 0;
6225 x->best_mv.as_int = INVALID_MV;
6226
6227 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006228 int j;
6229 for (j = 0; j < MAX_MB_PLANE; ++j)
6230 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006231 }
6232 return;
6233 }
6234 }
6235 }
6236 }
6237
Yaowu Xuf883b422016-08-30 14:01:10 -07006238 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006239
Yue Chene9638cc2016-10-10 12:37:54 -07006240#if CONFIG_MOTION_VAR
6241 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6242 mvp_full = mbmi->mv[0].as_mv;
6243 else
6244#endif // CONFIG_MOTION_VAR
6245 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006246
6247 mvp_full.col >>= 3;
6248 mvp_full.row >>= 3;
6249
6250 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6251
Yue Chene9638cc2016-10-10 12:37:54 -07006252#if CONFIG_MOTION_VAR
6253 switch (mbmi->motion_mode) {
6254 case SIMPLE_TRANSLATION:
6255#endif // CONFIG_MOTION_VAR
6256 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6257 sadpb, cond_cost_list(cpi, cost_list),
6258 &ref_mv, INT_MAX, 1);
6259#if CONFIG_MOTION_VAR
6260 break;
6261 case OBMC_CAUSAL:
6262 bestsme = av1_obmc_full_pixel_diamond(
6263 cpi, x, &mvp_full, step_param, sadpb,
6264 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6265 &(x->best_mv.as_mv), 0);
6266 break;
6267 default: assert("Invalid motion mode!\n");
6268 }
6269#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006270
6271 x->mv_col_min = tmp_col_min;
6272 x->mv_col_max = tmp_col_max;
6273 x->mv_row_min = tmp_row_min;
6274 x->mv_row_max = tmp_row_max;
6275
6276 if (bestsme < INT_MAX) {
6277 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006278#if CONFIG_MOTION_VAR
6279 switch (mbmi->motion_mode) {
6280 case SIMPLE_TRANSLATION:
6281#endif // CONFIG_MOTION_VAR
6282 if (cpi->sf.use_upsampled_references) {
6283 int best_mv_var;
6284 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6285 x->second_best_mv.as_int != x->best_mv.as_int;
6286 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
6287 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
6288 // Use up-sampled reference frames.
6289 struct macroblockd_plane *const pd = &xd->plane[0];
6290 struct buf_2d backup_pred = pd->pre[ref_idx];
6291 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006292
Yue Chene9638cc2016-10-10 12:37:54 -07006293 // Set pred for Y plane
6294 setup_pred_plane(
6295 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6296 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6297 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6298 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006299
Yue Chene9638cc2016-10-10 12:37:54 -07006300 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006301 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6302 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6303 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6304 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6305 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006306
Yue Chene9638cc2016-10-10 12:37:54 -07006307 if (try_second) {
6308 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6309 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6310 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6311 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6312 int this_var;
6313 MV best_mv = x->best_mv.as_mv;
6314
6315 x->best_mv = x->second_best_mv;
6316 if (x->best_mv.as_mv.row * 8 <= maxr &&
6317 x->best_mv.as_mv.row * 8 >= minr &&
6318 x->best_mv.as_mv.col * 8 <= maxc &&
6319 x->best_mv.as_mv.col * 8 >= minc) {
6320 this_var = cpi->find_fractional_mv_step(
6321 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6322 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6323 cpi->sf.mv.subpel_iters_per_step,
6324 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6325 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6326 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6327 x->best_mv.as_mv = best_mv;
6328 }
6329 }
6330
6331 // Restore the reference frames.
6332 pd->pre[ref_idx] = backup_pred;
6333 } else {
6334 cpi->find_fractional_mv_step(
6335 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6336 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6337 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6338 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6339 0);
6340 }
6341#if CONFIG_MOTION_VAR
6342 break;
6343 case OBMC_CAUSAL:
6344 av1_find_best_obmc_sub_pixel_tree_up(
6345 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6346 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6347 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6348 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6349 cpi->sf.use_upsampled_references);
6350 break;
6351 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006352 }
Yue Chene9638cc2016-10-10 12:37:54 -07006353#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006355 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6356 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006357
Yue Chene9638cc2016-10-10 12:37:54 -07006358#if CONFIG_MOTION_VAR
6359 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6360#else
6361 if (cpi->sf.adaptive_motion_search)
6362#endif // CONFIG_MOTION_VAR
6363 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364
6365 if (scaled_ref_frame) {
6366 int i;
6367 for (i = 0; i < MAX_MB_PLANE; i++)
6368 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6369 }
6370}
6371
6372static INLINE void restore_dst_buf(MACROBLOCKD *xd,
6373 uint8_t *orig_dst[MAX_MB_PLANE],
6374 int orig_dst_stride[MAX_MB_PLANE]) {
6375 int i;
6376 for (i = 0; i < MAX_MB_PLANE; i++) {
6377 xd->plane[i].dst.buf = orig_dst[i];
6378 xd->plane[i].dst.stride = orig_dst_stride[i];
6379 }
6380}
6381
Yaowu Xuc27fc142016-08-22 16:08:15 -07006382#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006383static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006384 const uint8_t *mask, int mask_stride,
6385 BLOCK_SIZE bsize, int mi_row, int mi_col,
6386 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6387 int mv_idx) {
6388 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006389 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6391 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6392 int bestsme = INT_MAX;
6393 int step_param;
6394 int sadpb = x->sadperbit16;
6395 MV mvp_full;
6396 int ref = mbmi->ref_frame[ref_idx];
6397 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6398
6399 int tmp_col_min = x->mv_col_min;
6400 int tmp_col_max = x->mv_col_max;
6401 int tmp_row_min = x->mv_row_min;
6402 int tmp_row_max = x->mv_row_max;
6403
6404 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006405 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006406 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006407
6408 MV pred_mv[3];
6409 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6410 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6411 pred_mv[2] = x->pred_mv[ref];
6412
6413#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006414 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006415#endif
6416
6417 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006418 // Swap out the reference frame for a version that's been scaled to
6419 // match the resolution of the current frame, allowing the existing
6420 // motion search code to be used without additional modifications.
6421 for (i = 0; i < MAX_MB_PLANE; i++)
6422 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6423
Yaowu Xuf883b422016-08-30 14:01:10 -07006424 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006425 }
6426
Yaowu Xuf883b422016-08-30 14:01:10 -07006427 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006428
6429 // Work out the size of the first step in the mv step search.
6430 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6431 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6432 // Take wtd average of the step_params based on the last frame's
6433 // max mv magnitude and that based on the best ref mvs of the current
6434 // block for the given reference.
6435 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006436 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006437 2;
6438 } else {
6439 step_param = cpi->mv_step_param;
6440 }
6441
6442 // TODO(debargha): is show_frame needed here?
6443 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6444 int boffset =
6445 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006446 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6447 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006448 }
6449
6450 if (cpi->sf.adaptive_motion_search) {
6451 int bwl = b_width_log2_lookup[bsize];
6452 int bhl = b_height_log2_lookup[bsize];
6453 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6454
6455 if (tlevel < 5) step_param += 2;
6456
6457 // prev_mv_sad is not setup for dynamically scaled frames.
6458 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006459 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6460 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6461 x->pred_mv[ref].row = 0;
6462 x->pred_mv[ref].col = 0;
6463 tmp_mv->as_int = INVALID_MV;
6464
6465 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006466 int j;
6467 for (j = 0; j < MAX_MB_PLANE; ++j)
6468 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006469 }
6470 return;
6471 }
6472 }
6473 }
6474 }
6475
6476 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6477
6478 mvp_full.col >>= 3;
6479 mvp_full.row >>= 3;
6480
Yaowu Xuf883b422016-08-30 14:01:10 -07006481 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006482 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6483 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6484 &tmp_mv->as_mv, ref_idx);
6485
6486 x->mv_col_min = tmp_col_min;
6487 x->mv_col_max = tmp_col_max;
6488 x->mv_row_min = tmp_row_min;
6489 x->mv_row_max = tmp_row_max;
6490
6491 if (bestsme < INT_MAX) {
6492 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006493 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006494 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6495 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6496 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6497 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6498 cpi->sf.use_upsampled_references);
6499 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006500 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6501 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006502
6503 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6504 x->pred_mv[ref] = tmp_mv->as_mv;
6505
6506 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006507 for (i = 0; i < MAX_MB_PLANE; i++)
6508 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6509 }
6510}
6511
Urvang Joshi52648442016-10-13 17:27:51 -07006512static void do_masked_motion_search_indexed(const AV1_COMP *const cpi,
6513 MACROBLOCK *x, int wedge_index,
6514 int wedge_sign, BLOCK_SIZE bsize,
6515 int mi_row, int mi_col,
6516 int_mv *tmp_mv, int *rate_mv,
6517 int mv_idx[2], int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006518 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6519 MACROBLOCKD *xd = &x->e_mbd;
6520 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6521 BLOCK_SIZE sb_type = mbmi->sb_type;
6522 const uint8_t *mask;
6523 const int mask_stride = 4 * num_4x4_blocks_wide_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006524 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006525
6526 if (which == 0 || which == 2)
6527 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6528 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6529
6530 if (which == 1 || which == 2) {
6531 // get the negative mask
Yaowu Xuf883b422016-08-30 14:01:10 -07006532 mask = av1_get_contiguous_soft_mask(wedge_index, !wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006533 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6534 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6535 }
6536}
6537#endif // CONFIG_EXT_INTER
6538
6539// In some situations we want to discount tha pparent cost of a new motion
6540// vector. Where there is a subtle motion field and especially where there is
6541// low spatial complexity then it can be hard to cover the cost of a new motion
6542// vector in a single block, even if that motion vector reduces distortion.
6543// However, once established that vector may be usable through the nearest and
6544// near mv modes to reduce distortion in subsequent blocks and also improve
6545// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006546static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006547 int_mv this_mv,
6548 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6549 int ref_frame) {
6550 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6551 (this_mv.as_int != 0) &&
6552 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6553 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6554 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6555 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6556}
6557
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006558#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6559#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006560
6561// TODO(jingning): this mv clamping function should be block size dependent.
6562static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6563 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6564 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6565 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6566 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6567}
6568
6569#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006570static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006571 const BLOCK_SIZE bsize, const uint8_t *pred0,
6572 int stride0, const uint8_t *pred1, int stride1) {
6573 const struct macroblock_plane *const p = &x->plane[0];
6574 const uint8_t *src = p->src.buf;
6575 int src_stride = p->src.stride;
6576 const int f_index = bsize - BLOCK_8X8;
6577 const int bw = 4 << (b_width_log2_lookup[bsize]);
6578 const int bh = 4 << (b_height_log2_lookup[bsize]);
6579 uint32_t esq[2][4], var;
6580 int64_t tl, br;
6581
Yaowu Xuf883b422016-08-30 14:01:10 -07006582#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006583 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6584 pred0 = CONVERT_TO_BYTEPTR(pred0);
6585 pred1 = CONVERT_TO_BYTEPTR(pred1);
6586 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006587#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006588
6589 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6590 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6591 stride0, &esq[0][1]);
6592 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6593 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6594 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6595 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6596 &esq[0][3]);
6597 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6598 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6599 stride1, &esq[1][1]);
6600 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6601 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6602 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6603 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6604 &esq[1][3]);
6605 (void)var;
6606
6607 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6608 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6609 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6610 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6611 return (tl + br > 0);
6612}
6613#endif // CONFIG_EXT_INTER
6614
6615#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006616static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006617 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006618 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006619 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6620 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006621 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006622 const MACROBLOCKD *xd = &x->e_mbd;
6623 int bsl = mi_width_log2_lookup[bsize];
6624 int pred_filter_search =
6625 cpi->sf.cb_pred_filter_search
6626 ? (((mi_row + mi_col) >> bsl) +
6627 get_chessboard_index(cm->current_video_frame)) &
6628 0x1
6629 : 0;
6630 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6631 const int is_comp_pred = has_second_ref(mbmi);
6632 const int this_mode = mbmi->mode;
6633 int refs[2] = { mbmi->ref_frame[0],
6634 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006635 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006636 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006637 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6638 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6639
6640#if CONFIG_EXT_INTER
6641 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6642 this_mode != NEW_NEWMV) ||
6643 (af == lf))
6644#else
6645 if ((this_mode != NEWMV) || (af == lf))
6646#endif // CONFIG_EXT_INTER
6647 best_filter = af;
6648 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006649 if (is_comp_pred) {
6650 if (cpi->sf.adaptive_mode_search) {
6651#if CONFIG_EXT_INTER
6652 switch (this_mode) {
6653 case NEAREST_NEARESTMV:
6654 if (single_filter[NEARESTMV][refs[0]] ==
6655 single_filter[NEARESTMV][refs[1]])
6656 best_filter = single_filter[NEARESTMV][refs[0]];
6657 break;
6658 case NEAREST_NEARMV:
6659 if (single_filter[NEARESTMV][refs[0]] ==
6660 single_filter[NEARMV][refs[1]])
6661 best_filter = single_filter[NEARESTMV][refs[0]];
6662 break;
6663 case NEAR_NEARESTMV:
6664 if (single_filter[NEARMV][refs[0]] ==
6665 single_filter[NEARESTMV][refs[1]])
6666 best_filter = single_filter[NEARMV][refs[0]];
6667 break;
6668 case NEAR_NEARMV:
6669 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6670 best_filter = single_filter[NEARMV][refs[0]];
6671 break;
6672 case ZERO_ZEROMV:
6673 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6674 best_filter = single_filter[ZEROMV][refs[0]];
6675 break;
6676 case NEW_NEWMV:
6677 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6678 best_filter = single_filter[NEWMV][refs[0]];
6679 break;
6680 case NEAREST_NEWMV:
6681 if (single_filter[NEARESTMV][refs[0]] ==
6682 single_filter[NEWMV][refs[1]])
6683 best_filter = single_filter[NEARESTMV][refs[0]];
6684 break;
6685 case NEAR_NEWMV:
6686 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6687 best_filter = single_filter[NEARMV][refs[0]];
6688 break;
6689 case NEW_NEARESTMV:
6690 if (single_filter[NEWMV][refs[0]] ==
6691 single_filter[NEARESTMV][refs[1]])
6692 best_filter = single_filter[NEWMV][refs[0]];
6693 break;
6694 case NEW_NEARMV:
6695 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6696 best_filter = single_filter[NEWMV][refs[0]];
6697 break;
6698 default:
6699 if (single_filter[this_mode][refs[0]] ==
6700 single_filter[this_mode][refs[1]])
6701 best_filter = single_filter[this_mode][refs[0]];
6702 break;
6703 }
6704#else
6705 if (single_filter[this_mode][refs[0]] ==
6706 single_filter[this_mode][refs[1]])
6707 best_filter = single_filter[this_mode][refs[0]];
6708#endif // CONFIG_EXT_INTER
6709 }
6710 }
Angie Chiang75c22092016-10-25 12:19:16 -07006711 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6712 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006713 }
6714 return best_filter;
6715}
6716#endif
6717
6718#if CONFIG_EXT_INTER
6719// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006720static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006721 const BLOCK_SIZE bsize, const uint8_t *const p0,
6722 const uint8_t *const p1, int *const best_wedge_sign,
6723 int *const best_wedge_index) {
6724 const MACROBLOCKD *const xd = &x->e_mbd;
6725 const struct buf_2d *const src = &x->plane[0].src;
6726 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6727 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6728 const int N = bw * bh;
6729 int rate;
6730 int64_t dist;
6731 int64_t rd, best_rd = INT64_MAX;
6732 int wedge_index;
6733 int wedge_sign;
6734 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6735 const uint8_t *mask;
6736 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006737#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006738 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6739 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6740#else
6741 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006742#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006743
6744 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6745 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6746 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6747 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6748
6749 int64_t sign_limit;
6750
Yaowu Xuf883b422016-08-30 14:01:10 -07006751#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006752 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006753 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006754 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006755 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006756 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006757 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6759 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006760#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006761 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006762 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6763 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6764 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006765 }
6766
Yaowu Xuf883b422016-08-30 14:01:10 -07006767 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6768 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006769 (1 << WEDGE_WEIGHT_BITS) / 2;
6770
Yaowu Xuf883b422016-08-30 14:01:10 -07006771 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006772
6773 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006774 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6775 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006776
Yaowu Xuf883b422016-08-30 14:01:10 -07006777 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6778 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006779 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6780
6781 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6782 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6783
6784 if (rd < best_rd) {
6785 *best_wedge_index = wedge_index;
6786 *best_wedge_sign = wedge_sign;
6787 best_rd = rd;
6788 }
6789 }
6790
6791 return best_rd;
6792}
6793
6794// Choose the best wedge index the specified sign
6795static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006796 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006797 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6798 const int wedge_sign, int *const best_wedge_index) {
6799 const MACROBLOCKD *const xd = &x->e_mbd;
6800 const struct buf_2d *const src = &x->plane[0].src;
6801 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6802 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6803 const int N = bw * bh;
6804 int rate;
6805 int64_t dist;
6806 int64_t rd, best_rd = INT64_MAX;
6807 int wedge_index;
6808 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6809 const uint8_t *mask;
6810 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006811#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006812 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6813 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6814#else
6815 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006816#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006817
6818 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6819 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6820
Yaowu Xuf883b422016-08-30 14:01:10 -07006821#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006822 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006823 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006824 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006825 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006826 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6827 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006828#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006829 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006830 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6831 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006832 }
6833
6834 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006835 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6836 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006837 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6838
6839 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6840 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6841
6842 if (rd < best_rd) {
6843 *best_wedge_index = wedge_index;
6844 best_rd = rd;
6845 }
6846 }
6847
6848 return best_rd;
6849}
6850
Yaowu Xuf883b422016-08-30 14:01:10 -07006851static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006852 const MACROBLOCK *const x,
6853 const BLOCK_SIZE bsize,
6854 const uint8_t *const p0,
6855 const uint8_t *const p1) {
6856 const MACROBLOCKD *const xd = &x->e_mbd;
6857 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6858 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6859
6860 int64_t rd;
6861 int wedge_index = -1;
6862 int wedge_sign = 0;
6863
6864 assert(is_interinter_wedge_used(bsize));
6865
6866 if (cpi->sf.fast_wedge_sign_estimate) {
6867 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6868 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6869 } else {
6870 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6871 }
6872
6873 mbmi->interinter_wedge_sign = wedge_sign;
6874 mbmi->interinter_wedge_index = wedge_index;
6875 return rd;
6876}
6877
Yaowu Xuf883b422016-08-30 14:01:10 -07006878static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006879 const MACROBLOCK *const x,
6880 const BLOCK_SIZE bsize,
6881 const uint8_t *const p0,
6882 const uint8_t *const p1) {
6883 const MACROBLOCKD *const xd = &x->e_mbd;
6884 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6885
6886 int64_t rd;
6887 int wedge_index = -1;
6888
6889 assert(is_interintra_wedge_used(bsize));
6890
6891 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6892
6893 mbmi->interintra_wedge_sign = 0;
6894 mbmi->interintra_wedge_index = wedge_index;
6895 return rd;
6896}
6897#endif // CONFIG_EXT_INTER
6898
6899static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08006900 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
6901 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006902 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
6903 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07006904#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07006905 uint8_t *above_pred_buf[3], int above_pred_stride[3],
6906 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07006907#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006908#if CONFIG_EXT_INTER
6909 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
6910 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
6911 int *compmode_interintra_cost, int *compmode_wedge_cost,
6912 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
6913#else
6914 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
6915#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07006916 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Angie Chiang76159122016-11-09 12:13:22 -08006917 int (*single_skippable)[TOTAL_REFS_PER_FRAME], const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07006918 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006919 MACROBLOCKD *xd = &x->e_mbd;
6920 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6921 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6922 const int is_comp_pred = has_second_ref(mbmi);
6923 const int this_mode = mbmi->mode;
6924 int_mv *frame_mv = mode_mv[this_mode];
6925 int i;
6926 int refs[2] = { mbmi->ref_frame[0],
6927 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6928 int_mv cur_mv[2];
6929 int rate_mv = 0;
6930#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07006931 int pred_exists = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006932 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6933 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6934 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
6935 const unsigned int *const interintra_mode_cost =
6936 cpi->interintra_mode_cost[size_group_lookup[bsize]];
6937 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6938#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006939 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006940#endif
6941#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006942#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006943 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
6944#else
6945 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006946#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006947 uint8_t *tmp_buf;
6948
Yue Chencb60b182016-10-13 15:18:22 -07006949#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006950 int allow_motvar =
6951#if CONFIG_EXT_INTER
6952 !is_comp_interintra_pred &&
6953#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006954 is_motion_variation_allowed(mbmi);
Angie Chiang76159122016-11-09 12:13:22 -08006955 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
6956 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006957#if CONFIG_VAR_TX
6958 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
6959#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07006960 int64_t best_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006961 MB_MODE_INFO best_mbmi;
6962#if CONFIG_EXT_INTER
6963 int rate2_bmc_nocoeff;
6964 int rate_mv_bmc;
6965 MB_MODE_INFO best_bmc_mbmi;
6966#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006967#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07006968 int64_t rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006969 uint8_t *orig_dst[MAX_MB_PLANE];
6970 int orig_dst_stride[MAX_MB_PLANE];
Angie Chiang75c22092016-10-25 12:19:16 -07006971 uint8_t *tmp_dst[MAX_MB_PLANE];
6972 int tmp_dst_stride[MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006973 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07006974 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006975
6976 int skip_txfm_sb = 0;
6977 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006978 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
Angie Chiang76159122016-11-09 12:13:22 -08006979#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
6980 av1_invalid_rd_stats(&best_rd_stats);
6981#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006982
6983#if CONFIG_EXT_INTER
6984 *compmode_interintra_cost = 0;
6985 mbmi->use_wedge_interintra = 0;
6986 *compmode_wedge_cost = 0;
Sarah Parker6fddd182016-11-10 20:57:20 -08006987 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006988
6989 // is_comp_interintra_pred implies !is_comp_pred
6990 assert(!is_comp_interintra_pred || (!is_comp_pred));
6991 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6992 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6993#endif // CONFIG_EXT_INTER
6994
6995#if CONFIG_REF_MV
6996#if CONFIG_EXT_INTER
6997 if (is_comp_pred)
6998 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6999 else
7000#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007001 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
7002 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007003#endif
7004
Yaowu Xuf883b422016-08-30 14:01:10 -07007005#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007006 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7007 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7008 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007009#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007010 tmp_buf = tmp_buf_;
7011
7012 if (is_comp_pred) {
7013 if (frame_mv[refs[0]].as_int == INVALID_MV ||
7014 frame_mv[refs[1]].as_int == INVALID_MV)
7015 return INT64_MAX;
7016 }
7017
Yue Chene9638cc2016-10-10 12:37:54 -07007018 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007019 if (have_newmv_in_inter_mode(this_mode)) {
7020 if (is_comp_pred) {
7021#if CONFIG_EXT_INTER
7022 for (i = 0; i < 2; ++i) {
7023 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
7024 }
7025
7026 if (this_mode == NEW_NEWMV) {
7027 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7028 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7029
7030 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7031 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
7032 single_newmv, &rate_mv, 0);
7033 } else {
7034#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007035 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007036#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007037 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007038 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007039 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007040#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007041 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007042#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007043 rate_mv += av1_mv_bit_cost(
Zoe Liu82c8c922016-11-01 14:52:34 -07007044 &frame_mv[refs[1]].as_mv, &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007045 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7046 }
7047 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7048 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007049 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007050 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007051 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007052 } else {
7053 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007054 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007055 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007056 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007057 }
7058#else
7059 // Initialize mv using single prediction mode result.
7060 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7061 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7062
7063 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7064 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
7065 single_newmv, &rate_mv, 0);
7066 } else {
7067#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007068 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007069#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007070 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007071 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007072 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007073#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007074 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007075#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007076 rate_mv += av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007077 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007078 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007079 }
7080#endif // CONFIG_EXT_INTER
7081 } else {
7082#if CONFIG_EXT_INTER
7083 if (is_comp_interintra_pred) {
7084 x->best_mv = single_newmvs[mv_idx][refs[0]];
7085 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
7086 } else {
7087 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
7088 &rate_mv);
7089 single_newmvs[mv_idx][refs[0]] = x->best_mv;
7090 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
7091 }
7092#else
7093 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
7094 single_newmv[refs[0]] = x->best_mv;
7095#endif // CONFIG_EXT_INTER
7096
7097 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7098
7099 frame_mv[refs[0]] = x->best_mv;
7100 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7101
7102 // Estimate the rate implications of a new mv but discount this
7103 // under certain circumstances where we want to help initiate a weak
7104 // motion field, where the distortion gain for a single block may not
7105 // be enough to overcome the cost of a new mv.
7106 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007107 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007108 }
7109 }
Angie Chiang76159122016-11-09 12:13:22 -08007110 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007111 }
7112
7113 for (i = 0; i < is_comp_pred + 1; ++i) {
7114 cur_mv[i] = frame_mv[refs[i]];
7115// Clip "next_nearest" so that it does not extend to far out of image
7116#if CONFIG_EXT_INTER
7117 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
7118#else
7119 if (this_mode != NEWMV)
7120#endif // CONFIG_EXT_INTER
7121 clamp_mv2(&cur_mv[i].as_mv, xd);
7122
7123 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7124 mbmi->mv[i].as_int = cur_mv[i].as_int;
7125 }
7126
7127#if CONFIG_REF_MV
7128#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007129 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007130#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08007131 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007132#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007133 {
7134#if !CONFIG_EXT_INTER
7135 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
7136#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007137 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7138 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7139 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7140
7141 for (i = 0; i < 2; ++i) {
7142 clamp_mv2(&cur_mv[i].as_mv, xd);
7143 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7144 mbmi->mv[i].as_int = cur_mv[i].as_int;
7145 }
7146 }
7147 }
7148
7149#if CONFIG_EXT_INTER
7150 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7151 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
7152 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7153
7154 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7155 clamp_mv2(&cur_mv[0].as_mv, xd);
7156 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7157 mbmi->mv[0].as_int = cur_mv[0].as_int;
7158 }
7159
7160 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
7161 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7162
7163 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7164 clamp_mv2(&cur_mv[1].as_mv, xd);
7165 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7166 mbmi->mv[1].as_int = cur_mv[1].as_int;
7167 }
7168 }
7169
7170 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7171 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
7172 this_mode == NEAR_NEARMV) {
7173 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
7174
7175 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7176 clamp_mv2(&cur_mv[0].as_mv, xd);
7177 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7178 mbmi->mv[0].as_int = cur_mv[0].as_int;
7179 }
7180
7181 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
7182 this_mode == NEAR_NEARMV) {
7183 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
7184
7185 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7186 clamp_mv2(&cur_mv[1].as_mv, xd);
7187 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7188 mbmi->mv[1].as_int = cur_mv[1].as_int;
7189 }
7190 }
7191#else
7192 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007193 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007194 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7195 int ref_mv_idx = mbmi->ref_mv_idx + 1;
7196 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
7197 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
7198
7199 for (i = 0; i < 2; ++i) {
7200 clamp_mv2(&cur_mv[i].as_mv, xd);
7201 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7202 mbmi->mv[i].as_int = cur_mv[i].as_int;
7203 }
7204 }
7205 }
7206#endif // CONFIG_EXT_INTER
7207#endif // CONFIG_REF_MV
7208
7209 // do first prediction into the destination buffer. Do the next
7210 // prediction into a temporary buffer. Then keep track of which one
7211 // of these currently holds the best predictor, and use the other
7212 // one for future predictions. In the end, copy from tmp_buf to
7213 // dst if necessary.
7214 for (i = 0; i < MAX_MB_PLANE; i++) {
Angie Chiang75c22092016-10-25 12:19:16 -07007215 tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
7216 tmp_dst_stride[i] = MAX_SB_SIZE;
7217 }
7218 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007219 orig_dst[i] = xd->plane[i].dst.buf;
7220 orig_dst_stride[i] = xd->plane[i].dst.stride;
7221 }
7222
7223 // We don't include the cost of the second reference here, because there
7224 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
7225 // words if you present them in that order, the second one is always known
7226 // if the first is known.
7227 //
7228 // Under some circumstances we discount the cost of new mv mode to encourage
7229 // initiation of a motion field.
7230 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
7231 refs[0])) {
7232#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007233 rd_stats->rate +=
7234 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
7235 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007236#else
Angie Chiang76159122016-11-09 12:13:22 -08007237 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7238 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007239#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7240 } else {
7241#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007242 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007243#else
Angie Chiang76159122016-11-09 12:13:22 -08007244 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007245#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7246 }
7247
Angie Chiang76159122016-11-09 12:13:22 -08007248 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07007249#if CONFIG_EXT_INTER
7250 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
7251#else
7252 mbmi->mode != NEARESTMV
7253#endif // CONFIG_EXT_INTER
7254 )
7255 return INT64_MAX;
7256
Angie Chiang75c22092016-10-25 12:19:16 -07007257 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007258#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007259 assign_filter =
7260 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007261#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007262#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
7263 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
7264#endif
7265 } else {
7266 assign_filter = cm->interp_filter;
7267 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007268
Angie Chiang75c22092016-10-25 12:19:16 -07007269 { // Do interpolation filter search in the parentheses
7270 int tmp_rate;
7271 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007272#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007273 mbmi->interp_filter[0] =
7274 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7275 mbmi->interp_filter[1] =
7276 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7277 mbmi->interp_filter[2] =
7278 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7279 mbmi->interp_filter[3] =
7280 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007281#else
Angie Chiang75c22092016-10-25 12:19:16 -07007282 mbmi->interp_filter =
7283 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007284#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007285 rs = av1_get_switchable_rate(cpi, xd);
7286 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7287 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7288 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7289 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007290
Angie Chiang75c22092016-10-25 12:19:16 -07007291 if (assign_filter == SWITCHABLE) {
7292 // do interp_filter search
7293 if (av1_is_interp_needed(xd)) {
7294 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007295#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007296 InterpFilter best_filter[4];
7297 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007298#else
Angie Chiang75c22092016-10-25 12:19:16 -07007299 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007300#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007301 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7302#if CONFIG_DUAL_FILTER
7303 // EIGHTTAP_REGULAR mode is calculated beforehand
7304 for (i = 1; i < SWITCHABLE_FILTERS * SWITCHABLE_FILTERS; ++i)
7305#else
7306 // EIGHTTAP_REGULAR mode is calculated beforehand
7307 for (i = 1; i < SWITCHABLE_FILTERS; ++i)
7308#endif
7309 {
7310 int tmp_skip_sb = 0;
7311 int64_t tmp_skip_sse = INT64_MAX;
7312 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07007313 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007314#if CONFIG_DUAL_FILTER
7315 mbmi->interp_filter[0] = filter_sets[i][0];
7316 mbmi->interp_filter[1] = filter_sets[i][1];
7317 mbmi->interp_filter[2] = filter_sets[i][0];
7318 mbmi->interp_filter[3] = filter_sets[i][1];
7319#else
7320 mbmi->interp_filter = i;
7321#endif
7322 tmp_rs = av1_get_switchable_rate(cpi, xd);
7323 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7324 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7325 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7326 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007327
Angie Chiang75c22092016-10-25 12:19:16 -07007328 if (tmp_rd < rd) {
7329 rd = tmp_rd;
7330 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007331#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007332 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007333#else
Angie Chiang75c22092016-10-25 12:19:16 -07007334 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007335#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007336 skip_txfm_sb = tmp_skip_sb;
7337 skip_sse_sb = tmp_skip_sse;
7338 best_in_temp = !best_in_temp;
7339 if (best_in_temp) {
7340 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7341 } else {
7342 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7343 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007344 }
7345 }
Angie Chiang75c22092016-10-25 12:19:16 -07007346 if (best_in_temp) {
7347 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7348 } else {
7349 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007350 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007351#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007352 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007353#else
Angie Chiang75c22092016-10-25 12:19:16 -07007354 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007355#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007356 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007357#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7358 int tmp_rs;
7359 InterpFilter best_filter = mbmi->interp_filter;
7360 rs = av1_get_switchable_rate(cpi, xd);
7361 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7362 mbmi->interp_filter = i;
7363 tmp_rs = av1_get_switchable_rate(cpi, xd);
7364 if (tmp_rs < rs) {
7365 rs = tmp_rs;
7366 best_filter = i;
7367 }
7368 }
7369 mbmi->interp_filter = best_filter;
7370#else
7371 assert(0);
7372#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007373 }
7374 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007375 }
7376
Yaowu Xuc27fc142016-08-22 16:08:15 -07007377#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007378#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007379 best_bmc_mbmi = *mbmi;
7380 rate_mv_bmc = rate_mv;
Angie Chiang76159122016-11-09 12:13:22 -08007381 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007382 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007383#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007384
7385 if (is_comp_pred && is_interinter_wedge_used(bsize)) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007386 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007387 int64_t dist_sum;
7388 int64_t best_rd_nowedge = INT64_MAX;
7389 int64_t best_rd_wedge = INT64_MAX;
7390 int tmp_skip_txfm_sb;
7391 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08007392 int compound_type_cost[COMPOUND_TYPES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007393
Sarah Parker6fddd182016-11-10 20:57:20 -08007394 mbmi->interinter_compound = COMPOUND_AVERAGE;
7395 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
7396 av1_compound_type_tree);
7397 rs2 = compound_type_cost[mbmi->interinter_compound];
Yaowu Xuf883b422016-08-30 14:01:10 -07007398 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
7399 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007400 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7401 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7402 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007403 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007404 best_rd_nowedge = rd;
7405
7406 // Disbale wedge search if source variance is small
7407 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7408 best_rd_nowedge / 3 < ref_best_rd) {
7409 uint8_t pred0[2 * MAX_SB_SQUARE];
7410 uint8_t pred1[2 * MAX_SB_SQUARE];
7411 uint8_t *preds0[1] = { pred0 };
7412 uint8_t *preds1[1] = { pred1 };
7413 int strides[1] = { bw };
7414
Sarah Parker6fddd182016-11-10 20:57:20 -08007415 mbmi->interinter_compound = COMPOUND_WEDGE;
Urvang Joshi368fbc92016-10-17 16:31:34 -07007416 rs2 = av1_cost_literal(get_interinter_wedge_bits(bsize)) +
Sarah Parker6fddd182016-11-10 20:57:20 -08007417 compound_type_cost[mbmi->interinter_compound];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007418
Yaowu Xuf883b422016-08-30 14:01:10 -07007419 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007420 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007421 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007422 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
7423
7424 // Choose the best wedge
7425 best_rd_wedge = pick_interinter_wedge(cpi, x, bsize, pred0, pred1);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007426 best_rd_wedge += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007427
7428 if (have_newmv_in_inter_mode(this_mode)) {
7429 int_mv tmp_mv[2];
7430 int rate_mvs[2], tmp_rate_mv = 0;
7431 if (this_mode == NEW_NEWMV) {
7432 int mv_idxs[2] = { 0, 0 };
7433 do_masked_motion_search_indexed(
7434 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7435 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 2);
7436 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7437 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7438 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7439 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7440 int mv_idxs[2] = { 0, 0 };
7441 do_masked_motion_search_indexed(
7442 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7443 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 0);
7444 tmp_rate_mv = rate_mvs[0];
7445 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7446 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7447 int mv_idxs[2] = { 0, 0 };
7448 do_masked_motion_search_indexed(
7449 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7450 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 1);
7451 tmp_rate_mv = rate_mvs[1];
7452 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7453 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007454 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007455 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7456 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007457 rd =
7458 RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007459 if (rd < best_rd_wedge) {
7460 best_rd_wedge = rd;
7461 } else {
7462 mbmi->mv[0].as_int = cur_mv[0].as_int;
7463 mbmi->mv[1].as_int = cur_mv[1].as_int;
7464 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007465 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7466 strides, preds1, strides);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007467 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007468 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007469 rd =
7470 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7471 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7472 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007473 rd = RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007474 dist_sum);
7475 best_rd_wedge = rd;
7476
7477 if (best_rd_wedge < best_rd_nowedge) {
Sarah Parker6fddd182016-11-10 20:57:20 -08007478 mbmi->interinter_compound = COMPOUND_WEDGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007479 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7480 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007481 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482 rate_mv = tmp_rate_mv;
7483 } else {
Sarah Parker6fddd182016-11-10 20:57:20 -08007484 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007485 mbmi->mv[0].as_int = cur_mv[0].as_int;
7486 mbmi->mv[1].as_int = cur_mv[1].as_int;
7487 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7488 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7489 }
7490 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007491 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7492 strides, preds1, strides);
7493 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007494 rd =
7495 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7496 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7497 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007498 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007499 best_rd_wedge = rd;
7500 if (best_rd_wedge < best_rd_nowedge) {
Sarah Parker6fddd182016-11-10 20:57:20 -08007501 mbmi->interinter_compound = COMPOUND_WEDGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007502 } else {
Sarah Parker6fddd182016-11-10 20:57:20 -08007503 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007504 }
7505 }
7506 }
7507 if (ref_best_rd < INT64_MAX &&
Yaowu Xuf883b422016-08-30 14:01:10 -07007508 AOMMIN(best_rd_wedge, best_rd_nowedge) / 3 > ref_best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007509 return INT64_MAX;
7510
7511 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007512
Sarah Parker6fddd182016-11-10 20:57:20 -08007513 *compmode_wedge_cost = compound_type_cost[mbmi->interinter_compound];
7514
Zoe Liu00d54722016-11-15 16:42:16 -08007515 if (mbmi->interinter_compound == COMPOUND_WEDGE)
Sarah Parker6fddd182016-11-10 20:57:20 -08007516 *compmode_wedge_cost +=
7517 av1_cost_literal(get_interinter_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007518 }
7519
7520 if (is_comp_interintra_pred) {
7521 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7522 int64_t best_interintra_rd = INT64_MAX;
7523 int rmode, rate_sum;
7524 int64_t dist_sum;
7525 int j;
7526 int64_t best_interintra_rd_nowedge = INT64_MAX;
7527 int64_t best_interintra_rd_wedge = INT64_MAX;
7528 int rwedge;
7529 int_mv tmp_mv;
7530 int tmp_rate_mv = 0;
7531 int tmp_skip_txfm_sb;
7532 int64_t tmp_skip_sse_sb;
7533 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7534 uint8_t *intrapred;
7535
Yaowu Xuf883b422016-08-30 14:01:10 -07007536#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007537 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7538 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7539 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007540#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007541 intrapred = intrapred_;
7542
7543 mbmi->ref_frame[1] = NONE;
7544 for (j = 0; j < MAX_MB_PLANE; j++) {
7545 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7546 xd->plane[j].dst.stride = bw;
7547 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007548 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007549 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7550 mbmi->ref_frame[1] = INTRA_FRAME;
7551 mbmi->use_wedge_interintra = 0;
7552
7553 for (j = 0; j < INTERINTRA_MODES; ++j) {
7554 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7555 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007556 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7557 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007558 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7559 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7560 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7561 if (rd < best_interintra_rd) {
7562 best_interintra_rd = rd;
7563 best_interintra_mode = mbmi->interintra_mode;
7564 }
7565 }
7566 mbmi->interintra_mode = best_interintra_mode;
7567 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007568 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7569 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7570 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007571 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7572 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7573 if (rd != INT64_MAX)
7574 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7575 best_interintra_rd = rd;
7576
7577 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
7578 return INT64_MAX;
7579 }
7580 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007581 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007582 if (rd != INT64_MAX)
7583 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7584 dist_sum);
7585 best_interintra_rd_nowedge = rd;
7586
7587 // Disbale wedge search if source variance is small
7588 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7589 mbmi->use_wedge_interintra = 1;
7590
Yaowu Xuf883b422016-08-30 14:01:10 -07007591 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7592 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007593
7594 best_interintra_rd_wedge =
7595 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7596
7597 best_interintra_rd_wedge +=
7598 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7599 // Refine motion vector.
7600 if (have_newmv_in_inter_mode(this_mode)) {
7601 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007602 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007603 mbmi->interintra_wedge_index, 1, bsize);
7604 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7605 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7606 mbmi->mv[0].as_int = tmp_mv.as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007607 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007608 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7609 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7610 rd = RDCOST(x->rdmult, x->rddiv,
7611 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7612 if (rd < best_interintra_rd_wedge) {
7613 best_interintra_rd_wedge = rd;
7614 } else {
7615 tmp_mv.as_int = cur_mv[0].as_int;
7616 tmp_rate_mv = rate_mv;
7617 }
7618 } else {
7619 tmp_mv.as_int = cur_mv[0].as_int;
7620 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007621 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007622 }
7623 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007624 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007625 rd =
7626 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7627 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7628 if (rd != INT64_MAX)
7629 rd = RDCOST(x->rdmult, x->rddiv,
7630 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7631 best_interintra_rd_wedge = rd;
7632 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7633 mbmi->use_wedge_interintra = 1;
7634 best_interintra_rd = best_interintra_rd_wedge;
7635 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007636 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007637 rate_mv = tmp_rate_mv;
7638 } else {
7639 mbmi->use_wedge_interintra = 0;
7640 best_interintra_rd = best_interintra_rd_nowedge;
7641 mbmi->mv[0].as_int = cur_mv[0].as_int;
7642 }
7643 } else {
7644 mbmi->use_wedge_interintra = 0;
7645 best_interintra_rd = best_interintra_rd_nowedge;
7646 }
7647 }
7648
7649 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007650 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007651 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007652 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7653 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007654 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007655 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7656 if (mbmi->use_wedge_interintra) {
7657 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007658 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007659 }
7660 }
7661 } else if (is_interintra_allowed(mbmi)) {
7662 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007663 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007664 }
7665
7666#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007667 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007668#if CONFIG_DUAL_FILTER
7669 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7670#else
7671 mbmi->interp_filter = EIGHTTAP_REGULAR;
7672#endif
7673 pred_exists = 0;
7674 }
7675#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007676 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007677 int tmp_rate;
7678 int64_t tmp_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07007679 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007680 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7681 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7682 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7683 }
Angie Chiang75c22092016-10-25 12:19:16 -07007684#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007685
7686#if CONFIG_DUAL_FILTER
7687 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7688#else
7689 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7690#endif
7691
7692#if CONFIG_EXT_INTER
7693 if (modelled_rd != NULL) {
7694 if (is_comp_pred) {
7695 const int mode0 = compound_ref0_mode(this_mode);
7696 const int mode1 = compound_ref1_mode(this_mode);
7697 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007698 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007699 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
7700 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7701 return INT64_MAX;
7702 }
7703 } else if (!is_comp_interintra_pred) {
7704 modelled_rd[this_mode][refs[0]] = rd;
7705 }
7706 }
7707#endif // CONFIG_EXT_INTER
7708
7709 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7710 // if current pred_error modeled rd is substantially more than the best
7711 // so far, do not bother doing full rd
7712 if (rd / 2 > ref_best_rd) {
7713 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7714 return INT64_MAX;
7715 }
7716 }
7717
Angie Chiang76159122016-11-09 12:13:22 -08007718 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007719#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08007720 rate2_nocoeff = rd_stats->rate;
Yue Chencb60b182016-10-13 15:18:22 -07007721#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007722
Yue Chencb60b182016-10-13 15:18:22 -07007723#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007724 best_rd = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007725 for (mbmi->motion_mode = SIMPLE_TRANSLATION;
7726 mbmi->motion_mode < (allow_motvar ? MOTION_MODES : 1);
7727 mbmi->motion_mode++) {
Angie Chianga2b56d32016-10-25 17:34:59 -07007728 int64_t tmp_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007729#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007730 int tmp_rate2 = mbmi->motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff
7731 : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007732#else
7733 int tmp_rate2 = rate2_nocoeff;
7734#endif // CONFIG_EXT_INTER
7735#if CONFIG_EXT_INTERP
7736#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007737 InterpFilter obmc_interp_filter[2][2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007738 { mbmi->interp_filter[0], mbmi->interp_filter[1] }, // obmc == 0
7739 { mbmi->interp_filter[0], mbmi->interp_filter[1] } // obmc == 1
7740 };
7741#else
James Zern7b9407a2016-05-18 23:48:05 -07007742 InterpFilter obmc_interp_filter[2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007743 mbmi->interp_filter, // obmc == 0
7744 mbmi->interp_filter // obmc == 1
7745 };
7746#endif // CONFIG_DUAL_FILTER
7747#endif // CONFIG_EXT_INTERP
7748
Yue Chencb60b182016-10-13 15:18:22 -07007749#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007750 int tmp_rate;
7751 int64_t tmp_dist;
Yue Chencb60b182016-10-13 15:18:22 -07007752 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007753#if CONFIG_EXT_INTER
7754 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007755 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007756#endif // CONFIG_EXT_INTER
7757 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007758 int tmp_rate_mv = 0;
7759
Yue Chene9638cc2016-10-10 12:37:54 -07007760 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007761#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007762 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007763#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007764 &tmp_rate_mv);
7765 mbmi->mv[0].as_int = x->best_mv.as_int;
7766 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7767 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007768 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007769 }
7770#if CONFIG_EXT_INTER
7771 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7772#else
7773 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7774#endif // CONFIG_EXT_INTER
7775#if CONFIG_EXT_INTERP
7776#if CONFIG_DUAL_FILTER
7777 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7778 obmc_interp_filter[1][0] = mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7779 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7780 obmc_interp_filter[1][1] = mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7781#else
Yaowu Xuf883b422016-08-30 14:01:10 -07007782 if (!av1_is_interp_needed(xd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007783 obmc_interp_filter[1] = mbmi->interp_filter = EIGHTTAP_REGULAR;
7784#endif // CONFIG_DUAL_FILTER
7785 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7786 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007787 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007788#endif // CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007789 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007790#if CONFIG_EXT_INTER
7791 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007792 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007793#endif // CONFIG_EXT_INTER
7794 }
Yue Chene9638cc2016-10-10 12:37:54 -07007795 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7796 above_pred_stride, left_pred_buf,
7797 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007798 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7799 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7800 }
Yue Chencb60b182016-10-13 15:18:22 -07007801#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007802
7803#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007804 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007805 // TODO(yuec): Add code
7806 }
7807#endif // CONFIG_WARPED_MOTION
7808 x->skip = 0;
7809
Angie Chiang76159122016-11-09 12:13:22 -08007810 rd_stats->rate = tmp_rate2;
7811 if (allow_motvar)
7812 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7813 rd_stats->dist = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007814#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007815 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007816 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07007817 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08007818
Yaowu Xu1e761992016-11-09 15:01:47 -08007819 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08007820 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007821#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08007822 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08007823 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007824 } else {
7825 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08007826 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007827 for (idy = 0; idy < xd->n8_h; ++idy)
7828 for (idx = 0; idx < xd->n8_w; ++idx)
7829 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08007830 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08007831 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7832 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08007833#else
Yaowu Xu1e761992016-11-09 15:01:47 -08007834 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08007835 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007836/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007837#endif // CONFIG_VAR_TX
7838
Angie Chiang76159122016-11-09 12:13:22 -08007839 if (rd_stats_y->rate == INT_MAX) {
7840 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07007841#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7842 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007843 continue;
7844 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007845#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007846 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7847 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007848#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007849 }
Yue Chencb60b182016-10-13 15:18:22 -07007850#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007851 }
7852
Angie Chiang76159122016-11-09 12:13:22 -08007853 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007854
Angie Chiang76159122016-11-09 12:13:22 -08007855 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7856 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007857/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007858#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007859 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007860 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007861#else
7862 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007863 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007864#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007865 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07007866#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007867 continue;
7868#else
Debargha Mukherjee0e119122016-11-04 12:10:23 -07007869 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7870 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007871#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007872 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007873 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08007874 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08007875#if CONFIG_RD_DEBUG
7876 // record transform block coefficient cost
7877 // TODO(angiebird): So far rd_debug tool only detects descrepancy of
7878 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
7879 // here because we already collect the coefficient cost. Move this part to
7880 // other place when we need to compare non-coefficient cost.
7881 mbmi->rd_stats = *rd_stats;
7882#endif
Yue Chencb60b182016-10-13 15:18:22 -07007883#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007884 if (rd_stats->skip) {
7885 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7886 rd_stats_y->rate = 0;
7887 rd_stats_uv->rate = 0;
7888 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007889 mbmi->skip = 0;
7890 // here mbmi->skip temporarily plays a role as what this_skip2 does
7891 } else if (!xd->lossless[mbmi->segment_id] &&
7892 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007893 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07007894 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08007895 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07007896 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007897 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
7898 rd_stats->sse))) {
7899 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7900 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7901 rd_stats->dist = rd_stats->sse;
7902 rd_stats_y->rate = 0;
7903 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007904 mbmi->skip = 1;
7905 } else {
Angie Chiang76159122016-11-09 12:13:22 -08007906 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007907 mbmi->skip = 0;
7908 }
7909 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007910#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007911 } else {
7912 x->skip = 1;
7913 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07007914 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007915
7916// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07007917#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007918 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007919#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007920 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007921
Angie Chiang76159122016-11-09 12:13:22 -08007922 rd_stats->dist = skip_sse_sb;
7923 rd_stats->sse = skip_sse_sb;
7924 rd_stats_y->rate = 0;
7925 rd_stats_uv->rate = 0;
7926 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007927 }
Sarah Parkere5299862016-08-16 14:57:37 -07007928#if CONFIG_GLOBAL_MOTION
7929 if (this_mode == ZEROMV) {
Angie Chiang76159122016-11-09 12:13:22 -08007930 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
7931 if (is_comp_pred)
7932 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
Sarah Parkere5299862016-08-16 14:57:37 -07007933 }
7934#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007935
Yue Chencb60b182016-10-13 15:18:22 -07007936#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007937 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07007938 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007939#if CONFIG_EXT_INTERP
7940#if CONFIG_DUAL_FILTER
Yue Chencb60b182016-10-13 15:18:22 -07007941 mbmi->interp_filter[0] = obmc_interp_filter[mbmi->motion_mode][0];
7942 mbmi->interp_filter[1] = obmc_interp_filter[mbmi->motion_mode][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007943#else
Yue Chencb60b182016-10-13 15:18:22 -07007944 mbmi->interp_filter = obmc_interp_filter[mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007945#endif // CONFIG_DUAL_FILTER
7946#endif // CONFIG_EXT_INTERP
7947 best_mbmi = *mbmi;
7948 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08007949 best_rd_stats = *rd_stats;
7950 best_rd_stats_y = *rd_stats_y;
7951 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007952#if CONFIG_VAR_TX
7953 for (i = 0; i < MAX_MB_PLANE; ++i)
7954 memcpy(best_blk_skip[i], x->blk_skip[i],
7955 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7956#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07007957 best_xskip = x->skip;
7958 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07007959#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007960 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007961 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007962 cpi, &xd->plane[0].dst, bsize, xd->bd);
7963 } else {
7964 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007965 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007966 }
7967#else
7968 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007969 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7970#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007971 }
7972 }
7973
7974 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08007975 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007976 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7977 return INT64_MAX;
7978 }
7979 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08007980 *rd_stats = best_rd_stats;
7981 *rd_stats_y = best_rd_stats_y;
7982 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007983#if CONFIG_VAR_TX
7984 for (i = 0; i < MAX_MB_PLANE; ++i)
7985 memcpy(x->blk_skip[i], best_blk_skip[i],
7986 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7987#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07007988 x->skip = best_xskip;
7989 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07007990#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007991
Angie Chiang76159122016-11-09 12:13:22 -08007992 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007993
Yue Chencb60b182016-10-13 15:18:22 -07007994#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuf883b422016-08-30 14:01:10 -07007995#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007996 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007997 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007998 cpi, &xd->plane[0].dst, bsize, xd->bd);
7999 } else {
8000 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008001 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008002 }
8003#else
8004 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008005 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8006#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008007#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008008
8009 restore_dst_buf(xd, orig_dst, orig_dst_stride);
8010 return 0; // The rate-distortion cost will be re-calculated by caller.
8011}
8012
Urvang Joshi52648442016-10-13 17:27:51 -07008013void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
8014 RD_COST *rd_cost, BLOCK_SIZE bsize,
8015 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
8016 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008017 MACROBLOCKD *const xd = &x->e_mbd;
8018 struct macroblockd_plane *const pd = xd->plane;
8019 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
8020 int y_skip = 0, uv_skip = 0;
8021 int64_t dist_y = 0, dist_uv = 0;
8022 TX_SIZE max_uv_tx_size;
8023 ctx->skip = 0;
8024 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
8025 xd->mi[0]->mbmi.ref_frame[1] = NONE;
8026
8027 if (bsize >= BLOCK_8X8) {
8028 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
8029 &y_skip, bsize, best_rd) >= best_rd) {
8030 rd_cost->rate = INT_MAX;
8031 return;
8032 }
8033 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008034 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07008035 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008036 rd_cost->rate = INT_MAX;
8037 return;
8038 }
8039 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008040 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
8041 [pd[1].subsampling_x][pd[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008042 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008043 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008044
8045 if (y_skip && uv_skip) {
8046 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07008047 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008048 rd_cost->dist = dist_y + dist_uv;
8049 } else {
8050 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07008051 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008052 rd_cost->dist = dist_y + dist_uv;
8053 }
8054
8055 ctx->mic = *xd->mi[0];
8056 ctx->mbmi_ext = *x->mbmi_ext;
8057 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
8058}
8059
Yaowu Xuc27fc142016-08-22 16:08:15 -07008060// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07008061int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008062 return (cpi->oxcf.pass == 2) &&
8063 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
8064 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
8065}
8066
8067// Checks to see if a super block is on a horizontal image edge.
8068// In most cases this is the "real" edge unless there are formatting
8069// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008070int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008071 int top_edge = 0;
8072 int bottom_edge = cpi->common.mi_rows;
8073 int is_active_h_edge = 0;
8074
8075 // For two pass account for any formatting bars detected.
8076 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008077 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008078
8079 // The inactive region is specified in MBs not mi units.
8080 // The image edge is in the following MB row.
8081 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
8082
8083 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008084 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008085 }
8086
8087 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
8088 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
8089 is_active_h_edge = 1;
8090 }
8091 return is_active_h_edge;
8092}
8093
8094// Checks to see if a super block is on a vertical image edge.
8095// In most cases this is the "real" edge unless there are formatting
8096// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008097int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008098 int left_edge = 0;
8099 int right_edge = cpi->common.mi_cols;
8100 int is_active_v_edge = 0;
8101
8102 // For two pass account for any formatting bars detected.
8103 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008104 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008105
8106 // The inactive region is specified in MBs not mi units.
8107 // The image edge is in the following MB row.
8108 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
8109
8110 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008111 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008112 }
8113
8114 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
8115 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
8116 is_active_v_edge = 1;
8117 }
8118 return is_active_v_edge;
8119}
8120
8121// Checks to see if a super block is at the edge of the active image.
8122// In most cases this is the "real" edge unless there are formatting
8123// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008124int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008125 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
8126 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008127}
8128
Urvang Joshib100db72016-10-12 16:28:56 -07008129#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07008130static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008131 MACROBLOCKD *const xd = &x->e_mbd;
8132 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8133 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
8134 const BLOCK_SIZE bsize = mbmi->sb_type;
8135 const int rows =
8136 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
8137 const int cols =
8138 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
8139 int src_stride = x->plane[1].src.stride;
8140 const uint8_t *const src_u = x->plane[1].src.buf;
8141 const uint8_t *const src_v = x->plane[2].src.buf;
8142 float *const data = x->palette_buffer->kmeans_data_buf;
8143 float centroids[2 * PALETTE_MAX_SIZE];
8144 uint8_t *const color_map = xd->plane[1].color_index_map;
8145 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07008146#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008147 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
8148 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07008149#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008150 (void)cpi;
8151
8152 for (r = 0; r < rows; ++r) {
8153 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008154#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008155 if (cpi->common.use_highbitdepth) {
8156 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
8157 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
8158 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008159#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008160 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
8161 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07008162#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008163 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008164#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008165 }
8166 }
8167
8168 for (r = 1; r < 3; ++r) {
8169 for (c = 0; c < pmi->palette_size[1]; ++c) {
8170 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
8171 }
8172 }
8173
Yaowu Xuf883b422016-08-30 14:01:10 -07008174 av1_calc_indices(data, centroids, color_map, rows * cols,
8175 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008176}
Urvang Joshib100db72016-10-12 16:28:56 -07008177#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008178
hui su5db97432016-10-14 16:10:14 -07008179#if CONFIG_FILTER_INTRA
8180static void pick_filter_intra_interframe(
8181 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07008182 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
8183 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07008184 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
8185#if CONFIG_EXT_INTRA
8186 int8_t *uv_angle_delta,
8187#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07008188#if CONFIG_PALETTE
8189 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
8190#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008191 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
8192 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
8193 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
8194#if CONFIG_SUPERTX
8195 int *returnrate_nocoef,
8196#endif // CONFIG_SUPERTX
8197 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07008198 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008199 MACROBLOCKD *const xd = &x->e_mbd;
8200 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008201#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008202 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008203#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008204 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
8205 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
8206 int dc_mode_index;
8207 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8208 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
8209 TX_SIZE uv_tx;
8210
8211 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008212 if (av1_mode_order[i].mode == DC_PRED &&
8213 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008214 break;
8215 dc_mode_index = i;
8216 assert(i < MAX_MODES);
8217
8218 // TODO(huisu): use skip_mask for further speedup.
8219 (void)skip_mask;
8220 mbmi->mode = DC_PRED;
8221 mbmi->uv_mode = DC_PRED;
8222 mbmi->ref_frame[0] = INTRA_FRAME;
8223 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07008224 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8225 &skippable, bsize, intra_mode_cost[mbmi->mode],
8226 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008227 return;
hui su5db97432016-10-14 16:10:14 -07008228 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008229 if (rate_y == INT_MAX) return;
8230
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008231 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
8232 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008233 if (rate_uv_intra[uv_tx] == INT_MAX) {
8234 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
8235 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
8236 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008237#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008238 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008239#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008240 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8241#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008242 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07008243#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008244 }
8245
8246 rate_uv = rate_uv_tokenonly[uv_tx];
8247 distortion_uv = dist_uv[uv_tx];
8248 skippable = skippable && skip_uv[uv_tx];
8249 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008250#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008251 if (cm->allow_screen_content_tools) {
8252 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8253 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8254 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8255 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8256 }
Urvang Joshib100db72016-10-12 16:28:56 -07008257#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008258#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008259 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07008260#endif // CONFIG_EXT_INTRA
8261 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8262 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8263 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8264 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8265 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008266 }
8267
8268 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8269 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008270#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008271 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008272 rate2 += av1_cost_bit(
8273 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008274#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008275
8276 if (!xd->lossless[mbmi->segment_id]) {
8277 // super_block_yrd above includes the cost of the tx_size in the
8278 // tokenonly rate, but for intra blocks, tx_size is always coded
8279 // (prediction granularity), so we account for it in the full rate,
8280 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008281 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07008282 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008283 }
8284
hui su5db97432016-10-14 16:10:14 -07008285 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8286 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8287 rate2 += write_uniform_cost(
8288 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8289#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008290 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8291 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8292 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8293 }
hui su5db97432016-10-14 16:10:14 -07008294#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008295 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008296 rate2 +=
8297 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8298 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8299 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8300 rate2 +=
8301 write_uniform_cost(FILTER_INTRA_MODES,
8302 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008303 }
8304 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008305 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008306#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008307 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008308 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008309 cpi, &xd->plane[0].dst, bsize, xd->bd);
8310 } else {
8311 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008312 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008313 }
8314#else
8315 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008316 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8317#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008318
8319 rate2 += ref_costs_single[INTRA_FRAME];
8320
8321 if (skippable) {
8322 rate2 -= (rate_y + rate_uv);
8323 rate_y = 0;
8324 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008325 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008326 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008327 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008328 }
8329 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008330
8331 if (this_rd < *best_intra_rd) {
8332 *best_intra_rd = this_rd;
8333 *best_intra_mode = mbmi->mode;
8334 }
8335 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008336 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008337
8338 if (this_rd < *best_rd) {
8339 *best_mode_index = dc_mode_index;
8340 mbmi->mv[0].as_int = 0;
8341 rd_cost->rate = rate2;
8342#if CONFIG_SUPERTX
8343 if (x->skip)
8344 *returnrate_nocoef = rate2;
8345 else
8346 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008347 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8348 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8349 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008350#endif // CONFIG_SUPERTX
8351 rd_cost->dist = distortion2;
8352 rd_cost->rdcost = this_rd;
8353 *best_rd = this_rd;
8354 *best_mbmode = *mbmi;
8355 *best_skip2 = 0;
8356 *best_mode_skippable = skippable;
8357 }
8358}
hui su5db97432016-10-14 16:10:14 -07008359#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008360
Yue Chencb60b182016-10-13 15:18:22 -07008361#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008362static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8363 const MACROBLOCKD *xd, int mi_row,
8364 int mi_col, const uint8_t *above,
8365 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008366 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008367#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008368
Urvang Joshi52648442016-10-13 17:27:51 -07008369void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008370 MACROBLOCK *x, int mi_row, int mi_col,
8371 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008372#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008373 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008374#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008375 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8376 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008377 const AV1_COMMON *const cm = &cpi->common;
8378 const RD_OPT *const rd_opt = &cpi->rd;
8379 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 MACROBLOCKD *const xd = &x->e_mbd;
8381 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008382#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008383 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008384#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008385 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8386 const struct segmentation *const seg = &cm->seg;
8387 PREDICTION_MODE this_mode;
8388 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8389 unsigned char segment_id = mbmi->segment_id;
8390 int comp_pred, i, k;
8391 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8392 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8393#if CONFIG_EXT_INTER
8394 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8395 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8396 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8397#else
8398 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8399#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008400 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008401 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8402 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8403 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008404 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008405#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008406 AOM_LAST2_FLAG,
8407 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008408#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008409 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008410#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008411 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008412#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008413 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008414 };
8415 int64_t best_rd = best_rd_so_far;
8416 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8417 int64_t best_pred_diff[REFERENCE_MODES];
8418 int64_t best_pred_rd[REFERENCE_MODES];
8419 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008420#if CONFIG_REF_MV
8421 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8422 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8423#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008424 int best_mode_skippable = 0;
8425 int midx, best_mode_index = -1;
8426 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8427 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008428 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008429 int64_t best_intra_rd = INT64_MAX;
8430 unsigned int best_pred_sse = UINT_MAX;
8431 PREDICTION_MODE best_intra_mode = DC_PRED;
8432 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008433 int64_t dist_uvs[TX_SIZES];
8434 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008435 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008436#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008437 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008438#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008439#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008440 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008441 int is_directional_mode, angle_stats_ready = 0;
8442 int rate_overhead, rate_dummy;
8443 uint8_t directional_mode_skip_mask[INTRA_MODES];
8444#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008445#if CONFIG_FILTER_INTRA
8446 int8_t dc_skipped = 1;
8447 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8448#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008449 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008450 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8451 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8452 int best_skip2 = 0;
8453 uint8_t ref_frame_skip_mask[2] = { 0 };
8454#if CONFIG_EXT_INTER
8455 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8456 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8457 int64_t best_single_inter_rd = INT64_MAX;
8458#else
8459 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8460#endif // CONFIG_EXT_INTER
8461 int mode_skip_start = sf->mode_skip_start + 1;
8462 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8463 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8464 int64_t mode_threshold[MAX_MODES];
8465 int *mode_map = tile_data->mode_map[bsize];
8466 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8467 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07008468#if CONFIG_PVQ
8469 od_rollback_buffer pre_buf;
8470#endif
8471
Urvang Joshib100db72016-10-12 16:28:56 -07008472#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008473 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
8474 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008475#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8476#if CONFIG_PALETTE
8477 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008478 const MODE_INFO *above_mi = xd->above_mi;
8479 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008480#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008481#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008482#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008483 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8484 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8485#else
8486 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8487 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008488#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008489 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8490 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8491 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8492 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8493 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8494 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8495 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8496 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8497 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8498
Yaowu Xuf883b422016-08-30 14:01:10 -07008499#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008500 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8501 int len = sizeof(uint16_t);
8502 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8503 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8504 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8505 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8506 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8507 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8508 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008509#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008510 dst_buf1[0] = tmp_buf1;
8511 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8512 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8513 dst_buf2[0] = tmp_buf2;
8514 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8515 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008516#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008517 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008518#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008519#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008520
Yaowu Xuf883b422016-08-30 14:01:10 -07008521 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008522
Urvang Joshib100db72016-10-12 16:28:56 -07008523#if CONFIG_PALETTE
8524 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008525 if (cm->allow_screen_content_tools) {
8526 if (above_mi)
8527 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8528 if (left_mi)
8529 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8530 }
Urvang Joshib100db72016-10-12 16:28:56 -07008531#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008532
8533#if CONFIG_EXT_INTRA
8534 memset(directional_mode_skip_mask, 0,
8535 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8536#endif // CONFIG_EXT_INTRA
8537
8538 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8539 &comp_mode_p);
8540
8541 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8542 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8543 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8544 for (i = 0; i < MB_MODE_COUNT; ++i) {
8545 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8546 single_inter_filter[i][k] = SWITCHABLE;
8547 single_skippable[i][k] = 0;
8548 }
8549 }
8550
8551 rd_cost->rate = INT_MAX;
8552#if CONFIG_SUPERTX
8553 *returnrate_nocoef = INT_MAX;
8554#endif // CONFIG_SUPERTX
8555
8556 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8557 x->pred_mv_sad[ref_frame] = INT_MAX;
8558 x->mbmi_ext->mode_context[ref_frame] = 0;
8559#if CONFIG_REF_MV && CONFIG_EXT_INTER
8560 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8561#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8562 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8563 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8564 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8565 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8566 }
8567 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008568#if CONFIG_GLOBAL_MOTION
8569 frame_mv[ZEROMV][ref_frame].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07008570 gm_get_motion_vector(&cm->global_motion[ref_frame]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008571#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008572 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008573#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008574#if CONFIG_EXT_INTER
8575 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8576 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8577 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8578#endif // CONFIG_EXT_INTER
8579 }
8580
8581#if CONFIG_REF_MV
8582 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8583 MODE_INFO *const mi = xd->mi[0];
8584 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8585 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008586 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8587 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008588#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008589 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008590#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008591 candidates, mi_row, mi_col, NULL, NULL,
8592 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08008593 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
8594 MV_REFERENCE_FRAME rf[2];
8595 av1_set_ref_frame(rf, ref_frame);
8596 if (mbmi_ext->ref_mvs[rf[0]][0].as_int != 0 ||
8597 mbmi_ext->ref_mvs[rf[0]][1].as_int != 0 ||
8598 mbmi_ext->ref_mvs[rf[1]][0].as_int != 0 ||
8599 mbmi_ext->ref_mvs[rf[1]][1].as_int != 0)
8600 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
8601 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008602 }
8603#endif // CONFIG_REF_MV
8604
Yue Chencb60b182016-10-13 15:18:22 -07008605#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008606 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8607 dst_width1, dst_height1, dst_stride1);
8608 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8609 dst_width2, dst_height2, dst_stride2);
8610 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008611 x->mask_buf = mask2d_buf;
8612 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008613 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008614 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008615#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008616
8617 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8618 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8619// Skip checking missing references in both single and compound reference
8620// modes. Note that a mode will be skipped iff both reference frames
8621// are masked out.
8622#if CONFIG_EXT_REFS
8623 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8624 ref_frame_skip_mask[0] |= (1 << ref_frame);
8625 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8626 } else {
8627#endif // CONFIG_EXT_REFS
8628 ref_frame_skip_mask[0] |= (1 << ref_frame);
8629 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8630#if CONFIG_EXT_REFS
8631 }
8632#endif // CONFIG_EXT_REFS
8633 } else {
8634 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8635 // Skip fixed mv modes for poor references
8636 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8637 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8638 break;
8639 }
8640 }
8641 }
8642 // If the segment reference frame feature is enabled....
8643 // then do nothing if the current ref frame is not allowed..
8644 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8645 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8646 ref_frame_skip_mask[0] |= (1 << ref_frame);
8647 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8648 }
8649 }
8650
8651 // Disable this drop out case if the ref frame
8652 // segment level feature is enabled for this segment. This is to
8653 // prevent the possibility that we end up unable to pick any mode.
8654 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8655 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8656 // unless ARNR filtering is enabled in which case we want
8657 // an unfiltered alternative. We allow near/nearest as well
8658 // because they may result in zero-zero MVs but be cheaper.
8659 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008660 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008661 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8662#if CONFIG_EXT_REFS
8663 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8664 (1 << BWDREF_FRAME) |
8665#endif // CONFIG_EXT_REFS
8666 (1 << GOLDEN_FRAME);
8667 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8668 // TODO(zoeliu): To further explore whether following needs to be done for
8669 // BWDREF_FRAME as well.
8670 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008671#if CONFIG_GLOBAL_MOTION
8672 zeromv.as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07008673 gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008674#else
8675 zeromv.as_int = 0;
8676#endif // CONFIG_GLOBAL_MOTION
8677 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008678 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008679 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008680 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8681#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008682 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008683 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008684 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008685 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008686 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008687 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008688 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008689 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8690#endif // CONFIG_EXT_INTER
8691 }
8692 }
8693
8694 if (cpi->rc.is_src_frame_alt_ref) {
8695 if (sf->alt_ref_search_fp) {
8696 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8697 mode_skip_mask[ALTREF_FRAME] = 0;
8698 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8699 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8700 }
8701 }
8702
8703 if (sf->alt_ref_search_fp)
8704 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8705 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8706 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8707
8708 if (sf->adaptive_mode_search) {
8709 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8710 cpi->rc.frames_since_golden >= 3)
8711 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8712 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8713 }
8714
8715 if (bsize > sf->max_intra_bsize) {
8716 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8717 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8718 }
8719
8720 mode_skip_mask[INTRA_FRAME] |=
8721 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8722
8723 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8724 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8725 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8726
8727 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8728 while (midx > 4) {
8729 uint8_t end_pos = 0;
8730 for (i = 5; i < midx; ++i) {
8731 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8732 uint8_t tmp = mode_map[i];
8733 mode_map[i] = mode_map[i - 1];
8734 mode_map[i - 1] = tmp;
8735 end_pos = i;
8736 }
8737 }
8738 midx = end_pos;
8739 }
8740
8741 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8742 x->use_default_intra_tx_type = 1;
8743 else
8744 x->use_default_intra_tx_type = 0;
8745
8746 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8747 x->use_default_inter_tx_type = 1;
8748 else
8749 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07008750#if CONFIG_PVQ
8751 od_encode_checkpoint(&x->daala_enc, &pre_buf);
8752#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008753#if CONFIG_EXT_INTER
8754 for (i = 0; i < MB_MODE_COUNT; ++i)
8755 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8756 modelled_rd[i][ref_frame] = INT64_MAX;
8757#endif // CONFIG_EXT_INTER
8758
8759 for (midx = 0; midx < MAX_MODES; ++midx) {
8760 int mode_index;
8761 int mode_excluded = 0;
8762 int64_t this_rd = INT64_MAX;
8763 int disable_skip = 0;
8764 int compmode_cost = 0;
8765#if CONFIG_EXT_INTER
8766 int compmode_interintra_cost = 0;
8767 int compmode_wedge_cost = 0;
8768#endif // CONFIG_EXT_INTER
8769 int rate2 = 0, rate_y = 0, rate_uv = 0;
8770 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8771 int skippable = 0;
8772 int this_skip2 = 0;
8773 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008774#if CONFIG_REF_MV
8775 uint8_t ref_frame_type;
8776#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07008777#if CONFIG_PVQ
8778 od_encode_rollback(&x->daala_enc, &pre_buf);
8779#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008780 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008781 this_mode = av1_mode_order[mode_index].mode;
8782 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8783 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008784#if CONFIG_REF_MV
8785 mbmi->ref_mv_idx = 0;
8786#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008787
8788#if CONFIG_EXT_INTER
8789 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8790 // Mode must by compatible
8791 assert(is_interintra_allowed_mode(this_mode));
8792
8793 if (!is_interintra_allowed_bsize(bsize)) continue;
8794 }
8795
8796 if (is_inter_compound_mode(this_mode)) {
8797 frame_mv[this_mode][ref_frame].as_int =
8798 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8799 frame_mv[this_mode][second_ref_frame].as_int =
8800 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8801 }
8802#endif // CONFIG_EXT_INTER
8803
8804 // Look at the reference frame of the best mode so far and set the
8805 // skip mask to look at a subset of the remaining modes.
8806 if (midx == mode_skip_start && best_mode_index >= 0) {
8807 switch (best_mbmode.ref_frame[0]) {
8808 case INTRA_FRAME: break;
8809 case LAST_FRAME:
8810 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8811 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8812 break;
8813#if CONFIG_EXT_REFS
8814 case LAST2_FRAME:
8815 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8816 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8817 break;
8818 case LAST3_FRAME:
8819 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8820 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8821 break;
8822#endif // CONFIG_EXT_REFS
8823 case GOLDEN_FRAME:
8824 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8825 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8826 break;
8827#if CONFIG_EXT_REFS
8828 case BWDREF_FRAME:
8829 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8830 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8831 break;
8832#endif // CONFIG_EXT_REFS
8833 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8834#if CONFIG_EXT_REFS
8835 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8836#endif // CONFIG_EXT_REFS
8837 break;
8838 case NONE:
8839 case TOTAL_REFS_PER_FRAME:
8840 assert(0 && "Invalid Reference frame");
8841 break;
8842 }
8843 }
8844
8845 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008846 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008847 continue;
8848
8849 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
8850
8851 // Test best rd so far against threshold for trying this mode.
8852 if (best_mode_skippable && sf->schedule_mode_search)
8853 mode_threshold[mode_index] <<= 1;
8854
8855 if (best_rd < mode_threshold[mode_index]) continue;
8856
8857 comp_pred = second_ref_frame > INTRA_FRAME;
8858 if (comp_pred) {
8859 if (!cpi->allow_comp_inter_inter) continue;
8860
8861 // Skip compound inter modes if ARF is not available.
8862 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
8863
8864 // Do not allow compound prediction if the segment level reference frame
8865 // feature is in use as in this case there can only be one reference.
8866 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
8867
8868 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8869 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
8870 continue;
8871
8872 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8873 } else {
8874 if (ref_frame != INTRA_FRAME)
8875 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8876 }
8877
8878 if (ref_frame == INTRA_FRAME) {
8879 if (sf->adaptive_mode_search)
8880 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
8881 continue;
8882
8883 if (this_mode != DC_PRED) {
8884 // Disable intra modes other than DC_PRED for blocks with low variance
8885 // Threshold for intra skipping based on source variance
8886 // TODO(debargha): Specialize the threshold for super block sizes
8887 const unsigned int skip_intra_var_thresh = 64;
8888 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
8889 x->source_variance < skip_intra_var_thresh)
8890 continue;
8891 // Only search the oblique modes if the best so far is
8892 // one of the neighboring directional modes
8893 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
8894 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
8895 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
8896 continue;
8897 }
8898 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
8899 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
8900 }
8901 }
Sarah Parkere5299862016-08-16 14:57:37 -07008902#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00008903 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07008904 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00008905 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008906#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008907 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07008908#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008909 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
8910 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
8911#if CONFIG_REF_MV && CONFIG_EXT_INTER
8912 mbmi_ext->compound_mode_context,
8913#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8914 frame_mv, this_mode, ref_frames, bsize, -1))
8915 continue;
8916 }
8917
8918 mbmi->mode = this_mode;
8919 mbmi->uv_mode = DC_PRED;
8920 mbmi->ref_frame[0] = ref_frame;
8921 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07008922#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008923 pmi->palette_size[0] = 0;
8924 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07008925#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008926#if CONFIG_FILTER_INTRA
8927 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8928 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8929#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008930 // Evaluate all sub-pel filters irrespective of whether we can use
8931 // them for this frame.
8932#if CONFIG_DUAL_FILTER
8933 for (i = 0; i < 4; ++i) {
8934 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
8935 ? EIGHTTAP_REGULAR
8936 : cm->interp_filter;
8937 }
8938#else
8939 mbmi->interp_filter =
8940 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
8941#endif
8942 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008943 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008944
8945 x->skip = 0;
8946 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
8947
8948 // Select prediction reference frames.
8949 for (i = 0; i < MAX_MB_PLANE; i++) {
8950 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
8951 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
8952 }
8953
8954#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008955 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008956#endif // CONFIG_EXT_INTER
8957
8958 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008959 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008960 TX_SIZE uv_tx;
8961 struct macroblockd_plane *const pd = &xd->plane[1];
8962#if CONFIG_EXT_INTRA
8963 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
8964 if (is_directional_mode) {
8965 if (!angle_stats_ready) {
8966 const int src_stride = x->plane[0].src.stride;
8967 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07008968#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008969 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8970 highbd_angle_estimation(src, src_stride, rows, cols,
8971 directional_mode_skip_mask);
8972 else
8973#endif
8974 angle_estimation(src, src_stride, rows, cols,
8975 directional_mode_skip_mask);
8976 angle_stats_ready = 1;
8977 }
8978 if (directional_mode_skip_mask[mbmi->mode]) continue;
8979 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
8980 intra_mode_cost[mbmi->mode];
8981 rate_y = INT_MAX;
8982 this_rd =
8983 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8984 &skippable, bsize, rate_overhead, best_rd);
8985 } else {
8986 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008987 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
8988 rate_y = rd_stats_y.rate;
8989 distortion_y = rd_stats_y.dist;
8990 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008991 }
8992#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008993 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
8994 rate_y = rd_stats_y.rate;
8995 distortion_y = rd_stats_y.dist;
8996 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008997#endif // CONFIG_EXT_INTRA
8998
8999 if (rate_y == INT_MAX) continue;
9000
hui su5db97432016-10-14 16:10:14 -07009001#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009002 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07009003#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009004
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009005 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
9006 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009007 if (rate_uv_intra[uv_tx] == INT_MAX) {
9008 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009009 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9010 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009011#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009012 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009013#endif // CONFIG_PALETTE
9014
Yaowu Xuc27fc142016-08-22 16:08:15 -07009015#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009016 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9017#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009018#if CONFIG_FILTER_INTRA
9019 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9020#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009021 }
9022
9023 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07009024 distortion_uv = dist_uvs[uv_tx];
9025 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009026 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009027#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009028 if (cm->allow_screen_content_tools) {
9029 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9030 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9031 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9032 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9033 }
Urvang Joshib100db72016-10-12 16:28:56 -07009034#endif // CONFIG_PALETTE
9035
Yaowu Xuc27fc142016-08-22 16:08:15 -07009036#if CONFIG_EXT_INTRA
9037 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009038#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009039#if CONFIG_FILTER_INTRA
9040 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9041 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9042 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9043 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9044 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9045 }
9046#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009047
9048 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9049 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009050#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009051 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009052 rate2 += av1_cost_bit(
9053 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009054#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009055
9056 if (!xd->lossless[mbmi->segment_id]) {
9057 // super_block_yrd above includes the cost of the tx_size in the
9058 // tokenonly rate, but for intra blocks, tx_size is always coded
9059 // (prediction granularity), so we account for it in the full rate,
9060 // not the tokenonly rate.
Jingning Hanb0a71302016-10-25 16:28:49 -07009061 rate_y -=
9062 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
9063 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009064 }
9065#if CONFIG_EXT_INTRA
9066 if (is_directional_mode) {
9067 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07009068 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009069 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9070 MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
9071 p_angle =
9072 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07009073 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009074 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
9075 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009076 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
9077 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9078 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
9079 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009080#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009081#if CONFIG_FILTER_INTRA
9082 if (mbmi->mode == DC_PRED) {
9083 rate2 +=
9084 av1_cost_bit(cm->fc->filter_intra_probs[0],
9085 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9086 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
9087 rate2 += write_uniform_cost(
9088 FILTER_INTRA_MODES,
9089 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9090 }
9091 }
9092 if (mbmi->uv_mode == DC_PRED) {
9093 rate2 +=
9094 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9095 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9096 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9097 rate2 += write_uniform_cost(
9098 FILTER_INTRA_MODES,
9099 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
9100 }
9101#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009102 if (this_mode != DC_PRED && this_mode != TM_PRED)
9103 rate2 += intra_cost_penalty;
9104 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07009105 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07009106#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009107 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009108 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009109 cpi, &xd->plane[0].dst, bsize, xd->bd);
9110 } else {
9111 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009112 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009113 }
9114#else
9115 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009116 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
9117#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009118 } else {
9119#if CONFIG_REF_MV
9120 int_mv backup_ref_mv[2];
9121
9122 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
9123 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
9124#endif
9125#if CONFIG_EXT_INTER
9126 if (second_ref_frame == INTRA_FRAME) {
9127 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009128 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07009129// TODO(debargha|geza.lore):
9130// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07009131#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009132 mbmi->angle_delta[0] = 0;
9133 mbmi->angle_delta[1] = 0;
9134 mbmi->intra_filter = INTRA_FILTER_LINEAR;
9135#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009136#if CONFIG_FILTER_INTRA
9137 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9138 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9139#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009140 }
9141#endif // CONFIG_EXT_INTER
9142#if CONFIG_REF_MV
9143 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009144 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009145
9146 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
9147 int ref;
9148 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9149 int_mv this_mv =
9150 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
9151 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
9152 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9153 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9154 }
9155 }
9156#endif
Angie Chiang76159122016-11-09 12:13:22 -08009157 {
9158 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
9159 av1_init_rd_stats(&rd_stats);
9160 rd_stats.rate = rate2;
9161 this_rd = handle_inter_mode(
9162 cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &disable_skip,
9163 frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009164#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009165 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009166#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009167#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009168 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
9169 &compmode_wedge_cost, modelled_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009170#else
Angie Chiang76159122016-11-09 12:13:22 -08009171 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009172#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009173 single_inter_filter, single_skippable, best_rd);
9174
9175 rate2 = rd_stats.rate;
9176 skippable = rd_stats.skip;
9177 distortion2 = rd_stats.dist;
9178 total_sse = rd_stats.sse;
9179 rate_y = rd_stats_y.rate;
9180 rate_uv = rd_stats_uv.rate;
9181 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009182
9183#if CONFIG_REF_MV
9184 // TODO(jingning): This needs some refactoring to improve code quality
9185 // and reduce redundant steps.
9186 if ((mbmi->mode == NEARMV &&
9187 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9188 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
9189 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
9190 MB_MODE_INFO backup_mbmi = *mbmi;
9191 int backup_skip = x->skip;
9192 int64_t tmp_ref_rd = this_rd;
9193 int ref_idx;
9194
9195 // TODO(jingning): This should be deprecated shortly.
9196 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
9197 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07009198 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009199
9200 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009201 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009202 // Dummy
9203 int_mv backup_fmv[2];
9204 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
9205 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
9206
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07009207 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009208
9209 if (this_rd < INT64_MAX) {
9210 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9211 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
9212 tmp_ref_rd =
9213 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009214 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07009215 distortion2);
9216 else
9217 tmp_ref_rd =
9218 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009219 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07009220 rate_y - rate_uv,
9221 total_sse);
9222 }
9223#if CONFIG_VAR_TX
9224 for (i = 0; i < MAX_MB_PLANE; ++i)
9225 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9226 sizeof(uint8_t) * ctx->num_4x4_blk);
9227#endif
9228
9229 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
9230 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009231 int dummy_disable_skip = 0;
9232 int ref;
9233 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009234 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009235
9236 mbmi->ref_mv_idx = 1 + ref_idx;
9237
9238 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9239 int_mv this_mv =
9240 (ref == 0)
9241 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9242 .this_mv
9243 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9244 .comp_mv;
9245 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9246 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9247 }
9248
9249 cur_mv =
9250 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
9251 .this_mv;
9252 clamp_mv2(&cur_mv.as_mv, xd);
9253
9254 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07009255 int dummy_single_skippable[MB_MODE_COUNT]
9256 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009257#if CONFIG_EXT_INTER
9258 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
9259 { { 0 } } };
9260 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
9261 { 0 } };
9262 int dummy_compmode_interintra_cost = 0;
9263 int dummy_compmode_wedge_cost = 0;
9264#else
9265 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9266#endif
9267
9268 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009269 av1_init_rd_stats(&tmp_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009270 tmp_alt_rd = handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08009271 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
9272 &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009273#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07009274 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009275#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009276#if CONFIG_EXT_INTER
9277 dummy_single_newmvs, dummy_single_newmvs_rate,
9278 &dummy_compmode_interintra_cost, &dummy_compmode_wedge_cost,
9279 NULL,
9280#else
9281 dummy_single_newmv,
9282#endif
Angie Chiang76159122016-11-09 12:13:22 -08009283 single_inter_filter, dummy_single_skippable, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009284 }
9285
9286 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
9287 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009288 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9289 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009290 tmp_rd_stats.rate +=
9291 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
9292 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009293 }
9294
9295 if (mbmi_ext->ref_mv_count[ref_frame_type] >
9296 mbmi->ref_mv_idx + idx_offset + 1 &&
9297 ref_idx < ref_set - 1) {
9298 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009299 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9300 mbmi->ref_mv_idx + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009301 tmp_rd_stats.rate += cpi->drl_mode_cost0[drl1_ctx][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009302 }
9303
9304 if (tmp_alt_rd < INT64_MAX) {
Yue Chencb60b182016-10-13 15:18:22 -07009305#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009306 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
9307 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009308#else
Angie Chiang76159122016-11-09 12:13:22 -08009309 if (RDCOST(x->rdmult, x->rddiv,
9310 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
9311 tmp_rd_stats.dist) <
9312 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009313 tmp_alt_rd =
9314 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009315 tmp_rd_stats.rate +
9316 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9317 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009318 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009319 tmp_alt_rd =
9320 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009321 tmp_rd_stats.rate +
9322 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9323 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
9324 tmp_rd_stats.sse);
Yue Chencb60b182016-10-13 15:18:22 -07009325#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009326 }
9327
9328 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -08009329 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009330 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -08009331 distortion2 = tmp_rd_stats.dist;
9332 skippable = tmp_rd_stats.skip;
9333 rate_y = tmp_rd_stats_y.rate;
9334 rate_uv = tmp_rd_stats_uv.rate;
9335 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009336 this_rd = tmp_alt_rd;
9337 tmp_ref_rd = tmp_alt_rd;
9338 backup_mbmi = *mbmi;
9339 backup_skip = x->skip;
9340#if CONFIG_VAR_TX
9341 for (i = 0; i < MAX_MB_PLANE; ++i)
9342 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9343 sizeof(uint8_t) * ctx->num_4x4_blk);
9344#endif
9345 } else {
9346 *mbmi = backup_mbmi;
9347 x->skip = backup_skip;
9348 }
9349 }
9350
9351 frame_mv[NEARMV][ref_frame] = backup_mv;
9352 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9353 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9354#if CONFIG_VAR_TX
9355 for (i = 0; i < MAX_MB_PLANE; ++i)
9356 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9357 sizeof(uint8_t) * ctx->num_4x4_blk);
9358#endif
9359 }
9360 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9361 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9362#endif // CONFIG_REF_MV
9363
9364 if (this_rd == INT64_MAX) continue;
9365
Yaowu Xuf883b422016-08-30 14:01:10 -07009366 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009367
9368 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9369 }
9370
9371#if CONFIG_EXT_INTER
9372 rate2 += compmode_interintra_cost;
9373 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009374#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9375 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9376#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009377 rate2 += compmode_wedge_cost;
9378#endif // CONFIG_EXT_INTER
9379
9380 // Estimate the reference frame signaling cost and add it
9381 // to the rolling cost variable.
9382 if (comp_pred) {
9383 rate2 += ref_costs_comp[ref_frame];
9384#if CONFIG_EXT_REFS
9385 rate2 += ref_costs_comp[second_ref_frame];
9386#endif // CONFIG_EXT_REFS
9387 } else {
9388 rate2 += ref_costs_single[ref_frame];
9389 }
9390
Yue Chencb60b182016-10-13 15:18:22 -07009391#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009392 if (ref_frame == INTRA_FRAME) {
9393#else
9394 if (!disable_skip) {
Yue Chencb60b182016-10-13 15:18:22 -07009395#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009396 if (skippable) {
9397 // Back out the coefficient coding costs
9398 rate2 -= (rate_y + rate_uv);
9399 rate_y = 0;
9400 rate_uv = 0;
9401 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009402 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009403 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009404#if CONFIG_REF_MV
9405 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9406 distortion2) <
9407 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9408#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009409 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9410 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009411#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009412 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009413 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414 } else {
9415 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009416 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009417 distortion2 = total_sse;
9418 assert(total_sse >= 0);
9419 rate2 -= (rate_y + rate_uv);
9420 this_skip2 = 1;
9421 rate_y = 0;
9422 rate_uv = 0;
9423 }
9424 } else {
9425 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009426 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009427 }
9428
9429 // Calculate the final RD estimate for this mode.
9430 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chencb60b182016-10-13 15:18:22 -07009431#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009432 } else {
9433 this_skip2 = mbmi->skip;
9434 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9435 if (this_skip2) {
9436 rate_y = 0;
9437 rate_uv = 0;
9438 }
Yue Chencb60b182016-10-13 15:18:22 -07009439#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009440 }
9441
Yaowu Xuc27fc142016-08-22 16:08:15 -07009442 if (ref_frame == INTRA_FRAME) {
9443 // Keep record of best intra rd
9444 if (this_rd < best_intra_rd) {
9445 best_intra_rd = this_rd;
9446 best_intra_mode = mbmi->mode;
9447 }
9448#if CONFIG_EXT_INTER
9449 } else if (second_ref_frame == NONE) {
9450 if (this_rd < best_single_inter_rd) {
9451 best_single_inter_rd = this_rd;
9452 best_single_inter_ref = mbmi->ref_frame[0];
9453 }
9454#endif // CONFIG_EXT_INTER
9455 }
9456
9457 if (!disable_skip && ref_frame == INTRA_FRAME) {
9458 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009459 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009460 }
9461
9462 // Did this mode help.. i.e. is it the new best mode
9463 if (this_rd < best_rd || x->skip) {
9464 if (!mode_excluded) {
9465 // Note index of best mode so far
9466 best_mode_index = mode_index;
9467
9468 if (ref_frame == INTRA_FRAME) {
9469 /* required for left and above block mv */
9470 mbmi->mv[0].as_int = 0;
9471 } else {
9472 best_pred_sse = x->pred_sse[ref_frame];
9473 }
9474
9475 rd_cost->rate = rate2;
9476#if CONFIG_SUPERTX
9477 if (x->skip)
9478 *returnrate_nocoef = rate2;
9479 else
9480 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009481 *returnrate_nocoef -= av1_cost_bit(
9482 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9483 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9484 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009485#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9486 if (is_inter_block(mbmi) && is_motion_variation_allowed(mbmi))
9487 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
9488#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009489#endif // CONFIG_SUPERTX
9490 rd_cost->dist = distortion2;
9491 rd_cost->rdcost = this_rd;
9492 best_rd = this_rd;
9493 best_mbmode = *mbmi;
9494 best_skip2 = this_skip2;
9495 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009496 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9497 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009498 best_rate_uv = rate_uv;
9499
9500#if CONFIG_VAR_TX
9501 for (i = 0; i < MAX_MB_PLANE; ++i)
9502 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9503 sizeof(uint8_t) * ctx->num_4x4_blk);
9504#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009505 }
9506 }
9507
9508 /* keep record of best compound/single-only prediction */
9509 if (!disable_skip && ref_frame != INTRA_FRAME) {
9510 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9511
9512 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9513 single_rate = rate2 - compmode_cost;
9514 hybrid_rate = rate2;
9515 } else {
9516 single_rate = rate2;
9517 hybrid_rate = rate2 + compmode_cost;
9518 }
9519
9520 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9521 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9522
9523 if (!comp_pred) {
9524 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9525 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9526 } else {
9527 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9528 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9529 }
9530 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9531 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9532 }
9533
Yaowu Xuc27fc142016-08-22 16:08:15 -07009534 if (x->skip && !comp_pred) break;
9535 }
9536
9537 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9538 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9539 is_inter_mode(best_mbmode.mode)) ||
9540 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9541 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009542 int skip_blk = 0;
9543 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009544
9545 x->use_default_inter_tx_type = 0;
9546 x->use_default_intra_tx_type = 0;
9547
9548 *mbmi = best_mbmode;
9549
9550 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9551
9552 // Select prediction reference frames.
9553 for (i = 0; i < MAX_MB_PLANE; i++) {
9554 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9555 if (has_second_ref(mbmi))
9556 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9557 }
9558
9559 if (is_inter_mode(mbmi->mode)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009560 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yue Chencb60b182016-10-13 15:18:22 -07009561#if CONFIG_MOTION_VAR
9562 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009563 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9564 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009565#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009566 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009567#if CONFIG_VAR_TX
9568 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07009569 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009570 } else {
9571 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009572 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009573 for (idy = 0; idy < xd->n8_h; ++idy)
9574 for (idx = 0; idx < xd->n8_w; ++idx)
9575 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009576 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009577 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9578 }
9579
Angie Chiangb5dda482016-11-02 16:19:58 -07009580 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009581#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009582 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009583 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009584#endif // CONFIG_VAR_TX
9585 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009586 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009587 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009588 }
9589
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009590 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9591 (rd_stats_y.dist + rd_stats_uv.dist)) >
9592 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009593 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009594 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9595 rd_stats_uv.rate = 0;
9596 rd_stats_y.dist = rd_stats_y.sse;
9597 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009598 } else {
9599 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009600 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009601 }
9602
9603 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009604 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9605 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009606#if CONFIG_VAR_TX
9607 int idx, idy;
9608#endif
9609 best_mbmode.tx_type = mbmi->tx_type;
9610 best_mbmode.tx_size = mbmi->tx_size;
9611#if CONFIG_VAR_TX
9612 for (idy = 0; idy < xd->n8_h; ++idy)
9613 for (idx = 0; idx < xd->n8_w; ++idx)
9614 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9615
9616 for (i = 0; i < MAX_MB_PLANE; ++i)
9617 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9618 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07009619
9620 best_mbmode.min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009621#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009622 rd_cost->rate +=
9623 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
9624 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009625 rd_cost->rdcost =
9626 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9627 best_skip2 = skip_blk;
9628 }
9629 }
9630
Urvang Joshib100db72016-10-12 16:28:56 -07009631#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009632 // Only try palette mode when the best mode so far is an intra mode.
9633 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9634 PREDICTION_MODE mode_selected;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009635 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009636#if CONFIG_SUPERTX
9637 int best_rate_nocoef;
9638#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009639 int64_t distortion2 = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009640 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009641 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009642 TX_SIZE best_tx_size, uv_tx;
9643 TX_TYPE best_tx_type;
9644 PALETTE_MODE_INFO palette_mode_info;
9645 uint8_t *const best_palette_color_map =
9646 x->palette_buffer->best_palette_color_map;
9647 uint8_t *const color_map = xd->plane[0].color_index_map;
9648
9649 mbmi->mode = DC_PRED;
9650 mbmi->uv_mode = DC_PRED;
9651 mbmi->ref_frame[0] = INTRA_FRAME;
9652 mbmi->ref_frame[1] = NONE;
9653 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009654 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009655 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9656 &palette_mode_info, best_palette_color_map, &best_tx_size,
9657 &best_tx_type, &mode_selected, &dummy_rd);
9658 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9659
9660 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9661 if (palette_mode_info.palette_size[0] > 0) {
9662 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9663 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9664 memcpy(color_map, best_palette_color_map,
9665 rows * cols * sizeof(best_palette_color_map[0]));
9666 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009667 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9668 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009669 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9670 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009671 if (rate_uv_intra[uv_tx] == INT_MAX) {
9672 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009673 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9674 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009675 pmi_uv[uv_tx] = *pmi;
9676#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009677 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9678#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009679#if CONFIG_FILTER_INTRA
9680 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9681#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009682 }
9683 mbmi->uv_mode = mode_uv[uv_tx];
9684 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9685 if (pmi->palette_size[1] > 0)
9686 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9687 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9688 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9689#if CONFIG_EXT_INTRA
9690 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009691#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009692#if CONFIG_FILTER_INTRA
9693 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9694 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9695 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9696 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9697 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9698 }
9699#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009700 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
9701 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
9702 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009703 rate2 += ref_costs_single[INTRA_FRAME];
9704
9705 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009706 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009707#if CONFIG_SUPERTX
9708 best_rate_nocoef = rate2;
9709#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009710 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009711 } else {
9712#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009713 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009714#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009715 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009716 }
9717 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9718 if (this_rd < best_rd) {
9719 best_mode_index = 3;
9720 mbmi->mv[0].as_int = 0;
9721 rd_cost->rate = rate2;
9722#if CONFIG_SUPERTX
9723 *returnrate_nocoef = best_rate_nocoef;
9724#endif
9725 rd_cost->dist = distortion2;
9726 rd_cost->rdcost = this_rd;
9727 best_rd = this_rd;
9728 best_mbmode = *mbmi;
9729 best_skip2 = 0;
9730 best_mode_skippable = skippable;
9731 }
9732 }
9733PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009734#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009735
hui su5db97432016-10-14 16:10:14 -07009736#if CONFIG_FILTER_INTRA
9737 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009738 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009739 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009740#if CONFIG_PALETTE
9741 mbmi->palette_mode_info.palette_size[0] == 0 &&
9742#endif // CONFIG_PALETTE
9743 !dc_skipped && best_mode_index >= 0 &&
9744 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009745 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009746 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009747 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9748#if CONFIG_EXT_INTRA
9749 uv_angle_delta,
9750#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009751#if CONFIG_PALETTE
9752 pmi_uv, palette_ctx,
9753#endif // CONFIG_PALETTE
9754 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009755 &best_mode_index, &best_skip2, &best_mode_skippable,
9756#if CONFIG_SUPERTX
9757 returnrate_nocoef,
9758#endif // CONFIG_SUPERTX
9759 best_pred_rd, &best_mbmode, rd_cost);
9760 }
hui su5db97432016-10-14 16:10:14 -07009761#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009762
9763 // The inter modes' rate costs are not calculated precisely in some cases.
9764 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9765 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9766 // are corrected.
9767 if (best_mbmode.mode == NEWMV
9768#if CONFIG_EXT_INTER
9769 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9770#endif // CONFIG_EXT_INTER
9771 ) {
9772 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9773 best_mbmode.ref_frame[1] };
9774 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009775 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009776#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009777 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009778#endif // CONFIG_REF_MV
9779#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07009780 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]]).as_int;
Sarah Parker70c4fab2016-11-04 12:35:57 -07009781 zeromv[1].as_int =
9782 comp_pred_mode
Debargha Mukherjee5f305852016-11-03 15:47:21 -07009783 ? gm_get_motion_vector(&cm->global_motion[refs[1]]).as_int
Sarah Parker70c4fab2016-11-04 12:35:57 -07009784 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009785#else
9786 zeromv[0].as_int = 0;
9787 zeromv[1].as_int = 0;
9788#endif // CONFIG_GLOBAL_MOTION
9789#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009790 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009791 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009792 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009793 : INT_MAX;
9794
9795 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9796 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9797 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
9798 best_mbmode.mode = NEARMV;
9799 best_mbmode.ref_mv_idx = i;
9800 }
9801 }
9802
9803 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
9804 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009805 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009806 best_mbmode.mode = ZEROMV;
9807 } else {
9808 int_mv nearestmv[2];
9809 int_mv nearmv[2];
9810
9811#if CONFIG_EXT_INTER
9812 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
9813 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
9814 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
9815 } else {
9816 nearmv[0] = frame_mv[NEARMV][refs[0]];
9817 nearmv[1] = frame_mv[NEARMV][refs[1]];
9818 }
9819#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009820 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009821 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009822 : INT_MAX;
9823
9824 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9825 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9826 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
9827
9828 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9829 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
9830 best_mbmode.mode = NEARMV;
9831 best_mbmode.ref_mv_idx = i;
9832 }
9833 }
9834#endif
9835 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
9836 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
9837 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
9838 } else {
9839 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
9840 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
9841 }
9842
9843 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9844 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9845#if CONFIG_EXT_INTER
9846 best_mbmode.mode = NEAREST_NEARESTMV;
9847 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9848 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9849 best_mbmode.mode = NEAREST_NEARMV;
9850 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9851 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9852 best_mbmode.mode = NEAR_NEARESTMV;
9853 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9854 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9855 best_mbmode.mode = NEAR_NEARMV;
9856 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9857 best_mbmode.mode = ZERO_ZEROMV;
9858#else
9859 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009860 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9861 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009862 best_mbmode.mode = ZEROMV;
9863#endif // CONFIG_EXT_INTER
9864 }
9865#else
9866#if CONFIG_EXT_INTER
9867 if (!comp_pred_mode) {
9868#endif // CONFIG_EXT_INTER
9869 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9870 ((comp_pred_mode &&
9871 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
9872 !comp_pred_mode))
9873 best_mbmode.mode = NEARESTMV;
9874 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9875 ((comp_pred_mode &&
9876 frame_mv[NEARMV][refs[1]].as_int ==
9877 best_mbmode.mv[1].as_int) ||
9878 !comp_pred_mode))
9879 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009880 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9881 ((comp_pred_mode &&
9882 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07009883 !comp_pred_mode))
9884 best_mbmode.mode = ZEROMV;
9885#if CONFIG_EXT_INTER
9886 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009887 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
9888 best_mbmode.mv[0].as_int &&
9889 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
9890 best_mbmode.mv[1].as_int)
9891 best_mbmode.mode = NEAREST_NEARESTMV;
9892 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
9893 best_mbmode.mv[0].as_int &&
9894 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
9895 best_mbmode.mv[1].as_int)
9896 best_mbmode.mode = NEAREST_NEARMV;
9897 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
9898 best_mbmode.mv[0].as_int &&
9899 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
9900 best_mbmode.mv[1].as_int)
9901 best_mbmode.mode = NEAR_NEARESTMV;
9902 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
9903 best_mbmode.mv[0].as_int &&
9904 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
9905 best_mbmode.mv[1].as_int)
9906 best_mbmode.mode = NEAR_NEARMV;
9907 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9908 best_mbmode.mode = ZERO_ZEROMV;
9909 }
9910#endif // CONFIG_EXT_INTER
9911#endif
9912 }
9913
9914#if CONFIG_REF_MV
9915 if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
9916#if CONFIG_EXT_INTER
9917 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
9918#else
9919 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
9920#endif // CONFIG_EXT_INTER
9921 ) {
Jingning Han731af492016-11-17 11:53:23 -08009922 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
9923 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009924#if !CONFIG_EXT_INTER
9925 if (best_mbmode.ref_frame[1] > NONE)
9926 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
9927#endif // !CONFIG_EXT_INTER
9928
9929 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) best_mbmode.mode = ZEROMV;
9930 }
9931#endif
9932
9933 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
9934 rd_cost->rate = INT_MAX;
9935 rd_cost->rdcost = INT64_MAX;
9936 return;
9937 }
9938
Yaowu Xuc27fc142016-08-22 16:08:15 -07009939#if CONFIG_DUAL_FILTER
9940 assert((cm->interp_filter == SWITCHABLE) ||
9941 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
9942 !is_inter_block(&best_mbmode));
9943 assert((cm->interp_filter == SWITCHABLE) ||
9944 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
9945 !is_inter_block(&best_mbmode));
9946 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
9947 assert((cm->interp_filter == SWITCHABLE) ||
9948 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
9949 !is_inter_block(&best_mbmode));
9950 assert((cm->interp_filter == SWITCHABLE) ||
9951 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
9952 !is_inter_block(&best_mbmode));
9953 }
9954#else
9955 assert((cm->interp_filter == SWITCHABLE) ||
9956 (cm->interp_filter == best_mbmode.interp_filter) ||
9957 !is_inter_block(&best_mbmode));
9958#endif
9959
9960 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -07009961 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9962 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009963
9964 // macroblock modes
9965 *mbmi = best_mbmode;
9966 x->skip |= best_skip2;
9967
9968#if CONFIG_REF_MV
9969 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
9970 if (mbmi->mode != NEWMV)
9971 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
9972 else
9973 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
9974 }
9975#endif
9976
9977 for (i = 0; i < REFERENCE_MODES; ++i) {
9978 if (best_pred_rd[i] == INT64_MAX)
9979 best_pred_diff[i] = INT_MIN;
9980 else
9981 best_pred_diff[i] = best_rd - best_pred_rd[i];
9982 }
9983
9984 x->skip |= best_mode_skippable;
9985
9986 assert(best_mode_index >= 0);
9987
9988 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
9989 best_mode_skippable);
9990
Urvang Joshib100db72016-10-12 16:28:56 -07009991#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009992 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
9993 restore_uv_color_map(cpi, x);
9994 }
Urvang Joshib100db72016-10-12 16:28:56 -07009995#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009996}
9997
Urvang Joshi52648442016-10-13 17:27:51 -07009998void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
9999 TileDataEnc *tile_data, MACROBLOCK *x,
10000 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070010001 PICK_MODE_CONTEXT *ctx,
10002 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010003 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010004 MACROBLOCKD *const xd = &x->e_mbd;
10005 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10006 unsigned char segment_id = mbmi->segment_id;
10007 const int comp_pred = 0;
10008 int i;
10009 int64_t best_pred_diff[REFERENCE_MODES];
10010 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10011 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010012 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070010013 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010014 int64_t this_rd = INT64_MAX;
10015 int rate2 = 0;
10016 const int64_t distortion2 = 0;
10017
10018 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10019 &comp_mode_p);
10020
10021 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
10022 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
10023 x->pred_mv_sad[i] = INT_MAX;
10024
10025 rd_cost->rate = INT_MAX;
10026
10027 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
10028
Urvang Joshib100db72016-10-12 16:28:56 -070010029#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010030 mbmi->palette_mode_info.palette_size[0] = 0;
10031 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010032#endif // CONFIG_PALETTE
10033
hui su5db97432016-10-14 16:10:14 -070010034#if CONFIG_FILTER_INTRA
10035 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10036 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10037#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010038 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070010039 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010040 mbmi->uv_mode = DC_PRED;
10041 mbmi->ref_frame[0] = LAST_FRAME;
10042 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -070010043#if CONFIG_GLOBAL_MOTION
10044 mbmi->mv[0].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -070010045 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070010046#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010047 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010048#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070010049 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070010050 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070010051
Yaowu Xuc27fc142016-08-22 16:08:15 -070010052#if CONFIG_REF_MV
10053 mbmi->ref_mv_idx = 0;
10054 mbmi->pred_mv[0].as_int = 0;
10055#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010056
10057 if (cm->interp_filter != BILINEAR) {
10058 best_filter = EIGHTTAP_REGULAR;
10059 if (cm->interp_filter == SWITCHABLE &&
10060#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010061 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010062#endif // CONFIG_EXT_INTERP
10063 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
10064 int rs;
10065 int best_rs = INT_MAX;
10066 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
10067#if CONFIG_DUAL_FILTER
10068 int k;
10069 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
10070#else
10071 mbmi->interp_filter = i;
10072#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010073 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010074 if (rs < best_rs) {
10075 best_rs = rs;
10076#if CONFIG_DUAL_FILTER
10077 best_filter = mbmi->interp_filter[0];
10078#else
10079 best_filter = mbmi->interp_filter;
10080#endif
10081 }
10082 }
10083 }
10084 }
10085 // Set the appropriate filter
10086 if (cm->interp_filter == SWITCHABLE) {
10087#if CONFIG_DUAL_FILTER
10088 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
10089#else
10090 mbmi->interp_filter = best_filter;
10091#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010092 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010093 } else {
10094#if CONFIG_DUAL_FILTER
10095 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
10096#else
10097 mbmi->interp_filter = cm->interp_filter;
10098#endif
10099 }
10100
10101 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070010102 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010103
10104 // Estimate the reference frame signaling cost and add it
10105 // to the rolling cost variable.
10106 rate2 += ref_costs_single[LAST_FRAME];
10107 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10108
10109 rd_cost->rate = rate2;
10110 rd_cost->dist = distortion2;
10111 rd_cost->rdcost = this_rd;
10112
10113 if (this_rd >= best_rd_so_far) {
10114 rd_cost->rate = INT_MAX;
10115 rd_cost->rdcost = INT64_MAX;
10116 return;
10117 }
10118
10119#if CONFIG_DUAL_FILTER
10120 assert((cm->interp_filter == SWITCHABLE) ||
10121 (cm->interp_filter == mbmi->interp_filter[0]));
10122#else
10123 assert((cm->interp_filter == SWITCHABLE) ||
10124 (cm->interp_filter == mbmi->interp_filter));
10125#endif
10126
Yaowu Xuf883b422016-08-30 14:01:10 -070010127 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10128 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010129
Yaowu Xuf883b422016-08-30 14:01:10 -070010130 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010131
10132 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
10133}
10134
Urvang Joshi52648442016-10-13 17:27:51 -070010135void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
10136 TileDataEnc *tile_data, struct macroblock *x,
10137 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070010138 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010139#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010140 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010141#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010142 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
10143 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010144 const AV1_COMMON *const cm = &cpi->common;
10145 const RD_OPT *const rd_opt = &cpi->rd;
10146 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010147 MACROBLOCKD *const xd = &x->e_mbd;
10148 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10149 const struct segmentation *const seg = &cm->seg;
10150 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
10151 unsigned char segment_id = mbmi->segment_id;
10152 int comp_pred, i;
10153 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
10154 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
10155 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
10156 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070010157 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010158#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010159 AOM_LAST2_FLAG,
10160 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010161#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010162 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010163#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010164 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010166 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070010167 };
10168 int64_t best_rd = best_rd_so_far;
10169 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
10170 int64_t best_pred_diff[REFERENCE_MODES];
10171 int64_t best_pred_rd[REFERENCE_MODES];
10172 MB_MODE_INFO best_mbmode;
10173 int ref_index, best_ref_index = 0;
10174 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10175 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010176 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010177#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070010178 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010179#else
James Zern7b9407a2016-05-18 23:48:05 -070010180 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010181#endif
Jingning Han3f167252016-06-07 16:11:42 -070010182 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
10183 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010184 int skip_uv;
10185 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070010186 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070010187 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
10188#if CONFIG_EXT_INTER
10189 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
10190#else
10191 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
10192#endif // CONFIG_EXT_INTER
10193 b_mode_info best_bmodes[4];
10194 int best_skip2 = 0;
10195 int ref_frame_skip_mask[2] = { 0 };
10196 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070010197 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070010198#if CONFIG_PVQ
10199 od_rollback_buffer pre_buf;
10200
10201 od_encode_checkpoint(&x->daala_enc, &pre_buf);
10202#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010203
10204#if CONFIG_SUPERTX
10205 best_rd_so_far = INT64_MAX;
10206 best_rd = best_rd_so_far;
10207 best_yrd = best_rd_so_far;
10208#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010209 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010210
hui su5db97432016-10-14 16:10:14 -070010211#if CONFIG_FILTER_INTRA
10212 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10213 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10214#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070010215 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010216#if CONFIG_EXT_INTER
Sarah Parker6fddd182016-11-10 20:57:20 -080010217 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010218 mbmi->use_wedge_interintra = 0;
10219#endif // CONFIG_EXT_INTER
10220
10221 for (i = 0; i < 4; i++) {
10222 int j;
10223#if CONFIG_EXT_INTER
10224 int k;
10225
10226 for (k = 0; k < 2; k++)
10227 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10228 seg_mvs[i][k][j].as_int = INVALID_MV;
10229#else
10230 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10231 seg_mvs[i][j].as_int = INVALID_MV;
10232#endif // CONFIG_EXT_INTER
10233 }
10234
10235 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10236 &comp_mode_p);
10237
10238 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
10239 rate_uv_intra = INT_MAX;
10240
10241 rd_cost->rate = INT_MAX;
10242#if CONFIG_SUPERTX
10243 *returnrate_nocoef = INT_MAX;
10244#endif
10245
10246 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
10247 x->mbmi_ext->mode_context[ref_frame] = 0;
10248#if CONFIG_REF_MV && CONFIG_EXT_INTER
10249 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
10250#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
10251 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
10252 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
10253 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
10254 } else {
10255 ref_frame_skip_mask[0] |= (1 << ref_frame);
10256 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10257 }
10258 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
10259#if CONFIG_EXT_INTER
10260 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
10261#endif // CONFIG_EXT_INTER
10262 frame_mv[ZEROMV][ref_frame].as_int = 0;
10263 }
10264
Urvang Joshib100db72016-10-12 16:28:56 -070010265#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010266 mbmi->palette_mode_info.palette_size[0] = 0;
10267 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010268#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010269
10270 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
10271 int mode_excluded = 0;
10272 int64_t this_rd = INT64_MAX;
10273 int disable_skip = 0;
10274 int compmode_cost = 0;
10275 int rate2 = 0, rate_y = 0, rate_uv = 0;
10276 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
10277 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010278 int this_skip2 = 0;
10279 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010280
Yushin Cho77bba8d2016-11-04 16:36:56 -070010281#if CONFIG_PVQ
10282 od_encode_rollback(&x->daala_enc, &pre_buf);
10283#endif
10284
Yaowu Xuf883b422016-08-30 14:01:10 -070010285 ref_frame = av1_ref_order[ref_index].ref_frame[0];
10286 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010287
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010288#if CONFIG_REF_MV
10289 mbmi->ref_mv_idx = 0;
10290#endif
10291
Yaowu Xuc27fc142016-08-22 16:08:15 -070010292 // Look at the reference frame of the best mode so far and set the
10293 // skip mask to look at a subset of the remaining modes.
10294 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
10295 if (ref_index == 3) {
10296 switch (best_mbmode.ref_frame[0]) {
10297 case INTRA_FRAME: break;
10298 case LAST_FRAME:
10299 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
10300#if CONFIG_EXT_REFS
10301 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10302 (1 << BWDREF_FRAME) |
10303#endif // CONFIG_EXT_REFS
10304 (1 << ALTREF_FRAME);
10305 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10306 break;
10307#if CONFIG_EXT_REFS
10308 case LAST2_FRAME:
10309 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
10310 (1 << GOLDEN_FRAME) |
10311 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10312 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10313 break;
10314 case LAST3_FRAME:
10315 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10316 (1 << GOLDEN_FRAME) |
10317 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10318 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10319 break;
10320#endif // CONFIG_EXT_REFS
10321 case GOLDEN_FRAME:
10322 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10323#if CONFIG_EXT_REFS
10324 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10325 (1 << BWDREF_FRAME) |
10326#endif // CONFIG_EXT_REFS
10327 (1 << ALTREF_FRAME);
10328 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10329 break;
10330#if CONFIG_EXT_REFS
10331 case BWDREF_FRAME:
10332 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10333 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
10334 (1 << ALTREF_FRAME);
10335 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
10336 break;
10337#endif // CONFIG_EXT_REFS
10338 case ALTREF_FRAME:
10339 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10340#if CONFIG_EXT_REFS
10341 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10342 (1 << BWDREF_FRAME) |
10343#endif // CONFIG_EXT_REFS
10344 (1 << GOLDEN_FRAME);
10345#if CONFIG_EXT_REFS
10346 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10347#endif // CONFIG_EXT_REFS
10348 break;
10349 case NONE:
10350 case TOTAL_REFS_PER_FRAME:
10351 assert(0 && "Invalid Reference frame");
10352 break;
10353 }
10354 }
10355 }
10356
10357 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010358 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010359 continue;
10360
10361 // Test best rd so far against threshold for trying this mode.
10362 if (!internal_active_edge &&
10363 rd_less_than_thresh(best_rd,
10364 rd_opt->threshes[segment_id][bsize][ref_index],
10365 tile_data->thresh_freq_fact[bsize][ref_index]))
10366 continue;
10367
10368 comp_pred = second_ref_frame > INTRA_FRAME;
10369 if (comp_pred) {
10370 if (!cpi->allow_comp_inter_inter) continue;
10371 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10372 // Do not allow compound prediction if the segment level reference frame
10373 // feature is in use as in this case there can only be one reference.
10374 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10375
10376 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10377 best_mbmode.ref_frame[0] == INTRA_FRAME)
10378 continue;
10379 }
10380
10381 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10382 // sub8x8 blocks.
10383 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010384 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010385 continue;
10386
10387 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010388 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010389 continue;
10390
10391 if (comp_pred)
10392 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10393 else if (ref_frame != INTRA_FRAME)
10394 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10395
10396 // If the segment reference frame feature is enabled....
10397 // then do nothing if the current ref frame is not allowed..
10398 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10399 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10400 continue;
10401 // Disable this drop out case if the ref frame
10402 // segment level feature is enabled for this segment. This is to
10403 // prevent the possibility that we end up unable to pick any mode.
10404 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10405 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10406 // unless ARNR filtering is enabled in which case we want
10407 // an unfiltered alternative. We allow near/nearest as well
10408 // because they may result in zero-zero MVs but be cheaper.
10409 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10410 continue;
10411 }
10412
10413 mbmi->tx_size = TX_4X4;
10414 mbmi->uv_mode = DC_PRED;
10415 mbmi->ref_frame[0] = ref_frame;
10416 mbmi->ref_frame[1] = second_ref_frame;
10417// Evaluate all sub-pel filters irrespective of whether we can use
10418// them for this frame.
10419#if CONFIG_DUAL_FILTER
10420 for (i = 0; i < 4; ++i)
10421 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10422 ? EIGHTTAP_REGULAR
10423 : cm->interp_filter;
10424#else
10425 mbmi->interp_filter =
10426 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10427#endif
10428 x->skip = 0;
10429 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10430
10431 // Select prediction reference frames.
10432 for (i = 0; i < MAX_MB_PLANE; i++) {
10433 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10434 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10435 }
10436
10437#if CONFIG_VAR_TX
10438 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070010439 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010440#endif
10441
10442 if (ref_frame == INTRA_FRAME) {
10443 int rate;
10444 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010445 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010446 continue;
10447 rate2 += rate;
10448 rate2 += intra_cost_penalty;
10449 distortion2 += distortion_y;
10450
10451 if (rate_uv_intra == INT_MAX) {
10452 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10453 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10454 }
10455 rate2 += rate_uv_intra;
10456 rate_uv = rate_uv_tokenonly;
10457 distortion2 += dist_uv;
10458 distortion_uv = dist_uv;
10459 mbmi->uv_mode = mode_uv;
10460 } else {
10461 int rate;
10462 int64_t distortion;
10463 int64_t this_rd_thresh;
10464 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10465 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10466 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10467 int tmp_best_skippable = 0;
10468 int switchable_filter_index;
10469 int_mv *second_ref =
10470 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10471 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10472 MB_MODE_INFO tmp_best_mbmode;
10473#if CONFIG_DUAL_FILTER
10474#if CONFIG_EXT_INTERP
10475 BEST_SEG_INFO bsi[25];
10476#else
10477 BEST_SEG_INFO bsi[9];
10478#endif
10479#else
10480 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10481#endif
10482 int pred_exists = 0;
10483 int uv_skippable;
10484#if CONFIG_EXT_INTER
10485 int_mv compound_seg_newmvs[4][2];
10486 for (i = 0; i < 4; i++) {
10487 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10488 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10489 }
10490#endif // CONFIG_EXT_INTER
10491
10492 this_rd_thresh = (ref_frame == LAST_FRAME)
10493 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10494 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10495#if CONFIG_EXT_REFS
10496 this_rd_thresh = (ref_frame == LAST2_FRAME)
10497 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10498 : this_rd_thresh;
10499 this_rd_thresh = (ref_frame == LAST3_FRAME)
10500 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10501 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070010502 this_rd_thresh = (ref_frame == BWDREF_FRAME)
10503 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
10504 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010505#endif // CONFIG_EXT_REFS
10506 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10507 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10508 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010509
10510 // TODO(any): Add search of the tx_type to improve rd performance at the
10511 // expense of speed.
10512 mbmi->tx_type = DCT_DCT;
10513
10514 if (cm->interp_filter != BILINEAR) {
10515#if CONFIG_DUAL_FILTER
10516 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10517 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10518 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10519 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10520#else
10521 tmp_best_filter = EIGHTTAP_REGULAR;
10522#endif
10523 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10524#if CONFIG_DUAL_FILTER
10525 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10526#else
10527 tmp_best_filter = EIGHTTAP_REGULAR;
10528#endif
10529 } else if (sf->adaptive_pred_interp_filter == 1 &&
10530 ctx->pred_interp_filter < SWITCHABLE) {
10531#if CONFIG_DUAL_FILTER
10532 tmp_best_filter[0] = ctx->pred_interp_filter;
10533#else
10534 tmp_best_filter = ctx->pred_interp_filter;
10535#endif
10536 } else if (sf->adaptive_pred_interp_filter == 2) {
10537#if CONFIG_DUAL_FILTER
10538 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10539 ? ctx->pred_interp_filter
10540 : 0;
10541#else
10542 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10543 ? ctx->pred_interp_filter
10544 : 0;
10545#endif
10546 } else {
10547#if CONFIG_DUAL_FILTER
10548 for (switchable_filter_index = 0;
10549#if CONFIG_EXT_INTERP
10550 switchable_filter_index < 25;
10551#else
10552 switchable_filter_index < 9;
10553#endif
10554 ++switchable_filter_index) {
10555#else
10556 for (switchable_filter_index = 0;
10557 switchable_filter_index < SWITCHABLE_FILTERS;
10558 ++switchable_filter_index) {
10559#endif
10560 int newbest, rs;
10561 int64_t rs_rd;
10562 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10563#if CONFIG_DUAL_FILTER
10564 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10565 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10566 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10567 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10568#else
10569 mbmi->interp_filter = switchable_filter_index;
10570#endif
10571 tmp_rd = rd_pick_best_sub8x8_mode(
10572 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10573 &rate, &rate_y, &distortion, &skippable, &total_sse,
10574 (int)this_rd_thresh, seg_mvs,
10575#if CONFIG_EXT_INTER
10576 compound_seg_newmvs,
10577#endif // CONFIG_EXT_INTER
10578 bsi, switchable_filter_index, mi_row, mi_col);
10579#if CONFIG_EXT_INTERP
10580#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010581 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010582 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10583 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10584 continue;
10585#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010586 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010587 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10588 continue;
10589#endif
10590#endif // CONFIG_EXT_INTERP
10591 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010592 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010593 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10594 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10595
10596 newbest = (tmp_rd < tmp_best_rd);
10597 if (newbest) {
10598#if CONFIG_DUAL_FILTER
10599 tmp_best_filter[0] = mbmi->interp_filter[0];
10600 tmp_best_filter[1] = mbmi->interp_filter[1];
10601 tmp_best_filter[2] = mbmi->interp_filter[2];
10602 tmp_best_filter[3] = mbmi->interp_filter[3];
10603#else
10604 tmp_best_filter = mbmi->interp_filter;
10605#endif
10606 tmp_best_rd = tmp_rd;
10607 }
10608 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10609 (
10610#if CONFIG_DUAL_FILTER
10611 mbmi->interp_filter[0] == cm->interp_filter
10612#else
10613 mbmi->interp_filter == cm->interp_filter
10614#endif
10615 && cm->interp_filter != SWITCHABLE)) {
10616 tmp_best_rdu = tmp_rd;
10617 tmp_best_rate = rate;
10618 tmp_best_ratey = rate_y;
10619 tmp_best_distortion = distortion;
10620 tmp_best_sse = total_sse;
10621 tmp_best_skippable = skippable;
10622 tmp_best_mbmode = *mbmi;
10623 for (i = 0; i < 4; i++) {
10624 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10625 }
10626 pred_exists = 1;
10627 }
10628 } // switchable_filter_index loop
10629 }
10630 }
10631
10632 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10633
10634#if CONFIG_DUAL_FILTER
10635 mbmi->interp_filter[0] =
10636 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10637 : cm->interp_filter);
10638 mbmi->interp_filter[1] =
10639 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10640 : cm->interp_filter);
10641 mbmi->interp_filter[2] =
10642 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10643 : cm->interp_filter);
10644 mbmi->interp_filter[3] =
10645 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10646 : cm->interp_filter);
10647#else
10648 mbmi->interp_filter =
10649 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10650 : cm->interp_filter);
10651#endif
10652
10653 if (!pred_exists) {
10654 // Handles the special case when a filter that is not in the
10655 // switchable list (bilinear) is indicated at the frame level
10656 tmp_rd = rd_pick_best_sub8x8_mode(
10657 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10658 &rate, &rate_y, &distortion, &skippable, &total_sse,
10659 (int)this_rd_thresh, seg_mvs,
10660#if CONFIG_EXT_INTER
10661 compound_seg_newmvs,
10662#endif // CONFIG_EXT_INTER
10663 bsi, 0, mi_row, mi_col);
10664#if CONFIG_EXT_INTERP
10665#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010666 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010667 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10668 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10669 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10670 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10671 }
10672#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010673 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 mbmi->interp_filter != EIGHTTAP_REGULAR)
10675 mbmi->interp_filter = EIGHTTAP_REGULAR;
10676#endif // CONFIG_DUAL_FILTER
10677#endif // CONFIG_EXT_INTERP
10678 if (tmp_rd == INT64_MAX) continue;
10679 } else {
10680 total_sse = tmp_best_sse;
10681 rate = tmp_best_rate;
10682 rate_y = tmp_best_ratey;
10683 distortion = tmp_best_distortion;
10684 skippable = tmp_best_skippable;
10685 *mbmi = tmp_best_mbmode;
10686 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10687 }
10688 // Add in the cost of the transform type
10689 if (!xd->lossless[mbmi->segment_id]) {
10690 int rate_tx_type = 0;
10691#if CONFIG_EXT_TX
10692 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10693 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10694 rate_tx_type =
10695 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10696 }
10697#else
10698 if (mbmi->tx_size < TX_32X32) {
10699 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10700 }
10701#endif
10702 rate += rate_tx_type;
10703 rate_y += rate_tx_type;
10704 }
10705
10706 rate2 += rate;
10707 distortion2 += distortion;
10708
10709 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010710 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010711
10712 if (!mode_excluded)
10713 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10714 : cm->reference_mode == COMPOUND_REFERENCE;
10715
Yaowu Xuf883b422016-08-30 14:01:10 -070010716 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010717
10718 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010719 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010720 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10721
10722 if (tmp_best_rdu > 0) {
10723 // If even the 'Y' rd value of split is higher than best so far
10724 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070010725 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070010726 RD_STATS rd_stats_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010727 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010728#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070010729 is_cost_valid_uv =
10730 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080010731#else
10732 is_cost_valid_uv =
10733 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
10734#endif
Angie Chiangb5dda482016-11-02 16:19:58 -070010735 rate_uv = rd_stats_uv.rate;
10736 distortion_uv = rd_stats_uv.dist;
10737 uv_skippable = rd_stats_uv.skip;
10738 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080010739
Angie Chiangb5dda482016-11-02 16:19:58 -070010740 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010741 rate2 += rate_uv;
10742 distortion2 += distortion_uv;
10743 skippable = skippable && uv_skippable;
10744 total_sse += uv_sse;
10745 } else {
10746 continue;
10747 }
10748 }
10749
10750 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10751
10752 // Estimate the reference frame signaling cost and add it
10753 // to the rolling cost variable.
10754 if (second_ref_frame > INTRA_FRAME) {
10755 rate2 += ref_costs_comp[ref_frame];
10756#if CONFIG_EXT_REFS
10757 rate2 += ref_costs_comp[second_ref_frame];
10758#endif // CONFIG_EXT_REFS
10759 } else {
10760 rate2 += ref_costs_single[ref_frame];
10761 }
10762
10763 if (!disable_skip) {
10764 // Skip is never coded at the segment level for sub8x8 blocks and instead
10765 // always coded in the bitstream at the mode info level.
10766
10767 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10768 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10769 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
10770 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010771 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010772 } else {
10773 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010774 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010775 distortion2 = total_sse;
10776 assert(total_sse >= 0);
10777 rate2 -= (rate_y + rate_uv);
10778 rate_y = 0;
10779 rate_uv = 0;
10780 this_skip2 = 1;
10781 }
10782 } else {
10783 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010784 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010785 }
10786
10787 // Calculate the final RD estimate for this mode.
10788 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10789 }
10790
10791 if (!disable_skip && ref_frame == INTRA_FRAME) {
10792 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010793 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010794 }
10795
10796 // Did this mode help.. i.e. is it the new best mode
10797 if (this_rd < best_rd || x->skip) {
10798 if (!mode_excluded) {
10799 // Note index of best mode so far
10800 best_ref_index = ref_index;
10801
10802 if (ref_frame == INTRA_FRAME) {
10803 /* required for left and above block mv */
10804 mbmi->mv[0].as_int = 0;
10805 }
10806
10807 rd_cost->rate = rate2;
10808#if CONFIG_SUPERTX
10809 *returnrate_nocoef = rate2 - rate_y - rate_uv;
10810 if (!disable_skip)
10811 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070010812 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
10813 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10814 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010815 assert(*returnrate_nocoef > 0);
10816#endif // CONFIG_SUPERTX
10817 rd_cost->dist = distortion2;
10818 rd_cost->rdcost = this_rd;
10819 best_rd = this_rd;
10820 best_yrd =
10821 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
10822 best_mbmode = *mbmi;
10823 best_skip2 = this_skip2;
10824
10825#if CONFIG_VAR_TX
10826 for (i = 0; i < MAX_MB_PLANE; ++i)
10827 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
10828#endif
10829
10830 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010831 }
10832 }
10833
10834 /* keep record of best compound/single-only prediction */
10835 if (!disable_skip && ref_frame != INTRA_FRAME) {
10836 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10837
10838 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10839 single_rate = rate2 - compmode_cost;
10840 hybrid_rate = rate2;
10841 } else {
10842 single_rate = rate2;
10843 hybrid_rate = rate2 + compmode_cost;
10844 }
10845
10846 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10847 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10848
10849 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
10850 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10851 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
10852 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10853
10854 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10855 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10856 }
10857
Yaowu Xuc27fc142016-08-22 16:08:15 -070010858 if (x->skip && !comp_pred) break;
10859 }
10860
10861 if (best_rd >= best_rd_so_far) {
10862 rd_cost->rate = INT_MAX;
10863 rd_cost->rdcost = INT64_MAX;
10864#if CONFIG_SUPERTX
10865 *returnrate_nocoef = INT_MAX;
10866#endif // CONFIG_SUPERTX
10867 return;
10868 }
10869
Yaowu Xuc27fc142016-08-22 16:08:15 -070010870 if (best_rd == INT64_MAX) {
10871 rd_cost->rate = INT_MAX;
10872 rd_cost->dist = INT64_MAX;
10873 rd_cost->rdcost = INT64_MAX;
10874#if CONFIG_SUPERTX
10875 *returnrate_nocoef = INT_MAX;
10876#endif // CONFIG_SUPERTX
10877 return;
10878 }
10879
10880#if CONFIG_DUAL_FILTER
10881 assert((cm->interp_filter == SWITCHABLE) ||
10882 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10883 !is_inter_block(&best_mbmode));
10884#else
10885 assert((cm->interp_filter == SWITCHABLE) ||
10886 (cm->interp_filter == best_mbmode.interp_filter) ||
10887 !is_inter_block(&best_mbmode));
10888#endif
10889
Yaowu Xuf883b422016-08-30 14:01:10 -070010890 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10891 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010892
10893 // macroblock modes
10894 *mbmi = best_mbmode;
10895#if CONFIG_VAR_TX && CONFIG_EXT_TX && CONFIG_RECT_TX
10896 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10897#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
10898
10899 x->skip |= best_skip2;
10900 if (!is_inter_block(&best_mbmode)) {
10901 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
10902 } else {
10903 for (i = 0; i < 4; ++i)
10904 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
10905
Yaowu Xuc27fc142016-08-22 16:08:15 -070010906#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070010907 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
10908 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010909#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010910 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
10911 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010912 }
10913
10914 for (i = 0; i < REFERENCE_MODES; ++i) {
10915 if (best_pred_rd[i] == INT64_MAX)
10916 best_pred_diff[i] = INT_MIN;
10917 else
10918 best_pred_diff[i] = best_rd - best_pred_rd[i];
10919 }
10920
10921 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
10922}
10923
Yue Chencb60b182016-10-13 15:18:22 -070010924#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010925// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070010926//
10927// The OBMC predictor is computed as:
10928//
10929// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010930// AOM_BLEND_A64(Mh(x),
10931// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010932// PLeft(x, y))
10933//
Yaowu Xuf883b422016-08-30 14:01:10 -070010934// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070010935// rounding, this can be written as:
10936//
Yaowu Xuf883b422016-08-30 14:01:10 -070010937// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010938// Mh(x) * Mv(y) * P(x,y) +
10939// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010940// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010941//
10942// Where :
10943//
Yaowu Xuf883b422016-08-30 14:01:10 -070010944// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
10945// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010946//
10947// This function computes 'wsrc' and 'mask' as:
10948//
10949// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010950// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010951// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010952// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010953//
10954// mask(x, y) = Mh(x) * Mv(y)
10955//
10956// These can then be used to efficiently approximate the error for any
10957// predictor P in the context of the provided neighbouring predictors by
10958// computing:
10959//
10960// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010961// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010962//
Yaowu Xuf883b422016-08-30 14:01:10 -070010963static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010964 const MACROBLOCKD *xd, int mi_row,
10965 int mi_col, const uint8_t *above,
10966 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070010967 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010968 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
10969 int row, col, i;
10970 const int bw = 8 * xd->n8_w;
10971 const int bh = 8 * xd->n8_h;
Yue Chene9638cc2016-10-10 12:37:54 -070010972 int32_t *mask_buf = x->mask_buf;
10973 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010974 const int wsrc_stride = bw;
10975 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070010976 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
10977#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010978 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
10979#else
10980 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010981#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010982
10983 // plane 0 should not be subsampled
10984 assert(xd->plane[0].subsampling_x == 0);
10985 assert(xd->plane[0].subsampling_y == 0);
10986
Yaowu Xuf883b422016-08-30 14:01:10 -070010987 av1_zero_array(wsrc_buf, bw * bh);
10988 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010989
10990 // handle above row
10991 if (xd->up_available) {
10992 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010993 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010994 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010995 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010996
10997 assert(miw > 0);
10998
10999 i = 0;
11000 do { // for each mi in the above row
11001 const int mi_col_offset = i;
11002 const MB_MODE_INFO *const above_mbmi =
11003 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11004 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011005 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011006 const int neighbor_bw = mi_step * MI_SIZE;
11007
11008 if (is_neighbor_overlappable(above_mbmi)) {
11009 const int tmp_stride = above_stride;
11010 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
11011 int32_t *mask = mask_buf + (i * MI_SIZE);
11012
11013 if (!is_hbd) {
11014 const uint8_t *tmp = above;
11015
11016 for (row = 0; row < overlap; ++row) {
11017 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011018 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011019 for (col = 0; col < neighbor_bw; ++col) {
11020 wsrc[col] = m1 * tmp[col];
11021 mask[col] = m0;
11022 }
11023 wsrc += wsrc_stride;
11024 mask += mask_stride;
11025 tmp += tmp_stride;
11026 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011027#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011028 } else {
11029 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11030
11031 for (row = 0; row < overlap; ++row) {
11032 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011033 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011034 for (col = 0; col < neighbor_bw; ++col) {
11035 wsrc[col] = m1 * tmp[col];
11036 mask[col] = m0;
11037 }
11038 wsrc += wsrc_stride;
11039 mask += mask_stride;
11040 tmp += tmp_stride;
11041 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011042#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011043 }
11044 }
11045
11046 above += neighbor_bw;
11047 i += mi_step;
11048 } while (i < miw);
11049 }
11050
11051 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011052 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11053 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011054 }
11055
11056 // handle left column
11057 if (xd->left_available) {
11058 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011059 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011060 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011061 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011062
11063 assert(mih > 0);
11064
11065 i = 0;
11066 do { // for each mi in the left column
11067 const int mi_row_offset = i;
11068 const MB_MODE_INFO *const left_mbmi =
11069 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11070 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011071 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011072 const int neighbor_bh = mi_step * MI_SIZE;
11073
11074 if (is_neighbor_overlappable(left_mbmi)) {
11075 const int tmp_stride = left_stride;
11076 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11077 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11078
11079 if (!is_hbd) {
11080 const uint8_t *tmp = left;
11081
11082 for (row = 0; row < neighbor_bh; ++row) {
11083 for (col = 0; col < overlap; ++col) {
11084 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011085 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11086 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11087 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11088 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011089 }
11090 wsrc += wsrc_stride;
11091 mask += mask_stride;
11092 tmp += tmp_stride;
11093 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011094#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011095 } else {
11096 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
11097
11098 for (row = 0; row < neighbor_bh; ++row) {
11099 for (col = 0; col < overlap; ++col) {
11100 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011101 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11102 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11103 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11104 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011105 }
11106 wsrc += wsrc_stride;
11107 mask += mask_stride;
11108 tmp += tmp_stride;
11109 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011110#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011111 }
11112 }
11113
11114 left += neighbor_bh * left_stride;
11115 i += mi_step;
11116 } while (i < mih);
11117 }
11118
11119 if (!is_hbd) {
11120 const uint8_t *src = x->plane[0].src.buf;
11121
11122 for (row = 0; row < bh; ++row) {
11123 for (col = 0; col < bw; ++col) {
11124 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11125 }
11126 wsrc_buf += wsrc_stride;
11127 src += x->plane[0].src.stride;
11128 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011129#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011130 } else {
11131 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11132
11133 for (row = 0; row < bh; ++row) {
11134 for (col = 0; col < bw; ++col) {
11135 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11136 }
11137 wsrc_buf += wsrc_stride;
11138 src += x->plane[0].src.stride;
11139 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011140#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011141 }
11142}
Yue Chencb60b182016-10-13 15:18:22 -070011143#endif // CONFIG_MOTION_VAR