blob: 3242f3d5495ce2b5ed9b16fd3a92d4a24053d64c [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];
939 c = 0;
940 } else {
941 if (use_fast_coef_costing) {
942 int band_left = *band_count++;
943
944 // dc token
945 int v = qcoeff[0];
946 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -0700947 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 cost += (*token_costs)[0][pt][prev_t];
949
Yaowu Xuf883b422016-08-30 14:01:10 -0700950 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 ++token_costs;
952
953 // ac tokens
954 for (c = 1; c < eob; c++) {
955 const int rc = scan[c];
956 int16_t t;
957
958 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700959 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700960 cost += (*token_costs)[!prev_t][!prev_t][t];
961 prev_t = t;
962 if (!--band_left) {
963 band_left = *band_count++;
964 ++token_costs;
965 }
966 }
967
968 // eob token
969 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
970
971 } else { // !use_fast_coef_costing
972 int band_left = *band_count++;
973
974 // dc token
975 int v = qcoeff[0];
976 int16_t tok;
977 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -0700978 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700979 cost += (*token_costs)[0][pt][tok];
980
Yaowu Xuf883b422016-08-30 14:01:10 -0700981 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700982 ++token_costs;
983
984 tok_cost_ptr = &((*token_costs)[!tok]);
985
986 // ac tokens
987 for (c = 1; c < eob; c++) {
988 const int rc = scan[c];
989
990 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -0700991 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700992 pt = get_coef_context(nb, token_cache, c);
993 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -0700994 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700995 if (!--band_left) {
996 band_left = *band_count++;
997 ++token_costs;
998 }
999 tok_cost_ptr = &((*token_costs)[!tok]);
1000 }
1001
1002 // eob token
1003 if (band_left) {
1004 pt = get_coef_context(nb, token_cache, c);
1005 cost += (*token_costs)[0][pt][EOB_TOKEN];
1006 }
1007 }
1008 }
1009
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 return cost;
1011}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001012#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001013
Yaowu Xuf883b422016-08-30 14:01:10 -07001014static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1015 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 int64_t *out_dist, int64_t *out_sse) {
1017 MACROBLOCKD *const xd = &x->e_mbd;
1018 const struct macroblock_plane *const p = &x->plane[plane];
1019 const struct macroblockd_plane *const pd = &xd->plane[plane];
1020 if (cpi->sf.use_transform_domain_distortion) {
1021 // Transform domain distortion computation is more accurate as it does
1022 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001023 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001024 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001025 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001026 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1027 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001028#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001029 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001030#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001031#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001032 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001033 *out_dist =
1034 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1035 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001036#elif CONFIG_PVQ
1037 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1038 &this_sse) >>
1039 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001040#else
1041 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001042 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001043#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001044 *out_sse = this_sse >> shift;
1045 } else {
1046 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001047 const int bsw = block_size_wide[tx_bsize];
1048 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001049 const int src_stride = x->plane[plane].src.stride;
1050 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001051 // Scale the transform block index to pixel unit.
1052 const int src_idx = (blk_row * src_stride + blk_col)
1053 << tx_size_wide_log2[0];
1054 const int dst_idx = (blk_row * dst_stride + blk_col)
1055 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1057 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1058 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1059 const uint16_t eob = p->eobs[block];
1060
1061 unsigned int tmp;
1062
1063 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001064 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001065
1066 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1067 *out_sse = (int64_t)tmp * 16;
1068
1069 if (eob) {
1070 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001071#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1073 uint8_t *recon = (uint8_t *)recon16;
1074#else
1075 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001076#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001077
1078 const PLANE_TYPE plane_type = plane == 0 ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1079
1080 INV_TXFM_PARAM inv_txfm_param;
1081
1082 inv_txfm_param.tx_type = get_tx_type(plane_type, xd, block, tx_size);
1083 inv_txfm_param.tx_size = tx_size;
1084 inv_txfm_param.eob = eob;
1085 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1086
Yaowu Xuf883b422016-08-30 14:01:10 -07001087#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001088 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1089 recon = CONVERT_TO_BYTEPTR(recon);
1090 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001091 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001092 NULL, 0, bsw, bsh, xd->bd);
1093 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1094 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001095#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 {
Yushin Cho721868c2016-11-14 16:04:33 +09001097#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001098 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001099 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001100#else
1101 int i, j;
1102
1103 for (j = 0; j < bsh; j++)
1104 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
1105#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001106 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1107 }
1108
1109 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
1110 }
1111
1112 *out_dist = (int64_t)tmp * 16;
1113 }
1114}
1115
Yushin Cho77bba8d2016-11-04 16:36:56 -07001116#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001117static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001118 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001119 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1120 tx_size, args->scan_order->scan,
1121 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001122 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001124#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125
1126static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1127 TX_SIZE tx_size) {
1128 uint64_t sse;
1129 switch (tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001131 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1132 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133 break;
1134 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001135 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1136 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001137 break;
1138 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001139 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1140 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001141 break;
1142 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001143 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1144 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001145 break;
1146 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001147 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1148 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001149 break;
1150 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001151 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1152 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 default:
1155 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001156 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001157 break;
1158 }
1159 return sse;
1160}
1161
1162static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1163 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1164 struct rdcost_block_args *args = arg;
1165 MACROBLOCK *const x = args->x;
1166 MACROBLOCKD *const xd = &x->e_mbd;
1167 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001168 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001169 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1171 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001172 RD_STATS this_rd_stats;
1173 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001174
1175 if (args->exit_early) return;
1176
1177 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001178 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001179 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001181 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001182 &b_args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001183
1184 if (args->cpi->sf.use_transform_domain_distortion) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001185 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1186 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001187 } else {
1188 // Note that the encode block_intra call above already calls
1189 // inv_txfm_add, so we can't just call dist_block here.
1190 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001191 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001192
1193 const struct macroblock_plane *const p = &x->plane[plane];
1194 const struct macroblockd_plane *const pd = &xd->plane[plane];
1195
1196 const int src_stride = p->src.stride;
1197 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001198 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001199
1200 const uint8_t *src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1201 const uint8_t *dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1202 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
1203
1204 unsigned int tmp;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001205 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001206
Yaowu Xuf883b422016-08-30 14:01:10 -07001207#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001208 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001209 this_rd_stats.sse =
1210 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001211#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001212 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213
1214 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001215 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001216 }
1217 } else {
1218// full forward transform and quantization
1219#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001220 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001221 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001223 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001224 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001225#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001226#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001227 if (x->plane[plane].eobs[block])
Angie Chiangff6d8902016-10-21 11:02:09 -07001228 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yushin Cho721868c2016-11-14 16:04:33 +09001229#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001230 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1231 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001232 }
1233
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001234 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001235 if (args->this_rd + rd > args->best_rd) {
1236 args->exit_early = 1;
1237 return;
1238 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001239#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001240 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001241#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001242 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1243 this_rd_stats.rate);
1244#endif
Angie Chiang3963d632016-11-10 18:41:40 -08001245
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001246 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1247 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001248#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001249 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001250 args->t_above[blk_col] = !x->pvq_skip[plane];
1251 args->t_left[blk_row] = !x->pvq_skip[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001252#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001253 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1254 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001255
1256 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001257 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001258
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001259#if !CONFIG_PVQ
1260 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1261#else
1262 this_rd_stats.skip &= x->pvq_skip[plane];
1263#endif
1264 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001265 args->this_rd += rd;
1266
1267 if (args->this_rd > args->best_rd) {
1268 args->exit_early = 1;
1269 return;
1270 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001271}
1272
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001273static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1274 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1275 BLOCK_SIZE bsize, TX_SIZE tx_size,
1276 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001277 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001278 MACROBLOCKD *const xd = &x->e_mbd;
1279 const struct macroblockd_plane *const pd = &xd->plane[plane];
1280 TX_TYPE tx_type;
1281 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001282 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001283 args.x = x;
1284 args.cpi = cpi;
1285 args.best_rd = ref_best_rd;
1286 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001287 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288
1289 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1290
Yaowu Xuf883b422016-08-30 14:01:10 -07001291 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001292
1293 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001294 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001295 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001296
Yaowu Xuf883b422016-08-30 14:01:10 -07001297 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1298 &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001299 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001300 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001301 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001302 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001303 }
1304}
1305
1306#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001307void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1308 int64_t *distortion, int *skippable,
1309 int64_t *sse, int64_t ref_best_rd, int plane,
1310 BLOCK_SIZE bsize, TX_SIZE tx_size,
1311 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001312 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313 MACROBLOCKD *const xd = &x->e_mbd;
1314 const struct macroblockd_plane *const pd = &xd->plane[plane];
1315 struct rdcost_block_args args;
1316 TX_TYPE tx_type;
1317
Yaowu Xuf883b422016-08-30 14:01:10 -07001318 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319 args.cpi = cpi;
1320 args.x = x;
1321 args.best_rd = ref_best_rd;
1322 args.use_fast_coef_costing = use_fast_coef_casting;
1323
1324#if CONFIG_EXT_TX
1325 assert(tx_size < TX_SIZES);
1326#endif // CONFIG_EXT_TX
1327
1328 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1329
Yaowu Xuf883b422016-08-30 14:01:10 -07001330 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331
1332 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001333 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001334 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001335
1336 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1337 &args);
1338
1339 if (args.exit_early) {
1340 *rate = INT_MAX;
1341 *distortion = INT64_MAX;
1342 *sse = INT64_MAX;
1343 *skippable = 0;
1344 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001345 *distortion = args.rd_stats.dist;
1346 *rate = args.rd_stats.rate;
1347 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348 *skippable = !x->plane[plane].eobs[0];
1349 }
1350}
1351#endif // CONFIG_SUPERTX
1352
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001353static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1354 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1355 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001356 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001357 MACROBLOCKD *const xd = &x->e_mbd;
1358 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1359 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001360 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001361 int s0, s1;
1362 const int is_inter = is_inter_block(mbmi);
1363 const int tx_size_ctx = get_tx_size_context(xd);
1364 const int tx_size_cat =
1365 is_inter ? inter_tx_size_cat_lookup[bs] : intra_tx_size_cat_lookup[bs];
1366 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Hanb0a71302016-10-25 16:28:49 -07001367 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001368 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
Jingning Hanb0a71302016-10-25 16:28:49 -07001369 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370
1371 assert(skip_prob > 0);
1372#if CONFIG_EXT_TX && CONFIG_RECT_TX
1373 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1374#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1375
Yaowu Xuf883b422016-08-30 14:01:10 -07001376 s0 = av1_cost_bit(skip_prob, 0);
1377 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001378
1379 mbmi->tx_type = tx_type;
1380 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001381 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001382 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001383 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001384#if CONFIG_EXT_TX
1385 if (get_ext_tx_types(tx_size, bs, is_inter) > 1 &&
1386 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1387 const int ext_tx_set = get_ext_tx_set(tx_size, bs, is_inter);
1388 if (is_inter) {
1389 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001390 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001391 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1392 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001393 } else {
1394 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001395 rd_stats->rate += cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
1396 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001397 }
1398 }
1399#else
1400 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1401 !FIXED_TX_TYPE) {
1402 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001403 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001404 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001405 rd_stats->rate +=
1406 cpi->intra_tx_type_costs[mbmi->tx_size]
1407 [intra_mode_to_tx_type_context[mbmi->mode]]
1408 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001409 }
1410 }
1411#endif // CONFIG_EXT_TX
1412
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001413 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001414 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001415 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001416 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001417 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1418 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001419 }
1420 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001421 rd = RDCOST(x->rdmult, x->rddiv,
1422 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001423 }
1424
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001425 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001426
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001427 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1428 !(rd_stats->skip))
1429 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001430
1431 return rd;
1432}
1433
Urvang Joshi52648442016-10-13 17:27:51 -07001434static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001435 MACROBLOCK *x, RD_STATS *rd_stats,
1436 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001437#if CONFIG_PVQ
1438 od_rollback_buffer buf,
1439#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001440 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001441 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001442 MACROBLOCKD *const xd = &x->e_mbd;
1443 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001444 int64_t rd = INT64_MAX;
1445 int n;
1446 int start_tx, end_tx;
1447 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1448 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1449 TX_SIZE best_tx_size = max_tx_size;
1450 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1451 const int is_inter = is_inter_block(mbmi);
1452#if CONFIG_EXT_TX
1453#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001454 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455#endif // CONFIG_RECT_TX
1456 int ext_tx_set;
1457#endif // CONFIG_EXT_TX
1458
1459 if (tx_select) {
1460#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001461 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1463 start_tx = max_tx_size;
Hui Sueafb2e62016-10-18 10:21:36 -07001464 end_tx = (max_tx_size == TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001465 } else {
1466 const TX_SIZE chosen_tx_size =
1467 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1468#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001469 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1470 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001471#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1472 start_tx = chosen_tx_size;
1473 end_tx = chosen_tx_size;
1474 }
1475
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001476 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001477
1478 mbmi->tx_type = tx_type;
1479
1480#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001481 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001483 RD_STATS this_rd_stats;
Urvang Joshi368fbc92016-10-17 16:31:34 -07001484 ext_tx_set = get_ext_tx_set(rect_tx_size, bs, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001485 if (ext_tx_used_inter[ext_tx_set][tx_type]) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001486 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001487 rect_tx_size);
1488 best_tx_size = rect_tx_size;
1489 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001490 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001491 }
1492 }
1493#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1494
1495 last_rd = INT64_MAX;
1496 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001497 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001498#if CONFIG_EXT_TX && CONFIG_RECT_TX
1499 if (is_rect_tx(n)) break;
1500#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1501 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1502 if (!is_inter && x->use_default_intra_tx_type &&
1503 tx_type != get_default_tx_type(0, xd, 0, n))
1504 continue;
1505 if (is_inter && x->use_default_inter_tx_type &&
1506 tx_type != get_default_tx_type(0, xd, 0, n))
1507 continue;
1508 if (max_tx_size == TX_32X32 && n == TX_4X4) continue;
1509#if CONFIG_EXT_TX
1510 ext_tx_set = get_ext_tx_set(n, bs, is_inter);
1511 if (is_inter) {
1512 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1513 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1514 if (!do_tx_type_search(tx_type, prune)) continue;
1515 }
1516 } else {
1517 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1518 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1519 }
1520 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1521 }
1522#else // CONFIG_EXT_TX
1523 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1524 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1525 !do_tx_type_search(tx_type, prune))
1526 continue;
1527#endif // CONFIG_EXT_TX
1528
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001529 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001530#if CONFIG_PVQ
1531 od_encode_rollback(&x->daala_enc, &buf);
1532#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001533 // Early termination in transform size search.
1534 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001535 (rd == INT64_MAX ||
1536 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001537 (n < (int)max_tx_size && rd > last_rd)))
1538 break;
1539
1540 last_rd = rd;
1541 if (rd < best_rd) {
1542 best_tx_size = n;
1543 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001544 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545 }
1546 }
1547 mbmi->tx_size = best_tx_size;
1548
1549 return best_rd;
1550}
1551
1552#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001553static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1554 MACROBLOCK *x, int *r, int64_t *d, int *s,
1555 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001556 RD_STATS rd_stats;
1557 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1558 max_txsize_lookup[bs]);
1559 *r = rd_stats.rate;
1560 *d = rd_stats.dist;
1561 *s = rd_stats.skip;
1562 *sse = rd_stats.sse;
1563 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001564}
1565#endif // CONFIG_EXT_INTER
1566
Urvang Joshi52648442016-10-13 17:27:51 -07001567static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001568 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001569 BLOCK_SIZE bs) {
1570 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001571 MACROBLOCKD *const xd = &x->e_mbd;
1572 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1573 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001574 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001575 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1576 int s0 = av1_cost_bit(skip_prob, 0);
1577 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001578 const int is_inter = is_inter_block(mbmi);
1579 int prune = 0;
1580#if CONFIG_EXT_TX
1581 int ext_tx_set;
1582#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001583 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584
1585 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001586#if CONFIG_VAR_TX
1587 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1588#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001589#if CONFIG_EXT_TX
1590 ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
1591#endif // CONFIG_EXT_TX
1592
1593 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1594#if CONFIG_EXT_TX
1595 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1596#else
1597 prune = prune_tx_types(cpi, bs, x, xd, 0);
1598#endif
1599#if CONFIG_EXT_TX
1600 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
1601 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001602#if CONFIG_PVQ
1603 od_rollback_buffer pre_buf, post_buf;
1604
1605 od_encode_checkpoint(&x->daala_enc, &pre_buf);
1606 od_encode_checkpoint(&x->daala_enc, &post_buf);
1607#endif
1608
1609 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001610 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611 if (is_inter) {
1612 if (x->use_default_inter_tx_type &&
1613 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1614 continue;
1615 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1616 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1617 if (!do_tx_type_search(tx_type, prune)) continue;
1618 }
1619 } else {
1620 if (x->use_default_intra_tx_type &&
1621 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1622 continue;
1623 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1624 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1625 }
1626 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1627 }
1628
1629 mbmi->tx_type = tx_type;
1630
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001631 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001632 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001633#if CONFIG_PVQ
1634 od_encode_rollback(&x->daala_enc, &pre_buf);
1635#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001636 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001637 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1) {
1638 if (is_inter) {
1639 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001640 this_rd_stats.rate +=
1641 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
1642 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001643 } else {
1644 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001645 this_rd_stats.rate +=
1646 cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->mode]
1647 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001648 }
1649 }
1650
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001651 if (this_rd_stats.skip)
1652 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001653 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001654 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1655 this_rd_stats.dist);
1656 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
1657 !this_rd_stats.skip)
1658 this_rd =
1659 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001660
1661 if (this_rd < best_rd) {
1662 best_rd = this_rd;
1663 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001664 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001665#if CONFIG_PVQ
1666 od_encode_checkpoint(&x->daala_enc, &post_buf);
1667#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001668 }
1669 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001670#if CONFIG_PVQ
1671 od_encode_rollback(&x->daala_enc, &post_buf);
1672#endif
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001673 } else {
1674 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001675 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1676 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001677 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001678#else // CONFIG_EXT_TX
1679 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
1680 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001681 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001682 if (!is_inter && x->use_default_intra_tx_type &&
1683 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1684 continue;
1685 if (is_inter && x->use_default_inter_tx_type &&
1686 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1687 continue;
1688 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001689 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001690 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001691 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001692 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001693 this_rd_stats.rate +=
1694 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001695 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1696 !do_tx_type_search(tx_type, prune))
1697 continue;
1698 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001699 this_rd_stats.rate +=
1700 cpi->intra_tx_type_costs[mbmi->tx_size]
1701 [intra_mode_to_tx_type_context[mbmi->mode]]
1702 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001703 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001704 if (this_rd_stats.skip)
1705 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001706 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001707 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1708 this_rd_stats.dist);
1709 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
1710 this_rd =
1711 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001712
1713 if (this_rd < best_rd) {
1714 best_rd = this_rd;
1715 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001716 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001717 }
1718 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001719 } else {
1720 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001721 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1722 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723 }
1724#endif // CONFIG_EXT_TX
1725 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001726}
1727
Urvang Joshi52648442016-10-13 17:27:51 -07001728static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001729 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001730 BLOCK_SIZE bs) {
1731 MACROBLOCKD *const xd = &x->e_mbd;
1732 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1733
1734 mbmi->tx_size = TX_4X4;
1735 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07001736#if CONFIG_VAR_TX
1737 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
1738#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001739
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001740 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
1741 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001742}
1743
Urvang Joshi52648442016-10-13 17:27:51 -07001744static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001745 MACROBLOCK *x, RD_STATS *rd_stats,
1746 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001747 MACROBLOCKD *const xd = &x->e_mbd;
1748 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001749 int64_t rd = INT64_MAX;
1750 int64_t best_rd = INT64_MAX;
1751 TX_SIZE best_tx = max_txsize_lookup[bs];
1752 const int is_inter = is_inter_block(mbmi);
1753 TX_TYPE tx_type, best_tx_type = DCT_DCT;
1754 int prune = 0;
1755
Yushin Cho77bba8d2016-11-04 16:36:56 -07001756#if CONFIG_PVQ
1757 od_rollback_buffer buf;
1758#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001759 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1760 // passing -1 in for tx_type indicates that all 1D
1761 // transforms should be considered for pruning
1762 prune = prune_tx_types(cpi, bs, x, xd, -1);
1763
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001764 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765
Yushin Cho77bba8d2016-11-04 16:36:56 -07001766#if CONFIG_PVQ
1767 od_encode_checkpoint(&x->daala_enc, &buf);
1768#endif
1769
Yaowu Xuc27fc142016-08-22 16:08:15 -07001770 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001771 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001772#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001773 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001774#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001775 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08001776 tx_type,
1777#if CONFIG_PVQ
1778 buf,
1779#endif
1780 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001781 if (rd < best_rd) {
1782 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001783 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001784 best_tx_type = tx_type;
1785 best_tx = mbmi->tx_size;
1786 }
1787 }
1788
1789 mbmi->tx_size = best_tx;
1790 mbmi->tx_type = best_tx_type;
1791
Jingning Hane67b38a2016-11-04 10:30:00 -07001792#if CONFIG_VAR_TX
1793 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
1794#endif
1795
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796#if !CONFIG_EXT_TX
1797 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
1798#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001799#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08001800 if (best_rd != INT64_MAX) {
1801 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, best_tx,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001802 cpi->sf.use_fast_coef_costing);
Yushin Cho05f540a2016-11-08 22:12:51 -08001803 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001804#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001805}
1806
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001807static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1808 RD_STATS *rd_stats, BLOCK_SIZE bs,
1809 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001810 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001811 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001812
1813 assert(bs == xd->mi[0]->mbmi.sb_type);
1814
1815 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001816 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001817 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001818 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001819 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001820 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001821 }
1822}
1823
1824static int conditional_skipintra(PREDICTION_MODE mode,
1825 PREDICTION_MODE best_intra_mode) {
1826 if (mode == D117_PRED && best_intra_mode != V_PRED &&
1827 best_intra_mode != D135_PRED)
1828 return 1;
1829 if (mode == D63_PRED && best_intra_mode != V_PRED &&
1830 best_intra_mode != D45_PRED)
1831 return 1;
1832 if (mode == D207_PRED && best_intra_mode != H_PRED &&
1833 best_intra_mode != D45_PRED)
1834 return 1;
1835 if (mode == D153_PRED && best_intra_mode != H_PRED &&
1836 best_intra_mode != D135_PRED)
1837 return 1;
1838 return 0;
1839}
1840
Urvang Joshib100db72016-10-12 16:28:56 -07001841#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842static int rd_pick_palette_intra_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07001843 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int palette_ctx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001844 int dc_mode_cost, PALETTE_MODE_INFO *palette_mode_info,
1845 uint8_t *best_palette_color_map, TX_SIZE *best_tx, TX_TYPE *best_tx_type,
1846 PREDICTION_MODE *mode_selected, int64_t *best_rd) {
1847 int rate_overhead = 0;
1848 MACROBLOCKD *const xd = &x->e_mbd;
1849 MODE_INFO *const mic = xd->mi[0];
1850 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
1851 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001852 int this_rate, colors, n;
1853 RD_STATS tokenonly_rd_stats;
1854 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001855 const int src_stride = x->plane[0].src.stride;
1856 const uint8_t *const src = x->plane[0].src.buf;
1857
1858 assert(cpi->common.allow_screen_content_tools);
1859
Yaowu Xuf883b422016-08-30 14:01:10 -07001860#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001861 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07001862 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
1863 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001864 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001865#endif // CONFIG_AOM_HIGHBITDEPTH
1866 colors = av1_count_colors(src, src_stride, rows, cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001867 palette_mode_info->palette_size[0] = 0;
hui su5db97432016-10-14 16:10:14 -07001868#if CONFIG_FILTER_INTRA
1869 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1870#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001871
1872 if (colors > 1 && colors <= 64) {
1873 int r, c, i, j, k;
1874 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07001875 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001876 float *const data = x->palette_buffer->kmeans_data_buf;
1877 float centroids[PALETTE_MAX_SIZE];
1878 uint8_t *const color_map = xd->plane[0].color_index_map;
1879 float lb, ub, val;
1880 MB_MODE_INFO *const mbmi = &mic->mbmi;
1881 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07001882#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
1884 if (cpi->common.use_highbitdepth)
1885 lb = ub = src16[0];
1886 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001887#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001888 lb = ub = src[0];
1889
Yaowu Xuf883b422016-08-30 14:01:10 -07001890#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891 if (cpi->common.use_highbitdepth) {
1892 for (r = 0; r < rows; ++r) {
1893 for (c = 0; c < cols; ++c) {
1894 val = src16[r * src_stride + c];
1895 data[r * cols + c] = val;
1896 if (val < lb)
1897 lb = val;
1898 else if (val > ub)
1899 ub = val;
1900 }
1901 }
1902 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001903#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001904 for (r = 0; r < rows; ++r) {
1905 for (c = 0; c < cols; ++c) {
1906 val = src[r * src_stride + c];
1907 data[r * cols + c] = val;
1908 if (val < lb)
1909 lb = val;
1910 else if (val > ub)
1911 ub = val;
1912 }
1913 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001914#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001915 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001916#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917
1918 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07001919#if CONFIG_FILTER_INTRA
1920 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
1921#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001922
1923 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
1924
1925 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
1926 --n) {
1927 for (i = 0; i < n; ++i)
1928 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001929 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
1930 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001931
Yaowu Xuf883b422016-08-30 14:01:10 -07001932#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001933 if (cpi->common.use_highbitdepth)
1934 for (i = 0; i < k; ++i)
1935 pmi->palette_colors[i] =
1936 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
1937 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001938#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001939 for (i = 0; i < k; ++i)
1940 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
1941 pmi->palette_size[0] = k;
1942
Yaowu Xuf883b422016-08-30 14:01:10 -07001943 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001944
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001945 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
1946 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001947
1948 this_rate =
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001949 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07001950 cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07001951 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - 2] +
1952 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07001953 av1_cost_bit(
1954 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07001955 1);
1956 for (i = 0; i < rows; ++i) {
1957 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07001958 int color_idx;
1959 const int color_ctx = av1_get_palette_color_context(
1960 color_map, cols, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 assert(color_idx >= 0 && color_idx < k);
1962 this_rate += cpi->palette_y_color_cost[k - 2][color_ctx][color_idx];
1963 }
1964 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001965 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001966
1967 if (this_rd < *best_rd) {
1968 *best_rd = this_rd;
1969 *palette_mode_info = *pmi;
1970 memcpy(best_palette_color_map, color_map,
1971 rows * cols * sizeof(color_map[0]));
1972 *mode_selected = DC_PRED;
1973 *best_tx = mbmi->tx_size;
1974 *best_tx_type = mbmi->tx_type;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08001975 rate_overhead = this_rate - tokenonly_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976 }
1977 }
1978 }
1979 return rate_overhead;
1980}
Urvang Joshib100db72016-10-12 16:28:56 -07001981#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001982
Urvang Joshi52648442016-10-13 17:27:51 -07001983static int64_t rd_pick_intra4x4block(
1984 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
1985 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
1986 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
1987 BLOCK_SIZE bsize, int *y_skip, int64_t rd_thresh) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001988#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07001989 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001990#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001991 PREDICTION_MODE mode;
1992 MACROBLOCKD *const xd = &x->e_mbd;
1993 int64_t best_rd = rd_thresh;
1994 struct macroblock_plane *p = &x->plane[0];
1995 struct macroblockd_plane *pd = &xd->plane[0];
1996 const int src_stride = p->src.stride;
1997 const int dst_stride = pd->dst.stride;
1998 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
1999 uint8_t *dst_init = &pd->dst.buf[row * 4 * src_stride + col * 4];
2000 ENTROPY_CONTEXT ta[2], tempa[2];
2001 ENTROPY_CONTEXT tl[2], templ[2];
2002 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2003 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2004 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002005 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006 uint8_t best_dst[8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -07002007#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008 uint16_t best_dst16[8 * 8];
2009#endif
2010
Yushin Cho77bba8d2016-11-04 16:36:56 -07002011#if CONFIG_PVQ
2012 od_rollback_buffer pre_buf, post_buf;
2013 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2014 od_encode_checkpoint(&x->daala_enc, &post_buf);
2015#endif
2016
Yaowu Xuc27fc142016-08-22 16:08:15 -07002017 memcpy(ta, a, num_4x4_blocks_wide * sizeof(a[0]));
2018 memcpy(tl, l, num_4x4_blocks_high * sizeof(l[0]));
2019 xd->mi[0]->mbmi.tx_size = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002020#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002021 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002022#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002023
Yaowu Xuf883b422016-08-30 14:01:10 -07002024#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2026 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2027 int64_t this_rd;
2028 int ratey = 0;
2029 int64_t distortion = 0;
2030 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002031 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002032
2033 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2034
2035 // Only do the oblique modes if the best so far is
2036 // one of the neighboring directional modes
2037 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2038 if (conditional_skipintra(mode, *best_mode)) continue;
2039 }
2040
2041 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2042 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2043
2044 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2045 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2046 const int block = (row + idy) * 2 + (col + idx);
2047 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2048 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
2049 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002050 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002051 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002052 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2053 dst_stride, dst, dst_stride, col + idx,
2054 row + idy, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002055 aom_highbd_subtract_block(4, 4, src_diff, 8, src, src_stride, dst,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002056 dst_stride, xd->bd);
2057 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2058 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002059 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002060 const int coeff_ctx =
2061 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002062#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002063 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2064 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002065#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002066 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002067 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002068#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002069 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002070 scan_order->scan, scan_order->neighbors,
2071 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002072 *(tempa + idx) = !(p->eobs[block] == 0);
2073 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002074 can_skip &= (p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002075 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2076 goto next_highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002077 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2078 dst_stride, p->eobs[block], xd->bd,
2079 DCT_DCT, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002080 } else {
2081 int64_t dist;
2082 unsigned int tmp;
2083 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002084 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002085 const int coeff_ctx =
2086 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2087#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002088 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2089 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002091 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Yaowu Xuf883b422016-08-30 14:01:10 -07002092 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002093#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002094 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002095 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002096 scan_order->scan, scan_order->neighbors,
2097 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002098 *(tempa + idx) = !(p->eobs[block] == 0);
2099 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002100 can_skip &= (p->eobs[block] == 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07002101 av1_highbd_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2102 dst_stride, p->eobs[block], xd->bd,
2103 tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002104 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2105 dist = (int64_t)tmp << 4;
2106 distortion += dist;
2107 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2108 goto next_highbd;
2109 }
2110 }
2111 }
2112
2113 rate += ratey;
2114 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2115
2116 if (this_rd < best_rd) {
2117 *bestrate = rate;
2118 *bestratey = ratey;
2119 *bestdistortion = distortion;
2120 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002121 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002122 *best_mode = mode;
2123 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2124 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
2125 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2126 memcpy(best_dst16 + idy * 8,
2127 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2128 num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2129 }
2130 }
2131 next_highbd : {}
2132 }
2133
2134 if (best_rd >= rd_thresh) return best_rd;
2135
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002136 if (y_skip) *y_skip &= best_can_skip;
2137
Yaowu Xuc27fc142016-08-22 16:08:15 -07002138 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy) {
2139 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
2140 best_dst16 + idy * 8, num_4x4_blocks_wide * 4 * sizeof(uint16_t));
2141 }
2142
2143 return best_rd;
2144 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002145#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002146
Yushin Cho77bba8d2016-11-04 16:36:56 -07002147#if CONFIG_PVQ
2148 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2149#endif
2150
Yaowu Xuc27fc142016-08-22 16:08:15 -07002151 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2152 int64_t this_rd;
2153 int ratey = 0;
2154 int64_t distortion = 0;
2155 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002156 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002157
2158 if (!(cpi->sf.intra_y_mode_mask[TX_4X4] & (1 << mode))) continue;
2159
2160 // Only do the oblique modes if the best so far is
2161 // one of the neighboring directional modes
2162 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2163 if (conditional_skipintra(mode, *best_mode)) continue;
2164 }
2165
2166 memcpy(tempa, ta, num_4x4_blocks_wide * sizeof(ta[0]));
2167 memcpy(templ, tl, num_4x4_blocks_high * sizeof(tl[0]));
2168
2169 for (idy = 0; idy < num_4x4_blocks_high; ++idy) {
2170 for (idx = 0; idx < num_4x4_blocks_wide; ++idx) {
2171 const int block = (row + idy) * 2 + (col + idx);
2172 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2173 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002174#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002175 int16_t *const src_diff =
Yaowu Xuf883b422016-08-30 14:01:10 -07002176 av1_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002177#else
2178 int lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2179 const int diff_stride = 8;
2180 tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
2181 tran_low_t *const dqcoeff = BLOCK_OFFSET(xd->plane[0].dqcoeff, block);
2182 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
2183 int16_t *pred = &pd->pred[4 * (row * diff_stride + col)];
2184 int16_t *src_int16 = &p->src_int16[4 * (row * diff_stride + col)];
2185 int i, j, tx_blk_size;
2186 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
2187 int rate_pvq;
2188 int skip;
2189#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002190 xd->mi[0]->bmi[block].as_mode = mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07002191 av1_predict_intra_block(xd, pd->width, pd->height, TX_4X4, mode, dst,
2192 dst_stride, dst, dst_stride, col + idx,
2193 row + idy, 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002194#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07002195 aom_subtract_block(4, 4, src_diff, 8, src, src_stride, dst, dst_stride);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002196#else
2197 if (lossless) tx_type = DCT_DCT;
2198 // transform block size in pixels
2199 tx_blk_size = 4;
2200
2201 // copy uint8 orig and predicted block to int16 buffer
2202 // in order to use existing VP10 transform functions
2203 for (j = 0; j < tx_blk_size; j++)
2204 for (i = 0; i < tx_blk_size; i++) {
2205 src_int16[diff_stride * j + i] = src[src_stride * j + i];
2206 pred[diff_stride * j + i] = dst[dst_stride * j + i];
2207 }
2208 {
2209 FWD_TXFM_PARAM fwd_txfm_param;
2210 fwd_txfm_param.tx_type = tx_type;
2211 fwd_txfm_param.tx_size = TX_4X4;
2212 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
2213 fwd_txfm_param.rd_transform = 0;
2214 fwd_txfm_param.lossless = lossless;
2215 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
2216 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
2217 }
2218#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002219
2220 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002221#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002222 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002223 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002224 const int coeff_ctx =
2225 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002227 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2228 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002229#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002230 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2231 TX_4X4, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232#endif // CONFIG_NEW_QUANT
Angie Chiang22ba7512016-10-20 17:10:33 -07002233 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002234 scan_order->scan, scan_order->neighbors,
2235 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002236 *(tempa + idx) = !(p->eobs[block] == 0);
2237 *(templ + idy) = !(p->eobs[block] == 0);
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002238 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002239#else
2240 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2241 &p->eobs[block], pd->dequant, 0, TX_4X4,
2242 tx_type, &rate_pvq, x->pvq_speed, NULL);
2243 ratey += rate_pvq;
2244#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002245 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2246 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002247#if CONFIG_PVQ
2248 if (!skip) {
2249 for (j = 0; j < tx_blk_size; j++)
2250 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2251#endif
2252 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2253 dst_stride, p->eobs[block], DCT_DCT, 1);
2254#if CONFIG_PVQ
2255 }
2256#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002257 } else {
2258 int64_t dist;
2259 unsigned int tmp;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002260#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002261 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, TX_4X4);
Angie Chiangff6d8902016-10-21 11:02:09 -07002262 const SCAN_ORDER *scan_order = get_scan(cm, TX_4X4, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002263 const int coeff_ctx =
2264 combine_entropy_contexts(*(tempa + idx), *(templ + idy));
2265#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002266 av1_xform_quant_fp_nuq(cm, x, 0, block, row + idy, col + idx,
2267 BLOCK_8X8, TX_4X4, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002268#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002269 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2270 TX_4X4, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002271#endif // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07002272 av1_optimize_b(cm, x, 0, block, TX_4X4, coeff_ctx);
Angie Chiang22ba7512016-10-20 17:10:33 -07002273 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, TX_4X4,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002274 scan_order->scan, scan_order->neighbors,
2275 cpi->sf.use_fast_coef_costing);
Jingning Han3d45c0e2016-11-08 12:35:04 -08002276 *(tempa + idx) = !(p->eobs[block] == 0);
2277 *(templ + idy) = !(p->eobs[block] == 0);
2278 can_skip &= (p->eobs[block] == 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002279#else
2280 skip = av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
2281 &p->eobs[block], pd->dequant, 0, TX_4X4,
2282 tx_type, &rate_pvq, x->pvq_speed, NULL);
2283 ratey += rate_pvq;
2284#endif
2285 // No need for av1_block_error2_c because the ssz is unused
Yaowu Xuf883b422016-08-30 14:01:10 -07002286 av1_inv_txfm_add_4x4(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2287 dst_stride, p->eobs[block], tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288 cpi->fn_ptr[BLOCK_4X4].vf(src, src_stride, dst, dst_stride, &tmp);
2289 dist = (int64_t)tmp << 4;
2290 distortion += dist;
2291 // To use the pixel domain distortion, the step below needs to be
2292 // put behind the inv txfm. Compared to calculating the distortion
2293 // in the frequency domain, the overhead of encoding effort is low.
2294 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2295 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002296#if CONFIG_PVQ
2297 if (!skip) {
2298 for (j = 0; j < tx_blk_size; j++)
2299 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
2300#endif
2301#if CONFIG_PVQ
2302 }
2303#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304 }
2305 }
2306 }
2307
2308 rate += ratey;
2309 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2310
2311 if (this_rd < best_rd) {
2312 *bestrate = rate;
2313 *bestratey = ratey;
2314 *bestdistortion = distortion;
2315 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002316 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002317 *best_mode = mode;
2318 memcpy(a, tempa, num_4x4_blocks_wide * sizeof(tempa[0]));
2319 memcpy(l, templ, num_4x4_blocks_high * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07002320#if CONFIG_PVQ
2321 od_encode_checkpoint(&x->daala_enc, &post_buf);
2322#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2324 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
2325 num_4x4_blocks_wide * 4);
2326 }
2327 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07002328#if CONFIG_PVQ
2329 od_encode_rollback(&x->daala_enc, &pre_buf);
2330#endif
2331 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07002332
2333 if (best_rd >= rd_thresh) return best_rd;
2334
Yushin Cho77bba8d2016-11-04 16:36:56 -07002335#if CONFIG_PVQ
2336 od_encode_rollback(&x->daala_enc, &post_buf);
2337#endif
2338
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002339 if (y_skip) *y_skip &= best_can_skip;
2340
Yaowu Xuc27fc142016-08-22 16:08:15 -07002341 for (idy = 0; idy < num_4x4_blocks_high * 4; ++idy)
2342 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
2343 num_4x4_blocks_wide * 4);
2344
2345 return best_rd;
2346}
2347
Urvang Joshi52648442016-10-13 17:27:51 -07002348static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
2349 MACROBLOCK *mb, int *rate,
2350 int *rate_y, int64_t *distortion,
2351 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002352 int i, j;
2353 const MACROBLOCKD *const xd = &mb->e_mbd;
2354 MODE_INFO *const mic = xd->mi[0];
2355 const MODE_INFO *above_mi = xd->above_mi;
2356 const MODE_INFO *left_mi = xd->left_mi;
2357 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2358 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2359 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2360 int idx, idy;
2361 int cost = 0;
2362 int64_t total_distortion = 0;
2363 int tot_rate_y = 0;
2364 int64_t total_rd = 0;
2365 const int *bmode_costs = cpi->mbmode_cost[0];
2366
2367#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002368 mic->mbmi.intra_filter = INTRA_FILTER_LINEAR;
2369#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002370#if CONFIG_FILTER_INTRA
2371 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2372#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002373
2374 // TODO(any): Add search of the tx_type to improve rd performance at the
2375 // expense of speed.
2376 mic->mbmi.tx_type = DCT_DCT;
2377 mic->mbmi.tx_size = TX_4X4;
2378
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002379 if (y_skip) *y_skip = 1;
2380
Yaowu Xuc27fc142016-08-22 16:08:15 -07002381 // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
2382 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
2383 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
2384 PREDICTION_MODE best_mode = DC_PRED;
2385 int r = INT_MAX, ry = INT_MAX;
2386 int64_t d = INT64_MAX, this_rd = INT64_MAX;
2387 i = idy * 2 + idx;
2388 if (cpi->common.frame_type == KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002389 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, i);
2390 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002391
2392 bmode_costs = cpi->y_mode_costs[A][L];
2393 }
2394
2395 this_rd = rd_pick_intra4x4block(
2396 cpi, mb, idy, idx, &best_mode, bmode_costs,
2397 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002398 &ry, &d, bsize, y_skip, best_rd - total_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002399 if (this_rd >= best_rd - total_rd) return INT64_MAX;
2400
2401 total_rd += this_rd;
2402 cost += r;
2403 total_distortion += d;
2404 tot_rate_y += ry;
2405
2406 mic->bmi[i].as_mode = best_mode;
2407 for (j = 1; j < num_4x4_blocks_high; ++j)
2408 mic->bmi[i + j * 2].as_mode = best_mode;
2409 for (j = 1; j < num_4x4_blocks_wide; ++j)
2410 mic->bmi[i + j].as_mode = best_mode;
2411
2412 if (total_rd >= best_rd) return INT64_MAX;
2413 }
2414 }
2415 mic->mbmi.mode = mic->bmi[3].as_mode;
2416
2417 // Add in the cost of the transform type
2418 if (!xd->lossless[mic->mbmi.segment_id]) {
2419 int rate_tx_type = 0;
2420#if CONFIG_EXT_TX
2421 if (get_ext_tx_types(TX_4X4, bsize, 0) > 1) {
2422 const int eset = get_ext_tx_set(TX_4X4, bsize, 0);
clang-format67948d32016-09-07 22:40:40 -07002423 rate_tx_type = cpi->intra_tx_type_costs[eset][TX_4X4][mic->mbmi.mode]
2424 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002425 }
2426#else
clang-format67948d32016-09-07 22:40:40 -07002427 rate_tx_type =
2428 cpi->intra_tx_type_costs[TX_4X4]
2429 [intra_mode_to_tx_type_context[mic->mbmi.mode]]
2430 [mic->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431#endif
2432 assert(mic->mbmi.tx_size == TX_4X4);
2433 cost += rate_tx_type;
2434 tot_rate_y += rate_tx_type;
2435 }
2436
2437 *rate = cost;
2438 *rate_y = tot_rate_y;
2439 *distortion = total_distortion;
2440
2441 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
2442}
2443
hui su5db97432016-10-14 16:10:14 -07002444#if CONFIG_FILTER_INTRA
2445// Return 1 if an filter intra mode is selected; return 0 otherwise.
2446static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2447 int *rate, int *rate_tokenonly,
2448 int64_t *distortion, int *skippable,
2449 BLOCK_SIZE bsize, int mode_cost,
2450 int64_t *best_rd, uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002451 MACROBLOCKD *const xd = &x->e_mbd;
2452 MODE_INFO *const mic = xd->mi[0];
2453 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002454 int this_rate;
2455 RD_STATS tokenonly_rd_stats;
hui su5db97432016-10-14 16:10:14 -07002456 int filter_intra_selected_flag = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002457 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07002458 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002459 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07002460 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002461 TX_TYPE best_tx_type;
2462
hui su5db97432016-10-14 16:10:14 -07002463 av1_zero(filter_intra_mode_info);
2464 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002465 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07002466#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002468#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002469
2470 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
2471 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07002472 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002473 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2474 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002476 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07002477 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002478 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002479 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002480
2481 if (this_rd < *best_rd) {
2482 *best_rd = this_rd;
2483 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07002484 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002485 best_tx_type = mic->mbmi.tx_type;
2486 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002487 *rate_tokenonly = tokenonly_rd_stats.rate;
2488 *distortion = tokenonly_rd_stats.dist;
2489 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07002490 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 }
2492 }
2493
hui su5db97432016-10-14 16:10:14 -07002494 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002495 mbmi->mode = DC_PRED;
2496 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07002497 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
2498 filter_intra_mode_info.use_filter_intra_mode[0];
2499 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
2500 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501 mbmi->tx_type = best_tx_type;
2502 return 1;
2503 } else {
2504 return 0;
2505 }
2506}
hui su5db97432016-10-14 16:10:14 -07002507#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002508
hui su5db97432016-10-14 16:10:14 -07002509#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510static void pick_intra_angle_routine_sby(
Urvang Joshi52648442016-10-13 17:27:51 -07002511 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002512 int64_t *distortion, int *skippable, int *best_angle_delta,
2513 TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter,
2514 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002515 int this_rate;
2516 RD_STATS tokenonly_rd_stats;
2517 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002518 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002519 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2520 if (tokenonly_rd_stats.rate == INT_MAX) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002521
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002522 this_rate = tokenonly_rd_stats.rate + rate_overhead;
2523 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002524
2525 if (this_rd < *best_rd) {
2526 *best_rd = this_rd;
2527 *best_angle_delta = mbmi->angle_delta[0];
2528 *best_tx_size = mbmi->tx_size;
2529 *best_filter = mbmi->intra_filter;
2530 *best_tx_type = mbmi->tx_type;
2531 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002532 *rate_tokenonly = tokenonly_rd_stats.rate;
2533 *distortion = tokenonly_rd_stats.dist;
2534 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002535 }
2536}
2537
Urvang Joshi52648442016-10-13 17:27:51 -07002538static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2539 int *rate, int *rate_tokenonly,
2540 int64_t *distortion, int *skippable,
2541 BLOCK_SIZE bsize, int rate_overhead,
2542 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002543 MACROBLOCKD *const xd = &x->e_mbd;
2544 MODE_INFO *const mic = xd->mi[0];
2545 MB_MODE_INFO *mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002546 int this_rate;
2547 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 int angle_delta, best_angle_delta = 0, p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07002549 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002550 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
2551 const double rd_adjust = 1.2;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002552 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002553 TX_SIZE best_tx_size = mic->mbmi.tx_size;
2554 TX_TYPE best_tx_type = mbmi->tx_type;
2555
2556 if (ANGLE_FAST_SEARCH) {
2557 int deltas_level1[3] = { 0, -2, 2 };
2558 int deltas_level2[3][2] = {
2559 { -1, 1 }, { -3, -1 }, { 1, 3 },
2560 };
2561 const int level1 = 3, level2 = 2;
2562 int i, j, best_i = -1;
2563
2564 for (i = 0; i < level1; ++i) {
2565 mic->mbmi.angle_delta[0] = deltas_level1[i];
2566 p_angle =
2567 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2568 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2569 int64_t tmp_best_rd;
Yaowu Xuf883b422016-08-30 14:01:10 -07002570 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002571 filter != INTRA_FILTER_LINEAR)
2572 continue;
2573 mic->mbmi.intra_filter = filter;
2574 tmp_best_rd =
2575 (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX)
2576 ? (int64_t)(best_rd * rd_adjust)
2577 : best_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002578 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd);
2579 if (tokenonly_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580 if (i == 0 && filter == INTRA_FILTER_LINEAR)
2581 return best_rd;
2582 else
2583 continue;
2584 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002585 this_rate = tokenonly_rd_stats.rate + rate_overhead +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002586 cpi->intra_filter_cost[intra_filter_ctx][filter];
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002587 this_rd =
2588 RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002589 if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX &&
2590 this_rd > best_rd * rd_adjust)
2591 return best_rd;
2592 if (this_rd < best_rd) {
2593 best_i = i;
2594 best_rd = this_rd;
2595 best_angle_delta = mbmi->angle_delta[0];
2596 best_tx_size = mbmi->tx_size;
2597 best_filter = mbmi->intra_filter;
2598 best_tx_type = mbmi->tx_type;
2599 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002600 *rate_tokenonly = tokenonly_rd_stats.rate;
2601 *distortion = tokenonly_rd_stats.dist;
2602 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603 }
2604 }
2605 }
2606
2607 if (best_i >= 0) {
2608 for (j = 0; j < level2; ++j) {
2609 mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
2610 p_angle =
2611 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2612 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2613 mic->mbmi.intra_filter = filter;
2614 if ((FILTER_FAST_SEARCH ||
Yaowu Xuf883b422016-08-30 14:01:10 -07002615 !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002616 filter != INTRA_FILTER_LINEAR)
2617 continue;
2618 pick_intra_angle_routine_sby(
2619 cpi, x, rate, rate_tokenonly, distortion, skippable,
2620 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2621 bsize,
2622 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2623 &best_rd);
2624 }
2625 }
2626 }
2627 } else {
2628 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
2629 ++angle_delta) {
2630 mbmi->angle_delta[0] = angle_delta;
2631 p_angle =
2632 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
2633 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
2634 mic->mbmi.intra_filter = filter;
Yaowu Xuf883b422016-08-30 14:01:10 -07002635 if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002636 filter != INTRA_FILTER_LINEAR)
2637 continue;
2638 pick_intra_angle_routine_sby(
2639 cpi, x, rate, rate_tokenonly, distortion, skippable,
2640 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2641 bsize,
2642 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2643 &best_rd);
2644 }
2645 }
2646 }
2647
2648 if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) {
2649 mbmi->angle_delta[0] = best_angle_delta;
2650 p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002651 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002652 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
2653 mic->mbmi.intra_filter = filter;
2654 pick_intra_angle_routine_sby(
2655 cpi, x, rate, rate_tokenonly, distortion, skippable,
2656 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
2657 bsize,
2658 rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter],
2659 &best_rd);
2660 }
2661 }
2662 }
2663
2664 mbmi->tx_size = best_tx_size;
2665 mbmi->angle_delta[0] = best_angle_delta;
2666 mic->mbmi.intra_filter = best_filter;
2667 mbmi->tx_type = best_tx_type;
2668 return best_rd;
2669}
2670
2671// Indices are sign, integer, and fractional part of the gradient value
2672static const uint8_t gradient_to_angle_bin[2][7][16] = {
2673 {
2674 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
2675 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
2679 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2680 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2681 },
2682 {
2683 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
2684 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2688 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2689 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2690 },
2691};
2692
2693static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
2694 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
2695};
2696
2697static void angle_estimation(const uint8_t *src, int src_stride, int rows,
2698 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002699 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002700 uint64_t hist[DIRECTIONAL_MODES];
2701 uint64_t hist_sum = 0;
2702
2703 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2704 src += src_stride;
2705 for (r = 1; r < rows; ++r) {
2706 for (c = 1; c < cols; ++c) {
2707 dx = src[c] - src[c - 1];
2708 dy = src[c] - src[c - src_stride];
2709 temp = dx * dx + dy * dy;
2710 if (dy == 0) {
2711 index = 2;
2712 } else {
2713 sn = (dx > 0) ^ (dy > 0);
2714 dx = abs(dx);
2715 dy = abs(dy);
2716 remd = dx % dy;
2717 quot = dx / dy;
2718 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002719 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002720 }
2721 hist[index] += temp;
2722 }
2723 src += src_stride;
2724 }
2725
2726 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2727 for (i = 0; i < INTRA_MODES; ++i) {
2728 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002729 const uint8_t angle_bin = mode_to_angle_bin[i];
2730 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002731 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002732 if (angle_bin > 0) {
2733 score += hist[angle_bin - 1];
2734 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002735 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002736 if (angle_bin < DIRECTIONAL_MODES - 1) {
2737 score += hist[angle_bin + 1];
2738 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002739 }
2740 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2741 directional_mode_skip_mask[i] = 1;
2742 }
2743 }
2744}
2745
Yaowu Xuf883b422016-08-30 14:01:10 -07002746#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
2748 int rows, int cols,
2749 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002750 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002751 uint64_t hist[DIRECTIONAL_MODES];
2752 uint64_t hist_sum = 0;
2753 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
2754
2755 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
2756 src += src_stride;
2757 for (r = 1; r < rows; ++r) {
2758 for (c = 1; c < cols; ++c) {
2759 dx = src[c] - src[c - 1];
2760 dy = src[c] - src[c - src_stride];
2761 temp = dx * dx + dy * dy;
2762 if (dy == 0) {
2763 index = 2;
2764 } else {
2765 sn = (dx > 0) ^ (dy > 0);
2766 dx = abs(dx);
2767 dy = abs(dy);
2768 remd = dx % dy;
2769 quot = dx / dy;
2770 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07002771 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002772 }
2773 hist[index] += temp;
2774 }
2775 src += src_stride;
2776 }
2777
2778 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
2779 for (i = 0; i < INTRA_MODES; ++i) {
2780 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07002781 const uint8_t angle_bin = mode_to_angle_bin[i];
2782 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002783 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07002784 if (angle_bin > 0) {
2785 score += hist[angle_bin - 1];
2786 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002787 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07002788 if (angle_bin < DIRECTIONAL_MODES - 1) {
2789 score += hist[angle_bin + 1];
2790 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002791 }
2792 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
2793 directional_mode_skip_mask[i] = 1;
2794 }
2795 }
2796}
Yaowu Xuf883b422016-08-30 14:01:10 -07002797#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002798#endif // CONFIG_EXT_INTRA
2799
2800// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07002801static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
2802 int *rate, int *rate_tokenonly,
2803 int64_t *distortion, int *skippable,
2804 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002805 uint8_t mode_idx;
2806 PREDICTION_MODE mode_selected = DC_PRED;
2807 MACROBLOCKD *const xd = &x->e_mbd;
2808 MODE_INFO *const mic = xd->mi[0];
2809 int this_rate, this_rate_tokenonly, s;
2810 int64_t this_distortion, this_rd;
2811 TX_SIZE best_tx = TX_4X4;
Urvang Joshib100db72016-10-12 16:28:56 -07002812#if CONFIG_EXT_INTRA || CONFIG_PALETTE
2813 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
2814 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
2815#endif // CONFIG_EXT_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002816#if CONFIG_EXT_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07002817 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002818 int is_directional_mode, rate_overhead, best_angle_delta = 0;
2819 INTRA_FILTER best_filter = INTRA_FILTER_LINEAR;
2820 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002821 const int src_stride = x->plane[0].src.stride;
2822 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002823#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002824#if CONFIG_FILTER_INTRA
2825 int beat_best_rd = 0;
2826 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
2827 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
2828#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829 TX_TYPE best_tx_type = DCT_DCT;
Urvang Joshi52648442016-10-13 17:27:51 -07002830 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07002831#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002832 PALETTE_MODE_INFO palette_mode_info;
2833 PALETTE_MODE_INFO *const pmi = &mic->mbmi.palette_mode_info;
2834 uint8_t *best_palette_color_map =
2835 cpi->common.allow_screen_content_tools
2836 ? x->palette_buffer->best_palette_color_map
2837 : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 int palette_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002839#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002840 const MODE_INFO *above_mi = xd->above_mi;
2841 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07002842 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
2843 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
2845 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002846#if CONFIG_PVQ
2847 od_rollback_buffer pre_buf, post_buf;
2848
2849 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2850 od_encode_checkpoint(&x->daala_enc, &post_buf);
2851#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852 bmode_costs = cpi->y_mode_costs[A][L];
2853
2854#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855 mic->mbmi.angle_delta[0] = 0;
2856 memset(directional_mode_skip_mask, 0,
2857 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07002858#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002859 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2860 highbd_angle_estimation(src, src_stride, rows, cols,
2861 directional_mode_skip_mask);
2862 else
2863#endif
2864 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
2865#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002866#if CONFIG_FILTER_INTRA
2867 filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2868 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2869#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07002870#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 palette_mode_info.palette_size[0] = 0;
2872 pmi->palette_size[0] = 0;
2873 if (above_mi)
2874 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
2875 if (left_mi)
2876 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002877#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002878
2879 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
2880 x->use_default_intra_tx_type = 1;
2881 else
2882 x->use_default_intra_tx_type = 0;
2883
2884 /* Y Search for intra prediction mode */
2885 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002886 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002887 if (mode_idx == FINAL_MODE_SEARCH) {
2888 if (x->use_default_intra_tx_type == 0) break;
2889 mic->mbmi.mode = mode_selected;
2890 x->use_default_intra_tx_type = 0;
2891 } else {
2892 mic->mbmi.mode = mode_idx;
2893 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002894#if CONFIG_PVQ
2895 od_encode_rollback(&x->daala_enc, &pre_buf);
2896#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002897#if CONFIG_EXT_INTRA
2898 is_directional_mode =
2899 (mic->mbmi.mode != DC_PRED && mic->mbmi.mode != TM_PRED);
2900 if (is_directional_mode && directional_mode_skip_mask[mic->mbmi.mode])
2901 continue;
2902 if (is_directional_mode) {
2903 rate_overhead = bmode_costs[mic->mbmi.mode] +
2904 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
2905 this_rate_tokenonly = INT_MAX;
2906 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate,
2907 &this_rate_tokenonly, &this_distortion,
2908 &s, bsize, rate_overhead, best_rd);
2909 } else {
2910 mic->mbmi.angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002911 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2912 this_rate_tokenonly = this_rd_stats.rate;
2913 this_distortion = this_rd_stats.dist;
2914 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002915 }
2916#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002917 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
2918 this_rate_tokenonly = this_rd_stats.rate;
2919 this_distortion = this_rd_stats.dist;
2920 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002921#endif // CONFIG_EXT_INTRA
2922
2923 if (this_rate_tokenonly == INT_MAX) continue;
2924
2925 this_rate = this_rate_tokenonly + bmode_costs[mic->mbmi.mode];
2926
2927 if (!xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2928 // super_block_yrd above includes the cost of the tx_size in the
2929 // tokenonly rate, but for intra blocks, tx_size is always coded
2930 // (prediction granularity), so we account for it in the full rate,
2931 // not the tokenonly rate.
2932 this_rate_tokenonly -=
clang-format67948d32016-09-07 22:40:40 -07002933 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07002934 [tx_size_to_depth(mic->mbmi.tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002935 }
Urvang Joshib100db72016-10-12 16:28:56 -07002936#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002937 if (cpi->common.allow_screen_content_tools && mic->mbmi.mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07002938 this_rate += av1_cost_bit(
2939 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07002940#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07002941#if CONFIG_FILTER_INTRA
2942 if (mic->mbmi.mode == DC_PRED)
2943 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
2944#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002945#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002946 if (is_directional_mode) {
2947 int p_angle;
2948 this_rate +=
2949 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
2950 MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]);
2951 p_angle = mode_to_angle_map[mic->mbmi.mode] +
2952 mic->mbmi.angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07002953 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07002954 this_rate +=
2955 cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter];
2956 }
2957#endif // CONFIG_EXT_INTRA
2958 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07002959#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07002960 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002961 filter_intra_mode_skip_mask ^= (1 << mic->mbmi.mode);
2962 }
hui su5db97432016-10-14 16:10:14 -07002963#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002964
2965 if (this_rd < best_rd) {
2966 mode_selected = mic->mbmi.mode;
2967 best_rd = this_rd;
2968 best_tx = mic->mbmi.tx_size;
2969#if CONFIG_EXT_INTRA
2970 best_angle_delta = mic->mbmi.angle_delta[0];
2971 best_filter = mic->mbmi.intra_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002972#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07002973#if CONFIG_FILTER_INTRA
2974 beat_best_rd = 1;
2975#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976 best_tx_type = mic->mbmi.tx_type;
2977 *rate = this_rate;
2978 *rate_tokenonly = this_rate_tokenonly;
2979 *distortion = this_distortion;
2980 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002981#if CONFIG_PVQ
2982 od_encode_checkpoint(&x->daala_enc, &post_buf);
2983#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002984 }
2985 }
2986
Yushin Cho77bba8d2016-11-04 16:36:56 -07002987#if CONFIG_PVQ
2988 od_encode_rollback(&x->daala_enc, &post_buf);
2989#endif
2990
Urvang Joshib100db72016-10-12 16:28:56 -07002991#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002992 if (cpi->common.allow_screen_content_tools)
2993 rd_pick_palette_intra_sby(cpi, x, bsize, palette_ctx, bmode_costs[DC_PRED],
2994 &palette_mode_info, best_palette_color_map,
2995 &best_tx, &best_tx_type, &mode_selected,
2996 &best_rd);
Urvang Joshib100db72016-10-12 16:28:56 -07002997#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002998
hui su5db97432016-10-14 16:10:14 -07002999#if CONFIG_FILTER_INTRA
3000 if (beat_best_rd) {
3001 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3002 skippable, bsize, bmode_costs[DC_PRED],
3003 &best_rd, filter_intra_mode_skip_mask)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003004 mode_selected = mic->mbmi.mode;
3005 best_tx = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003006 filter_intra_mode_info = mic->mbmi.filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003007 best_tx_type = mic->mbmi.tx_type;
3008 }
3009 }
3010
hui su5db97432016-10-14 16:10:14 -07003011 mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] =
3012 filter_intra_mode_info.use_filter_intra_mode[0];
3013 if (filter_intra_mode_info.use_filter_intra_mode[0]) {
3014 mic->mbmi.filter_intra_mode_info.filter_intra_mode[0] =
3015 filter_intra_mode_info.filter_intra_mode[0];
Urvang Joshib100db72016-10-12 16:28:56 -07003016#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003017 palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003018#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003019 }
hui su5db97432016-10-14 16:10:14 -07003020#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003021
3022 mic->mbmi.mode = mode_selected;
3023 mic->mbmi.tx_size = best_tx;
3024#if CONFIG_EXT_INTRA
3025 mic->mbmi.angle_delta[0] = best_angle_delta;
3026 mic->mbmi.intra_filter = best_filter;
3027#endif // CONFIG_EXT_INTRA
3028 mic->mbmi.tx_type = best_tx_type;
Urvang Joshib100db72016-10-12 16:28:56 -07003029#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003030 pmi->palette_size[0] = palette_mode_info.palette_size[0];
3031 if (palette_mode_info.palette_size[0] > 0) {
3032 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
3033 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
3034 memcpy(xd->plane[0].color_index_map, best_palette_color_map,
3035 rows * cols * sizeof(best_palette_color_map[0]));
3036 }
Urvang Joshib100db72016-10-12 16:28:56 -07003037#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003038
3039 return best_rd;
3040}
3041
Yue Chena1e48dc2016-08-29 17:29:33 -07003042// Return value 0: early termination triggered, no valid rd cost available;
3043// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003044static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3045 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3046 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003047 MACROBLOCKD *const xd = &x->e_mbd;
3048 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3049 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3050 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003051 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003052 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003053
3054 if (ref_best_rd < 0) is_cost_valid = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003055#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003056 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003057 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3058 av1_subtract_plane(x, bsize, plane);
3059 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003060#endif
Yue Chena1e48dc2016-08-29 17:29:33 -07003061
Yushin Cho09de28b2016-06-21 14:51:23 -07003062 if (is_cost_valid) {
3063 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003064 RD_STATS pn_rd_stats;
3065 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3066 uv_tx_size, cpi->sf.use_fast_coef_costing);
3067 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003068 is_cost_valid = 0;
3069 break;
3070 }
Angie Chiang284d7772016-11-08 11:06:45 -08003071 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3072 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003073 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003074 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003075 is_cost_valid = 0;
3076 break;
3077 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003078 }
3079 }
3080
3081 if (!is_cost_valid) {
3082 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003083 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003084 }
3085
3086 return is_cost_valid;
3087}
3088
Yaowu Xuc27fc142016-08-22 16:08:15 -07003089#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003090void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3091 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003092 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003093 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003094 MACROBLOCKD *xd = &x->e_mbd;
3095 const struct macroblock_plane *const p = &x->plane[plane];
3096 struct macroblockd_plane *const pd = &xd->plane[plane];
3097 int64_t tmp;
3098 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
3099 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
3100 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003101 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003102 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003103 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003104 int bh = block_size_high[txm_bsize];
3105 int bw = block_size_wide[txm_bsize];
3106 int txb_h = tx_size_high_unit[tx_size];
3107 int txb_w = tx_size_wide_unit[tx_size];
3108
Yaowu Xuc27fc142016-08-22 16:08:15 -07003109 int src_stride = p->src.stride;
3110 uint8_t *src = &p->src.buf[4 * blk_row * src_stride + 4 * blk_col];
3111 uint8_t *dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Yaowu Xuf883b422016-08-30 14:01:10 -07003112#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003113 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3114 uint8_t *rec_buffer;
3115#else
3116 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003117#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003118 int max_blocks_high = block_size_high[plane_bsize];
3119 int max_blocks_wide = block_size_wide[plane_bsize];
3120 const int diff_stride = max_blocks_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003121 const int16_t *diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003122 int txb_coeff_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003123#if CONFIG_EXT_TX
3124 assert(tx_size < TX_SIZES);
3125#endif // CONFIG_EXT_TX
3126
3127 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003128 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003129 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003130 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3131
3132 max_blocks_high >>= tx_size_wide_log2[0];
3133 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003134
3135#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07003136 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07003137 tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003138#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003139 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07003140 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003141#endif // CONFIG_NEW_QUANT
3142
Yushin Cho721868c2016-11-14 16:04:33 +09003143 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003144 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003145
3146// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003147#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3149 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003150 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003151 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003152 } else {
3153 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003154 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003155 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003156 }
3157#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003158 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003159 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003160#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161
Jingning Han9fdc4222016-10-27 21:32:19 -07003162 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003163 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003164 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3165 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 tmp = 0;
3167 for (idy = 0; idy < blocks_height; idy += 2) {
3168 for (idx = 0; idx < blocks_width; idx += 2) {
3169 const int16_t *d = diff + 4 * idy * diff_stride + 4 * idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07003170 tmp += aom_sum_squares_2d_i16(d, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003171 }
3172 }
3173 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003174 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003175 }
3176
Yaowu Xuf883b422016-08-30 14:01:10 -07003177#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003178 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3179 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003180#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003181 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003182
3183 if (p->eobs[block] > 0) {
3184 INV_TXFM_PARAM inv_txfm_param;
3185 inv_txfm_param.tx_type = tx_type;
3186 inv_txfm_param.tx_size = tx_size;
3187 inv_txfm_param.eob = p->eobs[block];
3188 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003189// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003190#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003191 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3192 inv_txfm_param.bd = xd->bd;
3193 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3194 } else {
3195 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3196 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003197#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003198 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003199#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003200
Jingning Han4b47c932016-11-03 09:20:08 -07003201 if (txb_w + blk_col > max_blocks_wide ||
3202 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203 int idx, idy;
3204 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003205 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3206 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003207 tmp = 0;
3208 for (idy = 0; idy < blocks_height; idy += 2) {
3209 for (idx = 0; idx < blocks_width; idx += 2) {
3210 uint8_t *const s = src + 4 * idy * src_stride + 4 * idx;
3211 uint8_t *const r = rec_buffer + 4 * idy * MAX_TX_SIZE + 4 * idx;
3212 cpi->fn_ptr[BLOCK_8X8].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
3213 tmp += this_dist;
3214 }
3215 }
3216 } else {
3217 uint32_t this_dist;
3218 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3219 &this_dist);
3220 tmp = this_dist;
3221 }
3222 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003223 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003224 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3225 scan_order->scan, scan_order->neighbors, 0);
3226 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003227 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003228
Angie Chiangd81fdb42016-11-03 12:20:58 -07003229#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003230 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3231 txb_coeff_cost);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003232#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003233}
3234
Yaowu Xuf883b422016-08-30 14:01:10 -07003235static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003236 int blk_col, int plane, int block, int block32,
3237 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003238 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3239 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003240 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003241 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003242 MACROBLOCKD *const xd = &x->e_mbd;
3243 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3244 struct macroblock_plane *const p = &x->plane[plane];
3245 struct macroblockd_plane *const pd = &xd->plane[plane];
3246 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3247 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003248 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003249 [MAX_MIB_SIZE] =
3250 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003251 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3252 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003253 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003254 int64_t this_rd = INT64_MAX;
3255 ENTROPY_CONTEXT *pta = ta + blk_col;
3256 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003257 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003258 int ctx =
3259 txfm_partition_context(tx_above + (blk_col >> 1),
3260 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003261
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003263 int tmp_eob = 0;
3264 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003265 RD_STATS sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003266
Jingning Han63cbf342016-11-09 15:37:48 -08003267 av1_init_rd_stats(&sum_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003268#if CONFIG_EXT_TX
3269 assert(tx_size < TX_SIZES);
3270#endif // CONFIG_EXT_TX
3271
3272 if (ref_best_rd < 0) {
3273 *is_cost_valid = 0;
3274 return;
3275 }
3276
Jingning Hance059e82016-10-31 16:27:28 -07003277 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278
Angie Chiangc0feea82016-11-03 15:36:18 -07003279 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003280
3281 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3282
3283 zero_blk_rate =
3284 x->token_costs[tx_size][pd->plane_type][1][0][0][coeff_ctx][EOB_TOKEN];
3285
3286 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3287 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003288
3289 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3290 rd_stats_stack[block32].rate != INT_MAX) {
3291 *rd_stats = rd_stats_stack[block32];
3292 p->eobs[block] = !rd_stats->skip;
3293 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3294 } else {
3295 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3296 plane_bsize, coeff_ctx, rd_stats);
3297 if (tx_size == TX_32X32) {
3298 rd_stats_stack[block32] = *rd_stats;
3299 }
3300 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003301
Angie Chiangb5dda482016-11-02 16:19:58 -07003302 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
3303 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
3304 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003305 !xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003306 rd_stats->rate = zero_blk_rate;
3307 rd_stats->dist = rd_stats->sse;
3308 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3310 p->eobs[block] = 0;
3311 } else {
3312 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003313 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003314 }
3315
Jingning Han571189c2016-10-24 10:38:43 -07003316 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07003317 rd_stats->rate +=
3318 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
3319 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003320 tmp_eob = p->eobs[block];
3321 }
3322
Jingning Han571189c2016-10-24 10:38:43 -07003323 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07003324 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3325 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003326 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07003327 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003328 int this_cost_valid = 1;
3329 int64_t tmp_rd = 0;
3330
Angie Chiangd7246172016-11-03 11:49:15 -07003331 sum_rd_stats.rate =
3332 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003333#if CONFIG_EXT_TX
3334 assert(tx_size < TX_SIZES);
3335#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003336 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003337 int offsetr = blk_row + (i >> 1) * bsl;
3338 int offsetc = blk_col + (i & 0x01) * bsl;
3339
3340 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3341
Jingning Han63cbf342016-11-09 15:37:48 -08003342 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07003343 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08003344 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
3345 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003346
Angie Chiangc0feea82016-11-03 15:36:18 -07003347 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07003348
Angie Chiangd7246172016-11-03 11:49:15 -07003349 tmp_rd =
3350 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003351 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07003352 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003353 }
3354 if (this_cost_valid) sum_rd = tmp_rd;
3355 }
3356
3357 if (this_rd < sum_rd) {
3358 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07003359 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
3360 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
3362 tx_size);
3363 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07003364 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
3365 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003366 inter_tx_size[idy][idx] = tx_size;
3367 mbmi->tx_size = tx_size;
3368 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003369 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003370 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07003371 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003372 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
3373 }
3374}
3375
Angie Chiangb5dda482016-11-02 16:19:58 -07003376static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3377 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003378 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003379 MACROBLOCKD *const xd = &x->e_mbd;
3380 int is_cost_valid = 1;
3381 int64_t this_rd = 0;
3382
3383 if (ref_best_rd < 0) is_cost_valid = 0;
3384
Angie Chiangc0feea82016-11-03 15:36:18 -07003385 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003386
3387 if (is_cost_valid) {
3388 const struct macroblockd_plane *const pd = &xd->plane[0];
3389 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3390 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3391 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003392 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003393 const int bh = tx_size_high_unit[max_tx_size];
3394 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003395 int idx, idy;
3396 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003397 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003398 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
3400 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
3401 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
3402 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
3403
Angie Chiangb5dda482016-11-02 16:19:58 -07003404 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003405 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003406
Yaowu Xuf883b422016-08-30 14:01:10 -07003407 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003408 memcpy(tx_above, xd->above_txfm_context,
3409 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
3410 memcpy(tx_left, xd->left_txfm_context,
3411 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
3412
3413 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003414 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08003415 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07003416 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07003417 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003418 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07003419 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07003420 this_rd += AOMMIN(
3421 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
3422 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003423 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08003424 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003425 }
3426 }
3427 }
3428
Angie Chiangb5dda482016-11-02 16:19:58 -07003429 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3430 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 if (this_rd > ref_best_rd) is_cost_valid = 0;
3432
3433 if (!is_cost_valid) {
3434 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003435 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003436 }
3437}
3438
Yaowu Xuf883b422016-08-30 14:01:10 -07003439static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07003440 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08003441 int64_t ref_best_rd, TX_TYPE tx_type,
3442 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003443 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003444 MACROBLOCKD *const xd = &x->e_mbd;
3445 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003446 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003447 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
3448 int s0 = av1_cost_bit(skip_prob, 0);
3449 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07003451 int row, col;
3452 const int max_blocks_high = max_block_high(xd, bsize, 0);
3453 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003454
3455 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07003456 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08003457 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yue Chena1e48dc2016-08-29 17:29:33 -07003458#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07003459 if (is_rect_tx_allowed(xd, mbmi)) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003460 RD_STATS rect_rd_stats;
3461 int64_t rd_rect_tx;
Yue Chena1e48dc2016-08-29 17:29:33 -07003462 int tx_size_cat = inter_tx_size_cat_lookup[bsize];
3463 TX_SIZE tx_size = max_txsize_rect_lookup[bsize];
3464 TX_SIZE var_tx_size = mbmi->tx_size;
3465
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003466 txfm_rd_in_plane(x, cpi, &rect_rd_stats, ref_best_rd, 0, bsize, tx_size,
3467 cpi->sf.use_fast_coef_costing);
Yue Chena1e48dc2016-08-29 17:29:33 -07003468
Angie Chiangb5dda482016-11-02 16:19:58 -07003469 if (rd_stats->rate != INT_MAX) {
3470 rd_stats->rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 0);
3471 if (rd_stats->skip) {
3472 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yue Chena1e48dc2016-08-29 17:29:33 -07003473 } else {
Angie Chiangb5dda482016-11-02 16:19:58 -07003474 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yue Chena1e48dc2016-08-29 17:29:33 -07003475 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
Angie Chiangb5dda482016-11-02 16:19:58 -07003476 !rd_stats->skip)
3477 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yue Chena1e48dc2016-08-29 17:29:33 -07003478 }
3479 } else {
3480 rd = INT64_MAX;
3481 }
3482
Angie Chiangb5dda482016-11-02 16:19:58 -07003483 if (rect_rd_stats.rate != INT_MAX) {
3484 rect_rd_stats.rate += av1_cost_bit(cm->fc->rect_tx_prob[tx_size_cat], 1);
3485 if (rect_rd_stats.skip) {
3486 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, s1, rect_rd_stats.sse);
Yue Chena1e48dc2016-08-29 17:29:33 -07003487 } else {
Angie Chiangb5dda482016-11-02 16:19:58 -07003488 rd_rect_tx = RDCOST(x->rdmult, x->rddiv, rect_rd_stats.rate + s0,
3489 rect_rd_stats.dist);
Yue Chena1e48dc2016-08-29 17:29:33 -07003490 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
Angie Chiangb5dda482016-11-02 16:19:58 -07003491 !(rect_rd_stats.skip))
3492 rd_rect_tx = AOMMIN(
3493 rd_rect_tx, RDCOST(x->rdmult, x->rddiv, s1, rect_rd_stats.sse));
Yue Chena1e48dc2016-08-29 17:29:33 -07003494 }
3495 } else {
3496 rd_rect_tx = INT64_MAX;
3497 }
3498
3499 if (rd_rect_tx < rd) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003500 *rd_stats = rect_rd_stats;
3501 if (!xd->lossless[mbmi->segment_id]) x->blk_skip[0][0] = rd_stats->skip;
Yue Chena1e48dc2016-08-29 17:29:33 -07003502 mbmi->tx_size = tx_size;
3503 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
3504 } else {
3505 mbmi->tx_size = var_tx_size;
3506 }
3507 }
3508#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003509
Angie Chiangb5dda482016-11-02 16:19:58 -07003510 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003511
Jingning Hane67b38a2016-11-04 10:30:00 -07003512 for (row = 0; row < max_blocks_high / 2; ++row)
3513 for (col = 0; col < max_blocks_wide / 2; ++col)
3514 mbmi->min_tx_size = AOMMIN(
3515 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
3516
Yaowu Xuc27fc142016-08-22 16:08:15 -07003517#if CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003518 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003519 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07003520 int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003521 if (is_inter) {
3522 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07003523 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07003524 cpi->inter_tx_type_costs[ext_tx_set]
3525 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01003526 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003527 } else {
3528 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07003529 rd_stats->rate +=
3530 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
3531 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 }
3533 }
3534#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07003535 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
3536 rd_stats->rate +=
3537 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003538#endif // CONFIG_EXT_TX
3539
Angie Chiangb5dda482016-11-02 16:19:58 -07003540 if (rd_stats->skip)
3541 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003542 else
Angie Chiangb5dda482016-11-02 16:19:58 -07003543 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003544
Angie Chiangb5dda482016-11-02 16:19:58 -07003545 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
3546 !(rd_stats->skip))
3547 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003548
3549 return rd;
3550}
3551
Angie Chiangb5dda482016-11-02 16:19:58 -07003552static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
3553 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003554 int64_t ref_best_rd) {
3555 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
3556 MACROBLOCKD *const xd = &x->e_mbd;
3557 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3558 int64_t rd = INT64_MAX;
3559 int64_t best_rd = INT64_MAX;
3560 TX_TYPE tx_type, best_tx_type = DCT_DCT;
3561 const int is_inter = is_inter_block(mbmi);
3562 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07003563 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07003564 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
3566 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 4);
3567 int idx, idy;
3568 int prune = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08003569 RD_STATS rd_stats_stack[4];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570#if CONFIG_EXT_TX
3571 int ext_tx_set = get_ext_tx_set(max_tx_size, bsize, is_inter);
3572#endif // CONFIG_EXT_TX
3573
3574 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
3575#if CONFIG_EXT_TX
3576 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
3577#else
3578 prune = prune_tx_types(cpi, bsize, x, xd, 0);
3579#endif
3580
Angie Chiangc0feea82016-11-03 15:36:18 -07003581 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003582
Jingning Han63cbf342016-11-09 15:37:48 -08003583 for (idx = 0; idx < 4; ++idx) av1_invalid_rd_stats(&rd_stats_stack[idx]);
3584
Yaowu Xuc27fc142016-08-22 16:08:15 -07003585 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07003586 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003587 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003588#if CONFIG_EXT_TX
3589 if (is_inter) {
3590 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
3591 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
3592 if (!do_tx_type_search(tx_type, prune)) continue;
3593 }
3594 } else {
3595 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
3596 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
3597 }
3598 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
3599 }
3600#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
3602 !do_tx_type_search(tx_type, prune))
3603 continue;
3604#endif // CONFIG_EXT_TX
3605 if (is_inter && x->use_default_inter_tx_type &&
3606 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
3607 continue;
3608
Jingning Hane67b38a2016-11-04 10:30:00 -07003609 if (xd->lossless[mbmi->segment_id])
3610 if (tx_type != DCT_DCT) continue;
3611
Angie Chiangb5dda482016-11-02 16:19:58 -07003612 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003613 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614
3615 if (rd < best_rd) {
3616 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07003617 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 best_tx_type = mbmi->tx_type;
3619 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07003620 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003621 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
3622 for (idy = 0; idy < xd->n8_h; ++idy)
3623 for (idx = 0; idx < xd->n8_w; ++idx)
3624 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
3625 }
3626 }
3627
3628 mbmi->tx_type = best_tx_type;
3629 for (idy = 0; idy < xd->n8_h; ++idy)
3630 for (idx = 0; idx < xd->n8_w; ++idx)
3631 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
3632 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07003633 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003634 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
3635}
3636
Yaowu Xuf883b422016-08-30 14:01:10 -07003637static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638 int blk_col, int plane, int block, TX_SIZE tx_size,
3639 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07003640 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003641 MACROBLOCKD *const xd = &x->e_mbd;
3642 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3643 struct macroblock_plane *const p = &x->plane[plane];
3644 struct macroblockd_plane *const pd = &xd->plane[plane];
3645 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
3646 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3647 const int tx_col = blk_col >> (1 - pd->subsampling_x);
3648 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07003649 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3650 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003651
3652#if CONFIG_EXT_TX
3653 assert(tx_size < TX_SIZES);
3654#endif // CONFIG_EXT_TX
3655
Yaowu Xuc27fc142016-08-22 16:08:15 -07003656 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3657
Debargha Mukherjee2f123402016-08-30 17:43:38 -07003658 plane_tx_size =
3659 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
3660 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003661
3662 if (tx_size == plane_tx_size) {
3663 int coeff_ctx, i;
3664 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
3665 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07003666 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07003667 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003668 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07003669
Jingning Han58224042016-10-27 16:35:32 -07003670 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003671 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07003672 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003673 tl[i] = !(p->eobs[block] == 0);
3674 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07003675 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
3676 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07003677 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003678 int i;
3679
3680 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681
3682 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07003683 int offsetr = blk_row + (i >> 1) * bsl;
3684 int offsetc = blk_col + (i & 0x01) * bsl;
3685
3686 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
3687
3688 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
3689 above_ctx, left_ctx, rd_stats);
3690 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003691 }
3692 }
3693}
3694
3695// Return value 0: early termination triggered, no valid rd cost available;
3696// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07003697static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
3698 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3699 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003700 MACROBLOCKD *const xd = &x->e_mbd;
3701 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3702 int plane;
3703 int is_cost_valid = 1;
3704 int64_t this_rd;
3705
3706 if (ref_best_rd < 0) is_cost_valid = 0;
3707
Angie Chiangc0feea82016-11-03 15:36:18 -07003708 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003709
3710#if CONFIG_EXT_TX && CONFIG_RECT_TX
3711 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08003712 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07003713 }
3714#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
3715
Yaowu Xuc27fc142016-08-22 16:08:15 -07003716 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003717 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07003718 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 }
3720
Yaowu Xuc27fc142016-08-22 16:08:15 -07003721 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3722 const struct macroblockd_plane *const pd = &xd->plane[plane];
3723 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
3724 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
3725 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08003726 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07003727 const int bh = tx_size_high_unit[max_tx_size];
3728 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003729 int idx, idy;
3730 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07003731 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
3733 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07003734 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07003735 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003736
Yaowu Xuf883b422016-08-30 14:01:10 -07003737 av1_get_entropy_contexts(bsize, TX_4X4, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003738
3739 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07003740 for (idx = 0; idx < mi_width; idx += bw) {
3741 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07003742 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003743 block += step;
3744 }
3745 }
3746
Angie Chiangb5dda482016-11-02 16:19:58 -07003747 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003748 is_cost_valid = 0;
3749 break;
3750 }
3751
Angie Chiang628d7c92016-11-03 16:24:56 -07003752 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003753
Angie Chiangb5dda482016-11-02 16:19:58 -07003754 this_rd =
3755 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
3756 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003757
3758 if (this_rd > ref_best_rd) {
3759 is_cost_valid = 0;
3760 break;
3761 }
3762 }
3763
3764 if (!is_cost_valid) {
3765 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07003766 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003767 }
3768
3769 return is_cost_valid;
3770}
3771#endif // CONFIG_VAR_TX
3772
Urvang Joshib100db72016-10-12 16:28:56 -07003773#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003774static void rd_pick_palette_intra_sbuv(
Urvang Joshi52648442016-10-13 17:27:51 -07003775 const AV1_COMP *const cpi, MACROBLOCK *x, int dc_mode_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003776 PALETTE_MODE_INFO *palette_mode_info, uint8_t *best_palette_color_map,
3777 PREDICTION_MODE *mode_selected, int64_t *best_rd, int *rate,
3778 int *rate_tokenonly, int64_t *distortion, int *skippable) {
3779 MACROBLOCKD *const xd = &x->e_mbd;
3780 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3781 const BLOCK_SIZE bsize = mbmi->sb_type;
3782 const int rows =
3783 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
3784 const int cols =
3785 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
Angie Chiang284d7772016-11-08 11:06:45 -08003786 int this_rate;
3787 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788 int colors_u, colors_v, colors;
3789 const int src_stride = x->plane[1].src.stride;
3790 const uint8_t *const src_u = x->plane[1].src.buf;
3791 const uint8_t *const src_v = x->plane[2].src.buf;
Angie Chiang284d7772016-11-08 11:06:45 -08003792 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003793
3794 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
3795
hui su5db97432016-10-14 16:10:14 -07003796#if CONFIG_FILTER_INTRA
3797 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3798#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003799
Yaowu Xuf883b422016-08-30 14:01:10 -07003800#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003801 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003802 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
3803 cpi->common.bit_depth);
3804 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
3805 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003806 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003807#endif // CONFIG_AOM_HIGHBITDEPTH
3808 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
3809 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
3810#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003811 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003812#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003813
3814 colors = colors_u > colors_v ? colors_u : colors_v;
3815 if (colors > 1 && colors <= 64) {
3816 int r, c, n, i, j;
3817 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07003818 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 float lb_u, ub_u, val_u;
3820 float lb_v, ub_v, val_v;
3821 float *const data = x->palette_buffer->kmeans_data_buf;
3822 float centroids[2 * PALETTE_MAX_SIZE];
3823 uint8_t *const color_map = xd->plane[1].color_index_map;
3824 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
3825
Yaowu Xuf883b422016-08-30 14:01:10 -07003826#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003827 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
3828 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
3829 if (cpi->common.use_highbitdepth) {
3830 lb_u = src_u16[0];
3831 ub_u = src_u16[0];
3832 lb_v = src_v16[0];
3833 ub_v = src_v16[0];
3834 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003835#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003836 lb_u = src_u[0];
3837 ub_u = src_u[0];
3838 lb_v = src_v[0];
3839 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07003840#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003841 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003842#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003843
3844 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003845#if CONFIG_FILTER_INTRA
3846 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
3847#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003848 for (r = 0; r < rows; ++r) {
3849 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003850#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003851 if (cpi->common.use_highbitdepth) {
3852 val_u = src_u16[r * src_stride + c];
3853 val_v = src_v16[r * src_stride + c];
3854 data[(r * cols + c) * 2] = val_u;
3855 data[(r * cols + c) * 2 + 1] = val_v;
3856 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003857#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858 val_u = src_u[r * src_stride + c];
3859 val_v = src_v[r * src_stride + c];
3860 data[(r * cols + c) * 2] = val_u;
3861 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07003862#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003864#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865 if (val_u < lb_u)
3866 lb_u = val_u;
3867 else if (val_u > ub_u)
3868 ub_u = val_u;
3869 if (val_v < lb_v)
3870 lb_v = val_v;
3871 else if (val_v > ub_v)
3872 ub_v = val_v;
3873 }
3874 }
3875
3876 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
3877 --n) {
3878 for (i = 0; i < n; ++i) {
3879 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
3880 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
3881 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003882 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003883 pmi->palette_size[1] = n;
3884 for (i = 1; i < 3; ++i) {
3885 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003886#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003887 if (cpi->common.use_highbitdepth)
3888 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
3889 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
3890 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003891#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003892 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
3893 clip_pixel((int)centroids[j * 2 + i - 1]);
3894 }
3895 }
3896
Angie Chiang284d7772016-11-08 11:06:45 -08003897 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3898 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003899 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08003900 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07003901 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003902 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - 2] +
3903 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07003904 av1_cost_bit(
3905 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003906
3907 for (i = 0; i < rows; ++i) {
3908 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07003909 int color_idx;
3910 const int color_ctx = av1_get_palette_color_context(
3911 color_map, cols, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003912 assert(color_idx >= 0 && color_idx < n);
3913 this_rate += cpi->palette_uv_color_cost[n - 2][color_ctx][color_idx];
3914 }
3915 }
3916
Angie Chiang284d7772016-11-08 11:06:45 -08003917 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918 if (this_rd < *best_rd) {
3919 *best_rd = this_rd;
3920 *palette_mode_info = *pmi;
3921 memcpy(best_palette_color_map, color_map,
3922 rows * cols * sizeof(best_palette_color_map[0]));
3923 *mode_selected = DC_PRED;
3924 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003925 *distortion = tokenonly_rd_stats.dist;
3926 *rate_tokenonly = tokenonly_rd_stats.rate;
3927 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003928 }
3929 }
3930 }
3931}
Urvang Joshib100db72016-10-12 16:28:56 -07003932#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003933
hui su5db97432016-10-14 16:10:14 -07003934#if CONFIG_FILTER_INTRA
3935// Return 1 if an filter intra mode is selected; return 0 otherwise.
3936static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
3937 int *rate, int *rate_tokenonly,
3938 int64_t *distortion, int *skippable,
3939 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003940 MACROBLOCKD *const xd = &x->e_mbd;
3941 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07003942 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08003943 int this_rate;
3944 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07003945 FILTER_INTRA_MODE mode;
3946 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08003947 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003948
hui su5db97432016-10-14 16:10:14 -07003949 av1_zero(filter_intra_mode_info);
3950 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003952#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003953 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003954#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955
3956 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07003957 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08003958 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959 continue;
3960
Angie Chiang284d7772016-11-08 11:06:45 -08003961 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003962 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003963 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
3964 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08003965 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 if (this_rd < *best_rd) {
3967 *best_rd = this_rd;
3968 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08003969 *rate_tokenonly = tokenonly_rd_stats.rate;
3970 *distortion = tokenonly_rd_stats.dist;
3971 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003972 filter_intra_mode_info = mbmi->filter_intra_mode_info;
3973 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003974 }
3975 }
3976
hui su5db97432016-10-14 16:10:14 -07003977 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07003979 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
3980 filter_intra_mode_info.use_filter_intra_mode[1];
3981 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
3982 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003983 return 1;
3984 } else {
3985 return 0;
3986 }
3987}
hui su5db97432016-10-14 16:10:14 -07003988#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989
hui su5db97432016-10-14 16:10:14 -07003990#if CONFIG_EXT_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003991static void pick_intra_angle_routine_sbuv(
3992 const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly,
3993 int64_t *distortion, int *skippable, int *best_angle_delta,
3994 BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003995 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08003996 int this_rate;
3997 int64_t this_rd;
3998 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999
Angie Chiang284d7772016-11-08 11:06:45 -08004000 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004001
Angie Chiang284d7772016-11-08 11:06:45 -08004002 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4003 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004004 if (this_rd < *best_rd) {
4005 *best_rd = this_rd;
4006 *best_angle_delta = mbmi->angle_delta[1];
4007 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004008 *rate_tokenonly = tokenonly_rd_stats.rate;
4009 *distortion = tokenonly_rd_stats.dist;
4010 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004011 }
4012}
4013
Urvang Joshi52648442016-10-13 17:27:51 -07004014static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4015 int *rate, int *rate_tokenonly,
4016 int64_t *distortion, int *skippable,
4017 BLOCK_SIZE bsize, int rate_overhead,
4018 int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004019 MACROBLOCKD *const xd = &x->e_mbd;
4020 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004021 int this_rate;
4022 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004023 int angle_delta, best_angle_delta = 0;
4024 const double rd_adjust = 1.2;
Angie Chiang284d7772016-11-08 11:06:45 -08004025 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004026
4027 *rate_tokenonly = INT_MAX;
4028 if (ANGLE_FAST_SEARCH) {
4029 int deltas_level1[3] = { 0, -2, 2 };
4030 int deltas_level2[3][2] = {
4031 { -1, 1 }, { -3, -1 }, { 1, 3 },
4032 };
4033 const int level1 = 3, level2 = 2;
4034 int i, j, best_i = -1;
4035
4036 for (i = 0; i < level1; ++i) {
4037 int64_t tmp_best_rd;
4038 mbmi->angle_delta[1] = deltas_level1[i];
4039 tmp_best_rd = (i == 0 && best_rd < INT64_MAX)
4040 ? (int64_t)(best_rd * rd_adjust)
4041 : best_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004042 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004043 if (i == 0)
4044 break;
4045 else
4046 continue;
4047 }
Angie Chiang284d7772016-11-08 11:06:45 -08004048 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4049 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004050 if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) break;
4051 if (this_rd < best_rd) {
4052 best_i = i;
4053 best_rd = this_rd;
4054 best_angle_delta = mbmi->angle_delta[1];
4055 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004056 *rate_tokenonly = tokenonly_rd_stats.rate;
4057 *distortion = tokenonly_rd_stats.dist;
4058 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059 }
4060 }
4061
4062 if (best_i >= 0) {
4063 for (j = 0; j < level2; ++j) {
4064 mbmi->angle_delta[1] = deltas_level2[best_i][j];
4065 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4066 skippable, &best_angle_delta, bsize,
4067 rate_overhead, &best_rd);
4068 }
4069 }
4070 } else {
4071 for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
4072 ++angle_delta) {
4073 mbmi->angle_delta[1] = angle_delta;
4074 pick_intra_angle_routine_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4075 skippable, &best_angle_delta, bsize,
4076 rate_overhead, &best_rd);
4077 }
4078 }
4079
4080 mbmi->angle_delta[1] = best_angle_delta;
4081 return *rate_tokenonly != INT_MAX;
4082}
4083#endif // CONFIG_EXT_INTRA
4084
Urvang Joshi52648442016-10-13 17:27:51 -07004085static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4086 int *rate, int *rate_tokenonly,
4087 int64_t *distortion, int *skippable,
4088 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004089 MACROBLOCKD *xd = &x->e_mbd;
4090 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4091 PREDICTION_MODE mode;
4092 PREDICTION_MODE mode_selected = DC_PRED;
4093 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004094 int this_rate;
4095 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004096#if CONFIG_PVQ
4097 od_rollback_buffer buf;
4098
4099 od_encode_checkpoint(&x->daala_enc, &buf);
4100#endif
Urvang Joshib100db72016-10-12 16:28:56 -07004101#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004102 const int rows =
4103 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
4104 const int cols =
4105 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
4106 PALETTE_MODE_INFO palette_mode_info;
4107 PALETTE_MODE_INFO *const pmi = &xd->mi[0]->mbmi.palette_mode_info;
4108 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004109#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004110#if CONFIG_EXT_INTRA
4111 int is_directional_mode, rate_overhead, best_angle_delta = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004112#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004113#if CONFIG_FILTER_INTRA
4114 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
4115
4116 filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4117 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4118#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004119#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120 palette_mode_info.palette_size[1] = 0;
4121 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004122#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004123 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
4124 if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode))) continue;
4125
4126 mbmi->uv_mode = mode;
4127#if CONFIG_EXT_INTRA
4128 is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
4129 rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4130 write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
4131 mbmi->angle_delta[1] = 0;
4132 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
Angie Chiang284d7772016-11-08 11:06:45 -08004133 if (!rd_pick_intra_angle_sbuv(
4134 cpi, x, &this_rate, &tokenonly_rd_stats.rate,
4135 &tokenonly_rd_stats.dist, &tokenonly_rd_stats.skip, bsize,
4136 rate_overhead, best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004137 continue;
4138 } else {
Angie Chiang284d7772016-11-08 11:06:45 -08004139 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004140#if CONFIG_PVQ
4141 od_encode_rollback(&x->daala_enc, &buf);
4142#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004143 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004144 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004145 }
Angie Chiang284d7772016-11-08 11:06:45 -08004146 this_rate =
4147 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004148 if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
4149 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
4150 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151#else
Angie Chiang284d7772016-11-08 11:06:45 -08004152 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004153#if CONFIG_PVQ
4154 od_encode_rollback(&x->daala_enc, &buf);
4155#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004157 }
Angie Chiang284d7772016-11-08 11:06:45 -08004158 this_rate =
4159 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004160#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004161#if CONFIG_FILTER_INTRA
4162 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4163 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4164#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004165#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004166 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4167 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004168 this_rate += av1_cost_bit(
4169 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004170#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004171
Yushin Cho77bba8d2016-11-04 16:36:56 -07004172#if CONFIG_PVQ
4173 // For chroma channels, multiply lambda by 0.5 when doing intra prediction
4174 // NOTE: Chroma intra prediction itself has a separate RDO,
4175 // though final chroma intra mode's D and R is simply added to
4176 // those of luma then global RDO is performed to decide the modes of SB.
4177 // Also, for chroma, the RDO cannot decide tx_size (follow luma's decision)
4178 // or tx_type (DCT only), then only the intra prediction is
4179 // chroma's own mode decision based on separate RDO.
4180 // TODO(yushin) : Seek for more reasonable solution than this.
4181 this_rd = RDCOST(x->rdmult >> (1 * PVQ_CHROMA_RD), x->rddiv, this_rate,
Angie Chiang284d7772016-11-08 11:06:45 -08004182 tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004183 od_encode_rollback(&x->daala_enc, &buf);
4184#else
Angie Chiang284d7772016-11-08 11:06:45 -08004185 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004186#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004187
4188 if (this_rd < best_rd) {
4189 mode_selected = mode;
4190#if CONFIG_EXT_INTRA
4191 best_angle_delta = mbmi->angle_delta[1];
4192#endif // CONFIG_EXT_INTRA
4193 best_rd = this_rd;
4194 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004195 *rate_tokenonly = tokenonly_rd_stats.rate;
4196 *distortion = tokenonly_rd_stats.dist;
4197 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004198 }
4199 }
4200
Urvang Joshib100db72016-10-12 16:28:56 -07004201#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004202 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4203 best_palette_color_map = x->palette_buffer->best_palette_color_map;
4204 rd_pick_palette_intra_sbuv(
4205 cpi, x, cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4206 &palette_mode_info, best_palette_color_map, &mode_selected, &best_rd,
4207 rate, rate_tokenonly, distortion, skippable);
4208 }
Urvang Joshib100db72016-10-12 16:28:56 -07004209#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004210
hui su5db97432016-10-14 16:10:14 -07004211#if CONFIG_FILTER_INTRA
4212 if (mbmi->sb_type >= BLOCK_8X8) {
4213 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
4214 skippable, bsize, &best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215 mode_selected = mbmi->uv_mode;
hui su5db97432016-10-14 16:10:14 -07004216 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004217 }
4218 }
4219
hui su5db97432016-10-14 16:10:14 -07004220 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4221 filter_intra_mode_info.use_filter_intra_mode[1];
4222 if (filter_intra_mode_info.use_filter_intra_mode[1]) {
4223 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4224 filter_intra_mode_info.filter_intra_mode[1];
Urvang Joshib100db72016-10-12 16:28:56 -07004225#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226 palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004227#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 }
hui su5db97432016-10-14 16:10:14 -07004229#endif // CONFIG_FILTER_INTRA
4230
4231#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004232 mbmi->angle_delta[1] = best_angle_delta;
4233#endif // CONFIG_EXT_INTRA
4234 mbmi->uv_mode = mode_selected;
Urvang Joshib100db72016-10-12 16:28:56 -07004235#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236 pmi->palette_size[1] = palette_mode_info.palette_size[1];
4237 if (palette_mode_info.palette_size[1] > 0) {
4238 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
4239 palette_mode_info.palette_colors + PALETTE_MAX_SIZE,
4240 2 * PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
4241 memcpy(xd->plane[1].color_index_map, best_palette_color_map,
4242 rows * cols * sizeof(best_palette_color_map[0]));
4243 }
Urvang Joshib100db72016-10-12 16:28:56 -07004244#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245
4246 return best_rd;
4247}
4248
Urvang Joshi52648442016-10-13 17:27:51 -07004249static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004250 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4251 TX_SIZE max_tx_size, int *rate_uv,
4252 int *rate_uv_tokenonly, int64_t *dist_uv,
4253 int *skip_uv, PREDICTION_MODE *mode_uv) {
4254 // Use an estimated rd for uv_intra based on DC_PRED if the
4255 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004256 (void)ctx;
4257 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4258 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004259 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4260}
4261
Urvang Joshi52648442016-10-13 17:27:51 -07004262static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004263#if CONFIG_REF_MV && CONFIG_EXT_INTER
4264 int is_compound,
4265#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4266 int16_t mode_context) {
4267#if CONFIG_REF_MV
4268 int mode_cost = 0;
4269#if CONFIG_EXT_INTER
4270 int16_t mode_ctx =
4271 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4272#else
4273 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4274#endif // CONFIG_EXT_INTER
4275 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4276
4277 assert(is_inter_mode(mode));
4278
4279#if CONFIG_EXT_INTER
4280 if (is_compound) {
clang-format67948d32016-09-07 22:40:40 -07004281 return cpi->inter_compound_mode_cost[mode_context]
4282 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004283 } else {
4284 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4285#else
4286 if (mode == NEWMV) {
4287#endif // CONFIG_EXT_INTER
4288 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4289#if CONFIG_EXT_INTER
4290 if (!is_compound)
4291 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4292#endif // CONFIG_EXT_INTER
4293 return mode_cost;
4294 } else {
4295 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4296 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4297
4298 if (is_all_zero_mv) return mode_cost;
4299
4300 if (mode == ZEROMV) {
4301 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4302 return mode_cost;
4303 } else {
4304 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4305 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4306
4307 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4308 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4309 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4310
4311 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4312 return mode_cost;
4313 }
4314 }
4315#if CONFIG_EXT_INTER
4316 }
4317#endif // CONFIG_EXT_INTER
4318#else
4319 assert(is_inter_mode(mode));
4320#if CONFIG_EXT_INTER
4321 if (is_inter_compound_mode(mode)) {
clang-format67948d32016-09-07 22:40:40 -07004322 return cpi->inter_compound_mode_cost[mode_context]
4323 [INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004324 } else {
4325#endif // CONFIG_EXT_INTER
4326 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4327#if CONFIG_EXT_INTER
4328 }
4329#endif // CONFIG_EXT_INTER
4330#endif
4331}
4332
Sarah Parkere5299862016-08-16 14:57:37 -07004333#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00004334static int get_gmbitcost(const WarpedMotionParams *gm, const aom_prob *probs) {
4335 int gmtype_cost[TRANS_TYPES];
Sarah Parkere5299862016-08-16 14:57:37 -07004336 int bits;
David Barkercf3d0b02016-11-10 10:14:49 +00004337 TransformationType type = gm->wmtype;
Sarah Parkere5299862016-08-16 14:57:37 -07004338 av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
David Barkercf3d0b02016-11-10 10:14:49 +00004339 switch (type) {
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004340 case HOMOGRAPHY:
4341 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4 +
4342 (GM_ABS_ROW3HOMO_BITS + 1) * 2;
4343 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004344 case AFFINE:
4345 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004346 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004347 case ROTZOOM:
4348 bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 2;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004349 break;
David Barkercf3d0b02016-11-10 10:14:49 +00004350 case TRANSLATION: bits = (GM_ABS_TRANS_BITS + 1) * 2; break;
4351 case IDENTITY: bits = 0; break;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004352 default: assert(0); return 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004353 }
David Barkercf3d0b02016-11-10 10:14:49 +00004354 return bits ? (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[type] : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004355}
4356
4357#define GLOBAL_MOTION_RATE(ref) \
4358 (cpi->global_motion_used[ref] >= 2 \
4359 ? 0 \
4360 : get_gmbitcost(&cm->global_motion[(ref)], \
4361 cm->fc->global_motion_types_prob) / \
4362 2);
4363#endif // CONFIG_GLOBAL_MOTION
4364
Urvang Joshi52648442016-10-13 17:27:51 -07004365static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
4366 MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
4367 int_mv this_mv[2],
clang-format67948d32016-09-07 22:40:40 -07004368 int_mv frame_mv[MB_MODE_COUNT]
4369 [TOTAL_REFS_PER_FRAME],
4370 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004371#if CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004372 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004373#endif // CONFIG_EXT_INTER
clang-format67948d32016-09-07 22:40:40 -07004374 int_mv *best_ref_mv[2], const int *mvjcost,
4375 int *mvcost[2]) {
Sarah Parkere5299862016-08-16 14:57:37 -07004376#if CONFIG_GLOBAL_MOTION
4377 const AV1_COMMON *cm = &cpi->common;
4378#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 MODE_INFO *const mic = xd->mi[0];
4380 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4381 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4382 int thismvcost = 0;
4383 int idx, idy;
4384 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4385 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4386 const int is_compound = has_second_ref(mbmi);
4387 int mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
4388
4389 switch (mode) {
4390 case NEWMV:
4391#if CONFIG_EXT_INTER
4392 case NEWFROMNEARMV:
4393#endif // CONFIG_EXT_INTER
4394 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4395#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07004396 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004397 lower_mv_precision(&this_mv[0].as_mv, 0);
4398#endif // CONFIG_EXT_INTER
4399
4400#if CONFIG_REF_MV
4401 for (idx = 0; idx < 1 + is_compound; ++idx) {
4402 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004403 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07004405 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
4406 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407 }
4408 (void)mvjcost;
4409 (void)mvcost;
4410#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004411 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4412 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004413#if !CONFIG_EXT_INTER
4414 if (is_compound) {
4415 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07004416 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4417 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004418 }
4419#endif // !CONFIG_EXT_INTER
4420#endif
4421 break;
4422 case NEARMV:
4423 case NEARESTMV:
4424 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4425 if (is_compound)
4426 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4427 break;
4428 case ZEROMV:
Sarah Parkere5299862016-08-16 14:57:37 -07004429#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004430 this_mv[0].as_int =
4431 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]])
4432 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004433 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
4434 if (is_compound) {
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004435 this_mv[1].as_int =
4436 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]])
4437 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07004438 thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
4439 }
4440#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004441 this_mv[0].as_int = 0;
4442 if (is_compound) this_mv[1].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07004443#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004444 break;
4445#if CONFIG_EXT_INTER
4446 case NEW_NEWMV:
4447 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
4448 compound_seg_newmvs[1].as_int == INVALID_MV) {
4449 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
4450 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
4451 } else {
4452 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
4453 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
4454 }
Alex Converse6317c882016-09-29 14:21:37 -07004455 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004456 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07004457 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004458 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004459 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4460 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
4461 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4462 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463 break;
4464 case NEW_NEARMV:
4465 case NEW_NEARESTMV:
4466 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004467 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004468 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004469 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
4470 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004471 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4472 break;
4473 case NEAR_NEWMV:
4474 case NEAREST_NEWMV:
4475 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4476 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07004477 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004478 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07004479 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
4480 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004481 break;
4482 case NEAREST_NEARMV:
4483 case NEAR_NEARESTMV:
4484 case NEAREST_NEARESTMV:
4485 case NEAR_NEARMV:
4486 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
4487 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
4488 break;
4489 case ZERO_ZEROMV:
4490 this_mv[0].as_int = 0;
4491 this_mv[1].as_int = 0;
4492 break;
4493#endif // CONFIG_EXT_INTER
4494 default: break;
4495 }
4496
4497 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
4498 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
4499
4500 mic->bmi[i].as_mode = mode;
4501
4502#if CONFIG_REF_MV
4503 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07004504 mic->bmi[i].pred_mv[0].as_int =
4505 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
4506 if (is_compound)
4507 mic->bmi[i].pred_mv[1].as_int =
4508 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07004510 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
4511 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004512 }
4513#endif
4514
4515 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
4516 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
4517 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
4518
4519#if CONFIG_REF_MV
4520#if CONFIG_EXT_INTER
4521 if (is_compound)
4522 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
4523 else
4524#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07004525 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
4526 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004527#endif
4528#if CONFIG_REF_MV && CONFIG_EXT_INTER
4529 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
4530#else
4531 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
4532#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4533}
4534
Urvang Joshi52648442016-10-13 17:27:51 -07004535static int64_t encode_inter_mb_segment(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004536 int64_t best_yrd, int i, int *labelyrate,
4537 int64_t *distortion, int64_t *sse,
4538 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4539 int ir, int ic, int mi_row, int mi_col) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004540#if !CONFIG_PVQ
Angie Chiang22ba7512016-10-20 17:10:33 -07004541 const AV1_COMMON *const cm = &cpi->common;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004542#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004543 int k;
4544 MACROBLOCKD *xd = &x->e_mbd;
4545 struct macroblockd_plane *const pd = &xd->plane[0];
4546 struct macroblock_plane *const p = &x->plane[0];
4547 MODE_INFO *const mi = xd->mi[0];
4548 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanc4049db2016-10-27 14:44:13 -07004549 const int width = block_size_wide[plane_bsize];
4550 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004551 int idx, idy;
4552 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07004553 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004554 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07004555 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004556 int64_t thisdistortion = 0, thissse = 0;
4557 int thisrate = 0;
4558 TX_SIZE tx_size = mi->mbmi.tx_size;
4559
4560 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07004561 const int num_4x4_w = tx_size_wide_unit[tx_size];
4562 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004563#if !CONFIG_PVQ
4564 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
4565#else
4566 (void)cpi;
4567 (void)ta;
4568 (void)tl;
4569#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004570
4571#if CONFIG_EXT_TX && CONFIG_RECT_TX
4572 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
4573 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
4574 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
4575#else
4576 assert(tx_size == TX_4X4);
4577#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4578 assert(tx_type == DCT_DCT);
4579
Yaowu Xuf883b422016-08-30 14:01:10 -07004580 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004581
Yushin Cho77bba8d2016-11-04 16:36:56 -07004582#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07004583#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004584 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004585 aom_highbd_subtract_block(
4586 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
4587 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004588 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004589 aom_subtract_block(height, width,
4590 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004591 8, src, p->src.stride, dst, pd->dst.stride);
4592 }
4593#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004594 aom_subtract_block(height, width,
4595 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07004596 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07004597#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -07004598#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599
4600 k = i;
4601 for (idy = 0; idy < height / 4; idy += num_4x4_h) {
4602 for (idx = 0; idx < width / 4; idx += num_4x4_w) {
4603 int64_t dist, ssz, rd, rd1, rd2;
4604 int block;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004605#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004606 int coeff_ctx;
Yaowu Xu02d4c3b2016-11-07 10:45:56 -08004607#else
Yushin Cho77bba8d2016-11-04 16:36:56 -07004608 const int src_stride = p->src.stride;
4609 const int dst_stride = pd->dst.stride;
4610 const int diff_stride = 8;
4611 tran_low_t *coeff;
4612 tran_low_t *dqcoeff;
4613 tran_low_t *ref_coeff;
4614 int16_t *pred = &pd->pred[4 * (ir * diff_stride + ic)];
4615 int16_t *src_int16 = &p->src_int16[4 * (ir * diff_stride + ic)];
4616 int ii, j, tx_blk_size;
4617 int rate_pvq;
4618#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004619 k += (idy * 2 + idx);
4620 if (tx_size == TX_4X4)
4621 block = k;
4622 else
4623 block = (i ? 2 : 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004624#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004625 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
4626#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07004627 av1_xform_quant_fp_nuq(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Yaowu Xuf883b422016-08-30 14:01:10 -07004628 BLOCK_8X8, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004629#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004630 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
4631 BLOCK_8X8, tx_size, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004632#endif // CONFIG_NEW_QUANT
4633 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07004634 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004635#else
4636 coeff = BLOCK_OFFSET(p->coeff, k);
4637 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, k);
4638 ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, k);
4639
4640 // transform block size in pixels
4641 tx_blk_size = 4;
4642
4643 // copy uint8 orig and predicted block to int16 buffer
4644 // in order to use existing VP10 transform functions
4645 for (j = 0; j < tx_blk_size; j++)
4646 for (ii = 0; ii < tx_blk_size; ii++) {
4647 src_int16[diff_stride * j + ii] =
4648 src[src_stride * (j + 4 * idy) + (ii + 4 * idx)];
4649 pred[diff_stride * j + ii] =
4650 dst[dst_stride * (j + 4 * idy) + (ii + 4 * idx)];
4651 }
4652
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004653 {
4654 FWD_TXFM_PARAM fwd_txfm_param;
4655 fwd_txfm_param.tx_type = DCT_DCT;
4656 fwd_txfm_param.tx_size = TX_4X4;
4657 fwd_txfm_param.fwd_txfm_opt = FWD_TXFM_OPT_NORMAL;
4658 fwd_txfm_param.rd_transform = 0;
4659 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho77bba8d2016-11-04 16:36:56 -07004660
Yaowu Xu3442b4b2016-11-07 10:40:41 -08004661 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
4662 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
4663 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004664 av1_pvq_encode_helper(&x->daala_enc, coeff, ref_coeff, dqcoeff,
4665 &p->eobs[k], pd->dequant, 0, TX_4X4, tx_type,
4666 &rate_pvq, x->pvq_speed, NULL);
4667#endif
4668
Yaowu Xuc27fc142016-08-22 16:08:15 -07004669 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
4670 &dist, &ssz);
4671 thisdistortion += dist;
4672 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004673#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004674 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07004675 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004676 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004677#else
4678 thisrate += rate_pvq;
4679#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004680 *(ta + (k & 1)) = !(p->eobs[block] == 0);
4681 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004682#if CONFIG_EXT_TX
4683 if (tx_size == TX_8X4) {
4684 *(ta + (k & 1) + 1) = *(ta + (k & 1));
4685 }
4686 if (tx_size == TX_4X8) {
4687 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
4688 }
4689#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004690 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
4691 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07004692 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004693 if (rd >= best_yrd) return INT64_MAX;
4694 }
4695 }
4696
4697 *distortion = thisdistortion;
4698 *labelyrate = thisrate;
4699 *sse = thissse;
4700
4701 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
4702}
4703
4704typedef struct {
4705 int eobs;
4706 int brate;
4707 int byrate;
4708 int64_t bdist;
4709 int64_t bsse;
4710 int64_t brdcost;
4711 int_mv mvs[2];
4712#if CONFIG_REF_MV
4713 int_mv pred_mv[2];
4714#endif
4715#if CONFIG_EXT_INTER
4716 int_mv ref_mv[2];
4717#endif // CONFIG_EXT_INTER
4718 ENTROPY_CONTEXT ta[2];
4719 ENTROPY_CONTEXT tl[2];
4720} SEG_RDSTAT;
4721
4722typedef struct {
4723 int_mv *ref_mv[2];
4724 int_mv mvp;
4725
4726 int64_t segment_rd;
4727 int r;
4728 int64_t d;
4729 int64_t sse;
4730 int segment_yrate;
4731 PREDICTION_MODE modes[4];
4732#if CONFIG_EXT_INTER
4733 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
4734#else
4735 SEG_RDSTAT rdstat[4][INTER_MODES];
4736#endif // CONFIG_EXT_INTER
4737 int mvthresh;
4738} BEST_SEG_INFO;
4739
4740static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
4741 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
4742 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
4743}
4744
4745static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
4746 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
4747 struct macroblock_plane *const p = &x->plane[0];
4748 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
4749
4750 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004751 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004752 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
4753 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07004754 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755 if (has_second_ref(mbmi))
4756 pd->pre[1].buf =
4757 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07004758 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004759}
4760
4761static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
4762 struct buf_2d orig_pre[2]) {
4763 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
4764 x->plane[0].src = orig_src;
4765 x->e_mbd.plane[0].pre[0] = orig_pre[0];
4766 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
4767}
4768
4769// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
4770// TODO(aconverse): Find out if this is still productive then clean up or remove
4771static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07004772 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004773#if CONFIG_REF_MV && CONFIG_EXT_INTER
4774 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
4775#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4776 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
4777 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block) {
4778
4779#if !CONFIG_EXT_INTER
4780 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
4781#endif
4782
4783 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
4784 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4785 (ref_frames[1] <= INTRA_FRAME ||
4786 frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
4787#if CONFIG_REF_MV
4788 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07004789 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004790#else
4791 int16_t rfc = mode_context[ref_frames[0]];
4792#endif
4793#if CONFIG_REF_MV && CONFIG_EXT_INTER
4794 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
4795 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
4796 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
4797#else
4798 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
4799 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
4800 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
4801#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4802
4803#if !CONFIG_REF_MV
4804 (void)bsize;
4805 (void)block;
4806#endif
4807
4808 if (this_mode == NEARMV) {
4809 if (c1 > c3) return 0;
4810 } else if (this_mode == NEARESTMV) {
4811 if (c2 > c3) return 0;
4812 } else {
4813 assert(this_mode == ZEROMV);
4814 if (ref_frames[1] <= INTRA_FRAME) {
4815 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
4816 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
4817 return 0;
4818 } else {
4819 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
4820 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
4821 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
4822 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
4823 return 0;
4824 }
4825 }
4826 }
4827#if CONFIG_EXT_INTER
4828 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
4829 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
4830 this_mode == ZERO_ZEROMV) &&
4831 frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
4832 frame_mv[this_mode][ref_frames[1]].as_int == 0) {
4833#if CONFIG_REF_MV
4834 int16_t rfc = compound_mode_context[ref_frames[0]];
4835 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
4836 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
4837 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
4838 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
4839 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
4840#else
4841 int16_t rfc = mode_context[ref_frames[0]];
4842 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
4843 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
4844 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
4845 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
4846 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
4847#endif
4848
4849 if (this_mode == NEAREST_NEARMV) {
4850 if (c1 > c3) return 0;
4851 } else if (this_mode == NEAREST_NEARESTMV) {
4852 if (c2 > c3) return 0;
4853 } else if (this_mode == NEAR_NEARESTMV) {
4854 if (c4 > c3) return 0;
4855 } else if (this_mode == NEAR_NEARMV) {
4856 if (c5 > c3) return 0;
4857 } else {
4858 assert(this_mode == ZERO_ZEROMV);
4859 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
4860 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
4861 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
4862 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
4863 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
4864 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
4865 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
4866 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
4867 return 0;
4868 }
4869 }
4870#endif // CONFIG_EXT_INTER
4871 return 1;
4872}
4873
Urvang Joshi52648442016-10-13 17:27:51 -07004874static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
4875 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
4876 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004877#if CONFIG_EXT_INTER
4878 int_mv *ref_mv_sub8x8[2],
4879#endif
4880 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
4881 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004882 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004883 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
4884 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
4885 MACROBLOCKD *xd = &x->e_mbd;
4886 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
4887 const int refs[2] = { mbmi->ref_frame[0],
4888 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
4889 int_mv ref_mv[2];
4890 int ite, ref;
4891#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07004892 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004893 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
4894 mbmi->interp_filter[3],
4895 };
4896#else
James Zern7b9407a2016-05-18 23:48:05 -07004897 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004898#endif
4899 struct scale_factors sf;
4900
4901 // Do joint motion search in compound mode to get more accurate mv.
4902 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
4903 int last_besterr[2] = { INT_MAX, INT_MAX };
4904 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07004905 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
4906 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07004907 };
4908
4909// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004910#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004911 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
4912 uint8_t *second_pred;
4913#else
4914 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07004915#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004916
4917 for (ref = 0; ref < 2; ++ref) {
4918#if CONFIG_EXT_INTER
4919 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
4920 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
4921 else
4922#endif // CONFIG_EXT_INTER
4923 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
4924
4925 if (scaled_ref_frame[ref]) {
4926 int i;
4927 // Swap out the reference frame for a version that's been scaled to
4928 // match the resolution of the current frame, allowing the existing
4929 // motion search code to be used without additional modifications.
4930 for (i = 0; i < MAX_MB_PLANE; i++)
4931 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07004932 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
4933 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004934 }
4935
4936 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
4937 }
4938
4939// Since we have scaled the reference frames to match the size of the current
4940// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07004941#if CONFIG_AOM_HIGHBITDEPTH
4942 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4943 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004944#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004945 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
4946 cm->height);
4947#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004948
4949 // Allow joint search multiple times iteratively for each reference frame
4950 // and break out of the search loop if it couldn't find a better mv.
4951 for (ite = 0; ite < 4; ite++) {
4952 struct buf_2d ref_yv12[2];
4953 int bestsme = INT_MAX;
4954 int sadpb = x->sadperbit16;
4955 MV *const best_mv = &x->best_mv.as_mv;
4956 int search_range = 3;
4957
4958 int tmp_col_min = x->mv_col_min;
4959 int tmp_col_max = x->mv_col_max;
4960 int tmp_row_min = x->mv_row_min;
4961 int tmp_row_max = x->mv_row_max;
4962 int id = ite % 2; // Even iterations search in the first reference frame,
4963 // odd iterations search in the second. The predictor
4964 // found for the 'other' reference frame is factored in.
4965
4966 // Initialized here because of compiler problem in Visual Studio.
4967 ref_yv12[0] = xd->plane[0].pre[0];
4968 ref_yv12[1] = xd->plane[0].pre[1];
4969
4970#if CONFIG_DUAL_FILTER
4971 // reload the filter types
4972 interp_filter[0] =
4973 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
4974 interp_filter[1] =
4975 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
4976#endif
4977
4978// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004979#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004980 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4981 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004982 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004983 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
4984 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
4985 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
4986 } else {
4987 second_pred = (uint8_t *)second_pred_alloc_16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004988 av1_build_inter_predictor(ref_yv12[!id].buf, ref_yv12[!id].stride,
4989 second_pred, pw, &frame_mv[refs[!id]].as_mv,
4990 &sf, pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4991 mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004992 }
4993#else
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, &sf,
4996 pw, ph, 0, interp_filter, MV_PRECISION_Q3,
4997 mi_col * MI_SIZE, mi_row * MI_SIZE);
4998#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004999
5000 // Do compound motion search on the current reference frame.
5001 if (id) xd->plane[0].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005002 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005003
5004 // Use the mv result from the single mode as mv predictor.
5005 *best_mv = frame_mv[refs[id]].as_mv;
5006
5007 best_mv->col >>= 3;
5008 best_mv->row >>= 3;
5009
5010#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005011 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005012#endif
5013
5014 // Small-range full-pixel motion search.
5015 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005016 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5017 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005018 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005019 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5020 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005021
5022 x->mv_col_min = tmp_col_min;
5023 x->mv_col_max = tmp_col_max;
5024 x->mv_row_min = tmp_row_min;
5025 x->mv_row_max = tmp_row_max;
5026
5027 if (bestsme < INT_MAX) {
5028 int dis; /* TODO: use dis in distortion calculation later. */
5029 unsigned int sse;
5030 if (cpi->sf.use_upsampled_references) {
5031 // Use up-sampled reference frames.
5032 struct macroblockd_plane *const pd = &xd->plane[0];
5033 struct buf_2d backup_pred = pd->pre[0];
5034 const YV12_BUFFER_CONFIG *upsampled_ref =
5035 get_upsampled_ref(cpi, refs[id]);
5036
5037 // Set pred for Y plane
5038 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5039 upsampled_ref->y_crop_width,
5040 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5041 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5042 pd->subsampling_y);
5043
5044 // If bsize < BLOCK_8X8, adjust pred pointer for this block
5045 if (bsize < BLOCK_8X8)
5046 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005047 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5048 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005049 << 3];
5050
5051 bestsme = cpi->find_fractional_mv_step(
5052 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5053 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5054 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5055 &dis, &sse, second_pred, pw, ph, 1);
5056
5057 // Restore the reference frames.
5058 pd->pre[0] = backup_pred;
5059 } else {
5060 (void)block;
5061 bestsme = cpi->find_fractional_mv_step(
5062 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5063 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5064 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5065 &dis, &sse, second_pred, pw, ph, 0);
5066 }
5067 }
5068
5069 // Restore the pointer to the first (possibly scaled) prediction buffer.
5070 if (id) xd->plane[0].pre[0] = ref_yv12[0];
5071
5072 if (bestsme < last_besterr[id]) {
5073 frame_mv[refs[id]].as_mv = *best_mv;
5074 last_besterr[id] = bestsme;
5075 } else {
5076 break;
5077 }
5078 }
5079
5080 *rate_mv = 0;
5081
5082 for (ref = 0; ref < 2; ++ref) {
5083 if (scaled_ref_frame[ref]) {
5084 // Restore the prediction frame pointers to their unscaled versions.
5085 int i;
5086 for (i = 0; i < MAX_MB_PLANE; i++)
5087 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5088 }
5089#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005090 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005091#endif
5092#if CONFIG_EXT_INTER
5093 if (bsize >= BLOCK_8X8)
5094#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005095 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5096 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5097 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005098#if CONFIG_EXT_INTER
5099 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005100 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5101 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5102 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005103#endif // CONFIG_EXT_INTER
5104 }
5105}
5106
5107static int64_t rd_pick_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005108 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005109 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5110 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5111 int mvthresh,
5112#if CONFIG_EXT_INTER
5113 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5114 int_mv compound_seg_newmvs[4][2],
5115#else
5116 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5117#endif // CONFIG_EXT_INTER
5118 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5119 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5120#if CONFIG_REF_MV
5121 int_mv tmp_ref_mv[2];
5122#endif
5123 MACROBLOCKD *xd = &x->e_mbd;
5124 MODE_INFO *mi = xd->mi[0];
5125 MB_MODE_INFO *mbmi = &mi->mbmi;
5126 int mode_idx;
5127 int k, br = 0, idx, idy;
5128 int64_t bd = 0, block_sse = 0;
5129 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005130 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131 struct macroblock_plane *const p = &x->plane[0];
5132 struct macroblockd_plane *const pd = &xd->plane[0];
5133 const int label_count = 4;
5134 int64_t this_segment_rd = 0;
5135 int label_mv_thresh;
5136 int segmentyrate = 0;
5137 const BLOCK_SIZE bsize = mbmi->sb_type;
5138 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5139 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
5140 ENTROPY_CONTEXT t_above[2], t_left[2];
5141 int subpelmv = 1, have_ref = 0;
5142 const int has_second_rf = has_second_ref(mbmi);
5143 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5144 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005145#if CONFIG_PVQ
5146 od_rollback_buffer pre_buf;
5147
5148 od_encode_checkpoint(&x->daala_enc, &pre_buf);
5149#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005150#if CONFIG_EXT_TX && CONFIG_RECT_TX
5151 mbmi->tx_size =
5152 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5153#else
5154 mbmi->tx_size = TX_4X4;
5155#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5156
Yaowu Xuf883b422016-08-30 14:01:10 -07005157 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005158
5159 bsi->segment_rd = best_rd;
5160 bsi->ref_mv[0] = best_ref_mv;
5161 bsi->ref_mv[1] = second_best_ref_mv;
5162 bsi->mvp.as_int = best_ref_mv->as_int;
5163 bsi->mvthresh = mvthresh;
5164
5165 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5166
5167#if CONFIG_REFMV
5168 for (idx = 0; idx < 4; ++idx) {
5169 for (k = NEARESTMV; k <= NEWMV; ++k) {
5170 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5171 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5172
5173 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5174 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5175 }
5176 }
5177#endif
5178
5179 memcpy(t_above, pd->above_context, sizeof(t_above));
5180 memcpy(t_left, pd->left_context, sizeof(t_left));
5181
5182 // 64 makes this threshold really big effectively
5183 // making it so that we very rarely check mvs on
5184 // segments. setting this to 1 would make mv thresh
5185 // roughly equal to what it is for macroblocks
5186 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5187
5188 // Segmentation method overheads
5189 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5190 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5191 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5192 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5193 int_mv mode_mv[MB_MODE_COUNT][2];
5194 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5195 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005196 int64_t new_best_rd = INT64_MAX;
5197 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198 int ref;
5199#if CONFIG_REF_MV
5200 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5201 uint8_t ref_mv_count[2];
5202#endif
5203#if CONFIG_EXT_INTER
5204 int mv_idx;
5205 int_mv ref_mvs_sub8x8[2][2];
5206#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005207#if CONFIG_PVQ
5208 od_rollback_buffer idx_buf, post_buf;
5209 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5210 od_encode_checkpoint(&x->daala_enc, &post_buf);
5211#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212
5213 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5214 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5215#if CONFIG_EXT_INTER
5216 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07005217 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005218 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005219#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005220#if CONFIG_GLOBAL_MOTION
5221 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005222 gm_get_motion_vector(&cm->global_motion[frame]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005223#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005224 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005225#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005226 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005227#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005228 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005229#endif
5230#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005231 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005233 &frame_mv[NEARESTMV][frame],
5234 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005235
5236#if CONFIG_REF_MV
5237 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5238 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5239 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5240 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5241#endif
5242
5243#if CONFIG_EXT_INTER
5244 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5245 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005246 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5247 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005248
5249 if (has_second_rf) {
5250 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
5251 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5252 frame_mv[NEARESTMV][frame].as_int;
5253
5254 if (ref == 0) {
5255 frame_mv[NEAREST_NEARMV][frame].as_int =
5256 frame_mv[NEARESTMV][frame].as_int;
5257 frame_mv[NEAR_NEARESTMV][frame].as_int =
5258 frame_mv[NEARMV][frame].as_int;
5259 frame_mv[NEAREST_NEWMV][frame].as_int =
5260 frame_mv[NEARESTMV][frame].as_int;
5261 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5262 frame_mv[NEAR_NEARMV][frame].as_int =
5263 frame_mv[NEARMV][frame].as_int;
5264 } else if (ref == 1) {
5265 frame_mv[NEAREST_NEARMV][frame].as_int =
5266 frame_mv[NEARMV][frame].as_int;
5267 frame_mv[NEAR_NEARESTMV][frame].as_int =
5268 frame_mv[NEARESTMV][frame].as_int;
5269 frame_mv[NEW_NEARESTMV][frame].as_int =
5270 frame_mv[NEARESTMV][frame].as_int;
5271 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5272 frame_mv[NEAR_NEARMV][frame].as_int =
5273 frame_mv[NEARMV][frame].as_int;
5274 }
5275 }
5276#endif // CONFIG_EXT_INTER
5277 }
5278
5279// search for the best motion vector on this segment
5280#if CONFIG_EXT_INTER
5281 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5282 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5283 ++this_mode)
5284#else
5285 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5286#endif // CONFIG_EXT_INTER
5287 {
5288 const struct buf_2d orig_src = x->plane[0].src;
5289 struct buf_2d orig_pre[2];
5290 // This flag controls if the motion estimation will kick off. When it
5291 // is set to a non-zero value, the encoder will force motion estimation.
5292 int run_mv_search = 0;
5293
5294 mode_idx = INTER_OFFSET(this_mode);
5295#if CONFIG_EXT_INTER
5296 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5297
5298 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5299 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5300#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005301 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005302 if (!(inter_mode_mask & (1 << this_mode))) continue;
5303
5304#if CONFIG_REF_MV
5305 run_mv_search = 2;
5306#if !CONFIG_EXT_INTER
5307 if (filter_idx > 0 && this_mode == NEWMV) {
5308 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005309 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310
5311 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005312 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005313 ref_rdstat->mvs[0].as_int &&
5314 ref_rdstat->mvs[0].as_int != INVALID_MV)
5315 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5316 --run_mv_search;
5317
Urvang Joshi454280d2016-10-14 16:51:44 -07005318 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005319 ref_rdstat->mvs[1].as_int &&
5320 ref_rdstat->mvs[1].as_int != INVALID_MV)
5321 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5322 --run_mv_search;
5323 } else {
5324 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5325 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5326 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005327 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5328 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005329 }
5330 }
5331
5332 if (run_mv_search != 0 && filter_idx > 1) {
5333 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005334 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335 run_mv_search = 2;
5336
5337 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005338 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005339 ref_rdstat->mvs[0].as_int &&
5340 ref_rdstat->mvs[0].as_int != INVALID_MV)
5341 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5342 --run_mv_search;
5343
Urvang Joshi454280d2016-10-14 16:51:44 -07005344 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005345 ref_rdstat->mvs[1].as_int &&
5346 ref_rdstat->mvs[1].as_int != INVALID_MV)
5347 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5348 --run_mv_search;
5349 } else {
5350 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5351 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5352 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005353 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005354 ref_rdstat->mvs[0].as_int;
5355 }
5356 }
5357 }
5358 }
5359#endif // CONFIG_EXT_INTER
5360#endif // CONFIG_REF_MV
5361
Sarah Parkere5299862016-08-16 14:57:37 -07005362#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005363 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005364 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005365 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005366#endif // CONFIG_GLOBAL_MOTION
5367
5368 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005369#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005370 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005371#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005372 frame_mv, this_mode, mbmi->ref_frame, bsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07005373 index))
Sarah Parkere5299862016-08-16 14:57:37 -07005374 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005375
5376 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005377 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5378 sizeof(bsi->rdstat[index][mode_idx].ta));
5379 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5380 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005381#if CONFIG_PVQ
5382 od_encode_rollback(&x->daala_enc, &idx_buf);
5383#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005384
5385 // motion search for newmv (single predictor case only)
5386 if (!has_second_rf &&
5387#if CONFIG_EXT_INTER
5388 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07005389 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005390#else
5391 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005392 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005393 run_mv_search)
5394#endif // CONFIG_EXT_INTER
5395 ) {
5396 int step_param = 0;
5397 int bestsme = INT_MAX;
5398 int sadpb = x->sadperbit4;
5399 MV mvp_full;
5400 int max_mv;
5401 int cost_list[5];
5402 int tmp_col_min = x->mv_col_min;
5403 int tmp_col_max = x->mv_col_max;
5404 int tmp_row_min = x->mv_row_min;
5405 int tmp_row_max = x->mv_row_max;
5406
5407 /* Is the best so far sufficiently good that we cant justify doing
5408 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005409 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005410
5411 if (cpi->oxcf.mode != BEST) {
5412#if CONFIG_EXT_INTER
5413 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
5414#else
5415// use previous block's result as next block's MV predictor.
5416#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005417 if (index > 0) {
5418 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
5419 if (index == 2)
5420 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005421 }
5422#endif
5423#endif // CONFIG_EXT_INTER
5424 }
Urvang Joshi454280d2016-10-14 16:51:44 -07005425 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5426 : AOMMAX(abs(bsi->mvp.as_mv.row),
5427 abs(bsi->mvp.as_mv.col)) >>
5428 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005429
5430 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5431 // Take wtd average of the step_params based on the last frame's
5432 // max mv magnitude and the best ref mvs of the current block for
5433 // the given reference.
5434 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005435 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436 } else {
5437 step_param = cpi->mv_step_param;
5438 }
5439
5440#if CONFIG_REF_MV
5441 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5442 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
5443#else
5444 mvp_full.row = bsi->mvp.as_mv.row >> 3;
5445 mvp_full.col = bsi->mvp.as_mv.col >> 3;
5446#endif
5447
5448 if (cpi->sf.adaptive_motion_search) {
5449 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5450 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005451 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005452 }
5453
5454 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005455 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005456
Yaowu Xuf883b422016-08-30 14:01:10 -07005457 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458
5459 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5460
5461#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005462 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005463#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005464 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465 cpi, x, bsize, &mvp_full, step_param, sadpb,
5466 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
5467 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
5468
5469 x->mv_col_min = tmp_col_min;
5470 x->mv_col_max = tmp_col_max;
5471 x->mv_row_min = tmp_row_min;
5472 x->mv_row_max = tmp_row_max;
5473
5474 if (bestsme < INT_MAX) {
5475 int distortion;
5476 if (cpi->sf.use_upsampled_references) {
5477 int best_mv_var;
5478 const int try_second =
5479 x->second_best_mv.as_int != INVALID_MV &&
5480 x->second_best_mv.as_int != x->best_mv.as_int;
5481 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
5482 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
5483 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005484 struct buf_2d backup_pred = pd->pre[0];
5485 const YV12_BUFFER_CONFIG *upsampled_ref =
5486 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
5487
5488 // Set pred for Y plane
5489 setup_pred_plane(
5490 &pd->pre[0], upsampled_ref->y_buffer,
5491 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5492 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5493 pd->subsampling_x, pd->subsampling_y);
5494
5495 // adjust pred pointer for this block
5496 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07005497 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07005498 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005499 << 3];
5500
5501 best_mv_var = cpi->find_fractional_mv_step(
5502 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5503 x->errorperbit, &cpi->fn_ptr[bsize],
5504 cpi->sf.mv.subpel_force_stop,
5505 cpi->sf.mv.subpel_iters_per_step,
5506 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5507 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
5508 1);
5509
5510 if (try_second) {
5511 int this_var;
5512 MV best_mv = x->best_mv.as_mv;
5513 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07005514 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
5515 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
5516 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
5517 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518
5519 x->best_mv = x->second_best_mv;
5520 if (x->best_mv.as_mv.row * 8 <= maxr &&
5521 x->best_mv.as_mv.row * 8 >= minr &&
5522 x->best_mv.as_mv.col * 8 <= maxc &&
5523 x->best_mv.as_mv.col * 8 >= minc) {
5524 this_var = cpi->find_fractional_mv_step(
5525 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5526 x->errorperbit, &cpi->fn_ptr[bsize],
5527 cpi->sf.mv.subpel_force_stop,
5528 cpi->sf.mv.subpel_iters_per_step,
5529 cond_cost_list(cpi, cost_list), x->nmvjointcost,
5530 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
5531 NULL, pw, ph, 1);
5532 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5533 x->best_mv.as_mv = best_mv;
5534 }
5535 }
5536
5537 // Restore the reference frames.
5538 pd->pre[0] = backup_pred;
5539 } else {
5540 cpi->find_fractional_mv_step(
5541 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
5542 x->errorperbit, &cpi->fn_ptr[bsize],
5543 cpi->sf.mv.subpel_force_stop,
5544 cpi->sf.mv.subpel_iters_per_step,
5545 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
5546 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
5547 }
5548
5549// save motion search result for use in compound prediction
5550#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005551 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005553 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005554#endif // CONFIG_EXT_INTER
5555 }
5556
5557 if (cpi->sf.adaptive_motion_search)
5558 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
5559
5560#if CONFIG_EXT_INTER
5561 mode_mv[this_mode][0] = x->best_mv;
5562#else
5563 mode_mv[NEWMV][0] = x->best_mv;
5564#endif // CONFIG_EXT_INTER
5565
5566 // restore src pointers
5567 mi_buf_restore(x, orig_src, orig_pre);
5568 }
5569
5570 if (has_second_rf) {
5571#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005572 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5573 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005575 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
5576 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577#endif // CONFIG_EXT_INTER
5578 continue;
5579 }
5580
5581#if CONFIG_DUAL_FILTER
5582 (void)run_mv_search;
5583#endif
5584
5585 if (has_second_rf &&
5586#if CONFIG_EXT_INTER
5587 this_mode == NEW_NEWMV &&
5588#else
5589 this_mode == NEWMV &&
5590#endif // CONFIG_EXT_INTER
5591#if CONFIG_DUAL_FILTER
5592 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
5593#else
5594 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
5595#endif
5596 {
5597 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07005598 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
5600 int rate_mv;
5601 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
5602 mi_col,
5603#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005604 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005606 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005607#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005608 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005610 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005612 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5614#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005615 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005616 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07005617 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
5619#endif // CONFIG_EXT_INTER
5620 }
5621 // restore src pointers
5622 mi_buf_restore(x, orig_src, orig_pre);
5623 }
5624
Urvang Joshi454280d2016-10-14 16:51:44 -07005625 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
5626 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005627#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005628 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005629#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005630 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005631#endif // CONFIG_EXT_INTER
5632 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5633
5634 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005635 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 mode_mv[this_mode][ref].as_int;
5637 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005638 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005639 mode_mv[this_mode][ref].as_int;
5640 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005641 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005642 mode_mv[this_mode][ref].as_int;
5643#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005644 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
5645 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005647 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
5648 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005649 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005650 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
5651 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005652#endif
5653#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005654 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655 bsi->ref_mv[ref]->as_int;
5656 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005657 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658 bsi->ref_mv[ref]->as_int;
5659 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005660 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661 bsi->ref_mv[ref]->as_int;
5662#endif // CONFIG_EXT_INTER
5663 }
5664
5665 // Trap vectors that reach beyond the UMV borders
5666 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
5667 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
5668 continue;
5669
5670 if (filter_idx > 0) {
5671 BEST_SEG_INFO *ref_bsi = bsi_buf;
5672 subpelmv = 0;
5673 have_ref = 1;
5674
5675 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5676 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
5677#if CONFIG_EXT_INTER
5678 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005679 have_ref &=
5680 ((mode_mv[this_mode][ref].as_int ==
5681 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5682 (bsi->ref_mv[ref]->as_int ==
5683 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005684 else
5685#endif // CONFIG_EXT_INTER
5686 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005687 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688 }
5689
Urvang Joshi454280d2016-10-14 16:51:44 -07005690 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005691
5692 if (filter_idx > 1 && !subpelmv && !have_ref) {
5693 ref_bsi = bsi_buf + 1;
5694 have_ref = 1;
5695 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5696#if CONFIG_EXT_INTER
5697 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07005698 have_ref &=
5699 ((mode_mv[this_mode][ref].as_int ==
5700 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
5701 (bsi->ref_mv[ref]->as_int ==
5702 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005703 else
5704#endif // CONFIG_EXT_INTER
5705 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07005706 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005707
Urvang Joshi454280d2016-10-14 16:51:44 -07005708 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005709 }
5710
5711 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005712 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07005714 bsi->rdstat[index][mode_idx].byrate =
5715 ref_bsi->rdstat[index][mode_idx].byrate;
5716 bsi->rdstat[index][mode_idx].bdist =
5717 ref_bsi->rdstat[index][mode_idx].bdist;
5718 bsi->rdstat[index][mode_idx].bsse =
5719 ref_bsi->rdstat[index][mode_idx].bsse;
5720 bsi->rdstat[index][mode_idx].brate +=
5721 ref_bsi->rdstat[index][mode_idx].byrate;
5722 bsi->rdstat[index][mode_idx].eobs =
5723 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005724
Urvang Joshi454280d2016-10-14 16:51:44 -07005725 bsi->rdstat[index][mode_idx].brdcost =
5726 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
5727 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005728
Urvang Joshi454280d2016-10-14 16:51:44 -07005729 memcpy(bsi->rdstat[index][mode_idx].ta,
5730 ref_bsi->rdstat[index][mode_idx].ta,
5731 sizeof(bsi->rdstat[index][mode_idx].ta));
5732 memcpy(bsi->rdstat[index][mode_idx].tl,
5733 ref_bsi->rdstat[index][mode_idx].tl,
5734 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005735#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005736 memcpy(&bsi->rdstat[index][mode_idx],
5737 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005738#endif
5739 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005740 bsi->rdstat[index + 1][mode_idx].eobs =
5741 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005742 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005743 bsi->rdstat[index + 2][mode_idx].eobs =
5744 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005745
Urvang Joshi454280d2016-10-14 16:51:44 -07005746 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005747#if CONFIG_REF_MV
5748 // If the NEWMV mode is using the same motion vector as the
5749 // NEARESTMV mode, skip the rest rate-distortion calculations
5750 // and use the inferred motion vector modes.
5751 if (this_mode == NEWMV) {
5752 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005753 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005754 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005755 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005756 bsi->ref_mv[1]->as_int)
5757 continue;
5758 } else {
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)
5761 continue;
5762 }
5763 }
5764#endif
5765 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005766 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005767#if CONFIG_PVQ
5768 od_encode_checkpoint(&x->daala_enc, &post_buf);
5769#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005770 }
5771 continue;
5772 }
5773 }
5774
Urvang Joshi454280d2016-10-14 16:51:44 -07005775 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment(
5776 cpi, x, bsi->segment_rd - this_segment_rd, index,
5777 &bsi->rdstat[index][mode_idx].byrate,
5778 &bsi->rdstat[index][mode_idx].bdist,
5779 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
5780 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005781
Urvang Joshi454280d2016-10-14 16:51:44 -07005782 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
5783 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
5784 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
5785 bsi->rdstat[index][mode_idx].brate +=
5786 bsi->rdstat[index][mode_idx].byrate;
5787 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005789 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005790 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07005791 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005792 }
5793
Urvang Joshi454280d2016-10-14 16:51:44 -07005794 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005795#if CONFIG_REF_MV
5796 // If the NEWMV mode is using the same motion vector as the
5797 // NEARESTMV mode, skip the rest rate-distortion calculations
5798 // and use the inferred motion vector modes.
5799 if (this_mode == NEWMV) {
5800 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005801 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005802 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005803 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005804 bsi->ref_mv[1]->as_int)
5805 continue;
5806 } else {
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)
5809 continue;
5810 }
5811 }
5812#endif
5813 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07005814 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005815
5816#if CONFIG_PVQ
5817 od_encode_checkpoint(&x->daala_enc, &post_buf);
5818#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819 }
5820 } /*for each 4x4 mode*/
5821
Urvang Joshi454280d2016-10-14 16:51:44 -07005822 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005823 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005824 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005825#if CONFIG_EXT_INTER
5826 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5827#else
5828 for (midx = 0; midx < INTER_MODES; ++midx)
5829#endif // CONFIG_EXT_INTER
5830 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5831 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005832#if CONFIG_PVQ
5833 od_encode_rollback(&x->daala_enc, &pre_buf);
5834#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005835 return INT64_MAX;
5836 }
5837
5838 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07005839 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
5840 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005841#if CONFIG_PVQ
5842 od_encode_rollback(&x->daala_enc, &post_buf);
5843#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005844
5845#if CONFIG_EXT_INTER
5846 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005847 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07005849 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005850#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005851 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
5852 mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005853#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005854 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005855#else
Urvang Joshi454280d2016-10-14 16:51:44 -07005856 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005857#endif // CONFIG_EXT_INTER
5858 bsi->ref_mv, x->nmvjointcost, x->mvcost);
5859
Urvang Joshi454280d2016-10-14 16:51:44 -07005860 br += bsi->rdstat[index][mode_idx].brate;
5861 bd += bsi->rdstat[index][mode_idx].bdist;
5862 block_sse += bsi->rdstat[index][mode_idx].bsse;
5863 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
5864 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005865
5866 if (this_segment_rd > bsi->segment_rd) {
5867 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07005868 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005869#if CONFIG_EXT_INTER
5870 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
5871#else
5872 for (midx = 0; midx < INTER_MODES; ++midx)
5873#endif // CONFIG_EXT_INTER
5874 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
5875 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005876#if CONFIG_PVQ
5877 od_encode_rollback(&x->daala_enc, &pre_buf);
5878#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005879 return INT64_MAX;
5880 }
5881 }
5882 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07005883#if CONFIG_PVQ
5884 od_encode_rollback(&x->daala_enc, &pre_buf);
5885#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886
5887 bsi->r = br;
5888 bsi->d = bd;
5889 bsi->segment_yrate = segmentyrate;
5890 bsi->segment_rd = this_segment_rd;
5891 bsi->sse = block_sse;
5892
5893 // update the coding decisions
5894 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
5895
5896 if (bsi->segment_rd > best_rd) return INT64_MAX;
5897 /* set it to the best */
5898 for (idx = 0; idx < 4; idx++) {
5899 mode_idx = INTER_OFFSET(bsi->modes[idx]);
5900 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
5901 if (has_second_ref(mbmi))
5902 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
5903#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005904 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005905 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005906 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907#endif
5908#if CONFIG_EXT_INTER
5909 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
5910 if (has_second_rf)
5911 mi->bmi[idx].ref_mv[1].as_int =
5912 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
5913#endif // CONFIG_EXT_INTER
5914 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
5915 mi->bmi[idx].as_mode = bsi->modes[idx];
5916 }
5917
5918 /*
5919 * used to set mbmi->mv.as_int
5920 */
5921 *returntotrate = bsi->r;
5922 *returndistortion = bsi->d;
5923 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07005924 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005925 *psse = bsi->sse;
5926 mbmi->mode = bsi->modes[3];
5927
5928 return bsi->segment_rd;
5929}
5930
Yaowu Xuf883b422016-08-30 14:01:10 -07005931static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005932 const MACROBLOCKD *xd, int segment_id,
5933 unsigned int *ref_costs_single,
5934 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005935 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005936 int seg_ref_active =
5937 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5938 if (seg_ref_active) {
5939 memset(ref_costs_single, 0,
5940 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5941 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5942 *comp_mode_p = 128;
5943 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005944 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5945 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005946
5947 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005948 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005949 *comp_mode_p = comp_inter_p;
5950 } else {
5951 *comp_mode_p = 128;
5952 }
5953
Yaowu Xuf883b422016-08-30 14:01:10 -07005954 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005955
5956 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005957 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5958 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005959#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005960 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5961 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5962 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005963#endif // CONFIG_EXT_REFS
5964
Yaowu Xuf883b422016-08-30 14:01:10 -07005965 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005966
5967 ref_costs_single[LAST_FRAME] =
5968#if CONFIG_EXT_REFS
5969 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5970 ref_costs_single[BWDREF_FRAME] =
5971#endif // CONFIG_EXT_REFS
5972 ref_costs_single[GOLDEN_FRAME] =
5973 ref_costs_single[ALTREF_FRAME] = base_cost;
5974
5975#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005976 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5977 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5978 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5979 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5980 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5981 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005982
Yaowu Xuf883b422016-08-30 14:01:10 -07005983 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5984 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5985 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5986 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005987
Yaowu Xuf883b422016-08-30 14:01:10 -07005988 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5989 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005990
Yaowu Xuf883b422016-08-30 14:01:10 -07005991 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5992 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005993
Yaowu Xuf883b422016-08-30 14:01:10 -07005994 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
5995 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005996#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005997 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5998 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
5999 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006000
Yaowu Xuf883b422016-08-30 14:01:10 -07006001 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6002 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003#endif // CONFIG_EXT_REFS
6004 } else {
6005 ref_costs_single[LAST_FRAME] = 512;
6006#if CONFIG_EXT_REFS
6007 ref_costs_single[LAST2_FRAME] = 512;
6008 ref_costs_single[LAST3_FRAME] = 512;
6009 ref_costs_single[BWDREF_FRAME] = 512;
6010#endif // CONFIG_EXT_REFS
6011 ref_costs_single[GOLDEN_FRAME] = 512;
6012 ref_costs_single[ALTREF_FRAME] = 512;
6013 }
6014
6015 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006016 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006017#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006018 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6019 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6020 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021#endif // CONFIG_EXT_REFS
6022
Yaowu Xuf883b422016-08-30 14:01:10 -07006023 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006024
6025 ref_costs_comp[LAST_FRAME] =
6026#if CONFIG_EXT_REFS
6027 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6028#endif // CONFIG_EXT_REFS
6029 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6030
6031#if CONFIG_EXT_REFS
6032 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6033#endif // CONFIG_EXT_REFS
6034
6035#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006036 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6037 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6038 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6039 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040
Yaowu Xuf883b422016-08-30 14:01:10 -07006041 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6042 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006043
Yaowu Xuf883b422016-08-30 14:01:10 -07006044 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6045 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006046
6047 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6048 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006049 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6050 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006051#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006052 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6053 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006054#endif // CONFIG_EXT_REFS
6055 } else {
6056 ref_costs_comp[LAST_FRAME] = 512;
6057#if CONFIG_EXT_REFS
6058 ref_costs_comp[LAST2_FRAME] = 512;
6059 ref_costs_comp[LAST3_FRAME] = 512;
6060 ref_costs_comp[BWDREF_FRAME] = 512;
6061 ref_costs_comp[ALTREF_FRAME] = 512;
6062#endif // CONFIG_EXT_REFS
6063 ref_costs_comp[GOLDEN_FRAME] = 512;
6064 }
6065 }
6066}
6067
6068static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6069 int mode_index,
6070 int64_t comp_pred_diff[REFERENCE_MODES],
6071 int skippable) {
6072 MACROBLOCKD *const xd = &x->e_mbd;
6073
6074 // Take a snapshot of the coding context so it can be
6075 // restored if we decide to encode this way
6076 ctx->skip = x->skip;
6077 ctx->skippable = skippable;
6078 ctx->best_mode_index = mode_index;
6079 ctx->mic = *xd->mi[0];
6080 ctx->mbmi_ext = *x->mbmi_ext;
6081 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6082 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6083 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6084}
6085
Urvang Joshi52648442016-10-13 17:27:51 -07006086static void setup_buffer_inter(const AV1_COMP *const cpi, MACROBLOCK *x,
clang-format67948d32016-09-07 22:40:40 -07006087 MV_REFERENCE_FRAME ref_frame,
6088 BLOCK_SIZE block_size, int mi_row, int mi_col,
6089 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6090 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6091 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME]
6092 [MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006093 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6095 MACROBLOCKD *const xd = &x->e_mbd;
6096 MODE_INFO *const mi = xd->mi[0];
6097 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6098 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6099 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6100
6101 assert(yv12 != NULL);
6102
6103 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6104 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006105 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006106
6107 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006108 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006109 cm, xd, mi, ref_frame,
6110#if CONFIG_REF_MV
6111 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6112#if CONFIG_EXT_INTER
6113 mbmi_ext->compound_mode_context,
6114#endif // CONFIG_EXT_INTER
6115#endif
6116 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6117
6118 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006119 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6120 &frame_nearest_mv[ref_frame],
6121 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006122
6123 // Further refinement that is encode side only to test the top few candidates
6124 // in full and choose the best as the centre point for subsequent searches.
6125 // The current implementation doesn't support scaling.
Yaowu Xuf883b422016-08-30 14:01:10 -07006126 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6127 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6128 block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006129}
6130
Urvang Joshi52648442016-10-13 17:27:51 -07006131static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6132 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006133#if CONFIG_EXT_INTER
6134 int ref_idx, int mv_idx,
6135#endif // CONFIG_EXT_INTER
6136 int *rate_mv) {
6137 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006138 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006139 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6140 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6141 int bestsme = INT_MAX;
6142 int step_param;
6143 int sadpb = x->sadperbit16;
6144 MV mvp_full;
6145#if CONFIG_EXT_INTER
6146 int ref = mbmi->ref_frame[ref_idx];
6147 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6148#else
6149 int ref = mbmi->ref_frame[0];
6150 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6151 int ref_idx = 0;
6152#endif // CONFIG_EXT_INTER
6153
6154 int tmp_col_min = x->mv_col_min;
6155 int tmp_col_max = x->mv_col_max;
6156 int tmp_row_min = x->mv_row_min;
6157 int tmp_row_max = x->mv_row_max;
6158 int cost_list[5];
6159
6160 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006161 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006162
6163 MV pred_mv[3];
6164 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6165 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6166 pred_mv[2] = x->pred_mv[ref];
6167
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 if (scaled_ref_frame) {
6169 int i;
6170 // Swap out the reference frame for a version that's been scaled to
6171 // match the resolution of the current frame, allowing the existing
6172 // motion search code to be used without additional modifications.
6173 for (i = 0; i < MAX_MB_PLANE; i++)
6174 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6175
Yaowu Xuf883b422016-08-30 14:01:10 -07006176 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006177 }
6178
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006179 av1_set_mv_search_range(x, &ref_mv);
6180
6181#if CONFIG_REF_MV
6182 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6183#endif
6184
Yaowu Xuc27fc142016-08-22 16:08:15 -07006185 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006186 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006187 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6188 // Take wtd average of the step_params based on the last frame's
6189 // max mv magnitude and that based on the best ref mvs of the current
6190 // block for the given reference.
6191 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006192 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193 2;
6194 } else {
6195 step_param = cpi->mv_step_param;
6196 }
6197
6198 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6199 int boffset =
6200 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006201 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6202 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 }
6204
6205 if (cpi->sf.adaptive_motion_search) {
6206 int bwl = b_width_log2_lookup[bsize];
6207 int bhl = b_height_log2_lookup[bsize];
6208 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6209
6210 if (tlevel < 5) step_param += 2;
6211
6212 // prev_mv_sad is not setup for dynamically scaled frames.
6213 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6214 int i;
6215 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6216 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6217 x->pred_mv[ref].row = 0;
6218 x->pred_mv[ref].col = 0;
6219 x->best_mv.as_int = INVALID_MV;
6220
6221 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006222 int j;
6223 for (j = 0; j < MAX_MB_PLANE; ++j)
6224 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006225 }
6226 return;
6227 }
6228 }
6229 }
6230 }
6231
Yaowu Xuf883b422016-08-30 14:01:10 -07006232 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006233
Yue Chene9638cc2016-10-10 12:37:54 -07006234#if CONFIG_MOTION_VAR
6235 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6236 mvp_full = mbmi->mv[0].as_mv;
6237 else
6238#endif // CONFIG_MOTION_VAR
6239 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006240
6241 mvp_full.col >>= 3;
6242 mvp_full.row >>= 3;
6243
6244 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6245
Yue Chene9638cc2016-10-10 12:37:54 -07006246#if CONFIG_MOTION_VAR
6247 switch (mbmi->motion_mode) {
6248 case SIMPLE_TRANSLATION:
6249#endif // CONFIG_MOTION_VAR
6250 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6251 sadpb, cond_cost_list(cpi, cost_list),
6252 &ref_mv, INT_MAX, 1);
6253#if CONFIG_MOTION_VAR
6254 break;
6255 case OBMC_CAUSAL:
6256 bestsme = av1_obmc_full_pixel_diamond(
6257 cpi, x, &mvp_full, step_param, sadpb,
6258 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6259 &(x->best_mv.as_mv), 0);
6260 break;
6261 default: assert("Invalid motion mode!\n");
6262 }
6263#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
6265 x->mv_col_min = tmp_col_min;
6266 x->mv_col_max = tmp_col_max;
6267 x->mv_row_min = tmp_row_min;
6268 x->mv_row_max = tmp_row_max;
6269
6270 if (bestsme < INT_MAX) {
6271 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006272#if CONFIG_MOTION_VAR
6273 switch (mbmi->motion_mode) {
6274 case SIMPLE_TRANSLATION:
6275#endif // CONFIG_MOTION_VAR
6276 if (cpi->sf.use_upsampled_references) {
6277 int best_mv_var;
6278 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6279 x->second_best_mv.as_int != x->best_mv.as_int;
6280 const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
6281 const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
6282 // Use up-sampled reference frames.
6283 struct macroblockd_plane *const pd = &xd->plane[0];
6284 struct buf_2d backup_pred = pd->pre[ref_idx];
6285 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006286
Yue Chene9638cc2016-10-10 12:37:54 -07006287 // Set pred for Y plane
6288 setup_pred_plane(
6289 &pd->pre[ref_idx], upsampled_ref->y_buffer,
6290 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6291 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6292 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293
Yue Chene9638cc2016-10-10 12:37:54 -07006294 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006295 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6296 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6297 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6298 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6299 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006300
Yue Chene9638cc2016-10-10 12:37:54 -07006301 if (try_second) {
6302 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6303 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6304 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6305 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
6306 int this_var;
6307 MV best_mv = x->best_mv.as_mv;
6308
6309 x->best_mv = x->second_best_mv;
6310 if (x->best_mv.as_mv.row * 8 <= maxr &&
6311 x->best_mv.as_mv.row * 8 >= minr &&
6312 x->best_mv.as_mv.col * 8 <= maxc &&
6313 x->best_mv.as_mv.col * 8 >= minc) {
6314 this_var = cpi->find_fractional_mv_step(
6315 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6316 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6317 cpi->sf.mv.subpel_iters_per_step,
6318 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6319 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6320 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6321 x->best_mv.as_mv = best_mv;
6322 }
6323 }
6324
6325 // Restore the reference frames.
6326 pd->pre[ref_idx] = backup_pred;
6327 } else {
6328 cpi->find_fractional_mv_step(
6329 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6330 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6331 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6332 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6333 0);
6334 }
6335#if CONFIG_MOTION_VAR
6336 break;
6337 case OBMC_CAUSAL:
6338 av1_find_best_obmc_sub_pixel_tree_up(
6339 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6340 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6341 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6342 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6343 cpi->sf.use_upsampled_references);
6344 break;
6345 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006346 }
Yue Chene9638cc2016-10-10 12:37:54 -07006347#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006348 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006349 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6350 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006351
Yue Chene9638cc2016-10-10 12:37:54 -07006352#if CONFIG_MOTION_VAR
6353 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6354#else
6355 if (cpi->sf.adaptive_motion_search)
6356#endif // CONFIG_MOTION_VAR
6357 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006358
6359 if (scaled_ref_frame) {
6360 int i;
6361 for (i = 0; i < MAX_MB_PLANE; i++)
6362 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6363 }
6364}
6365
6366static INLINE void restore_dst_buf(MACROBLOCKD *xd,
6367 uint8_t *orig_dst[MAX_MB_PLANE],
6368 int orig_dst_stride[MAX_MB_PLANE]) {
6369 int i;
6370 for (i = 0; i < MAX_MB_PLANE; i++) {
6371 xd->plane[i].dst.buf = orig_dst[i];
6372 xd->plane[i].dst.stride = orig_dst_stride[i];
6373 }
6374}
6375
Yaowu Xuc27fc142016-08-22 16:08:15 -07006376#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07006377static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006378 const uint8_t *mask, int mask_stride,
6379 BLOCK_SIZE bsize, int mi_row, int mi_col,
6380 int_mv *tmp_mv, int *rate_mv, int ref_idx,
6381 int mv_idx) {
6382 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006383 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006384 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6385 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6386 int bestsme = INT_MAX;
6387 int step_param;
6388 int sadpb = x->sadperbit16;
6389 MV mvp_full;
6390 int ref = mbmi->ref_frame[ref_idx];
6391 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6392
6393 int tmp_col_min = x->mv_col_min;
6394 int tmp_col_max = x->mv_col_max;
6395 int tmp_row_min = x->mv_row_min;
6396 int tmp_row_max = x->mv_row_max;
6397
6398 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006399 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07006400 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006401
6402 MV pred_mv[3];
6403 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6404 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6405 pred_mv[2] = x->pred_mv[ref];
6406
6407#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006408 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006409#endif
6410
6411 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006412 // Swap out the reference frame for a version that's been scaled to
6413 // match the resolution of the current frame, allowing the existing
6414 // motion search code to be used without additional modifications.
6415 for (i = 0; i < MAX_MB_PLANE; i++)
6416 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6417
Yaowu Xuf883b422016-08-30 14:01:10 -07006418 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006419 }
6420
Yaowu Xuf883b422016-08-30 14:01:10 -07006421 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006422
6423 // Work out the size of the first step in the mv step search.
6424 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
6425 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6426 // Take wtd average of the step_params based on the last frame's
6427 // max mv magnitude and that based on the best ref mvs of the current
6428 // block for the given reference.
6429 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006430 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431 2;
6432 } else {
6433 step_param = cpi->mv_step_param;
6434 }
6435
6436 // TODO(debargha): is show_frame needed here?
6437 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
6438 int boffset =
6439 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006440 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6441 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006442 }
6443
6444 if (cpi->sf.adaptive_motion_search) {
6445 int bwl = b_width_log2_lookup[bsize];
6446 int bhl = b_height_log2_lookup[bsize];
6447 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6448
6449 if (tlevel < 5) step_param += 2;
6450
6451 // prev_mv_sad is not setup for dynamically scaled frames.
6452 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006453 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6454 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6455 x->pred_mv[ref].row = 0;
6456 x->pred_mv[ref].col = 0;
6457 tmp_mv->as_int = INVALID_MV;
6458
6459 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07006460 int j;
6461 for (j = 0; j < MAX_MB_PLANE; ++j)
6462 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006463 }
6464 return;
6465 }
6466 }
6467 }
6468 }
6469
6470 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
6471
6472 mvp_full.col >>= 3;
6473 mvp_full.row >>= 3;
6474
Yaowu Xuf883b422016-08-30 14:01:10 -07006475 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006476 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
6477 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6478 &tmp_mv->as_mv, ref_idx);
6479
6480 x->mv_col_min = tmp_col_min;
6481 x->mv_col_max = tmp_col_max;
6482 x->mv_row_min = tmp_row_min;
6483 x->mv_row_max = tmp_row_max;
6484
6485 if (bestsme < INT_MAX) {
6486 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07006487 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006488 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
6489 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6490 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6491 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
6492 cpi->sf.use_upsampled_references);
6493 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006494 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
6495 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006496
6497 if (cpi->sf.adaptive_motion_search && cm->show_frame)
6498 x->pred_mv[ref] = tmp_mv->as_mv;
6499
6500 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006501 for (i = 0; i < MAX_MB_PLANE; i++)
6502 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6503 }
6504}
6505
Urvang Joshi52648442016-10-13 17:27:51 -07006506static void do_masked_motion_search_indexed(const AV1_COMP *const cpi,
6507 MACROBLOCK *x, int wedge_index,
6508 int wedge_sign, BLOCK_SIZE bsize,
6509 int mi_row, int mi_col,
6510 int_mv *tmp_mv, int *rate_mv,
6511 int mv_idx[2], int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006512 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6513 MACROBLOCKD *xd = &x->e_mbd;
6514 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6515 BLOCK_SIZE sb_type = mbmi->sb_type;
6516 const uint8_t *mask;
6517 const int mask_stride = 4 * num_4x4_blocks_wide_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006518 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006519
6520 if (which == 0 || which == 2)
6521 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6522 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
6523
6524 if (which == 1 || which == 2) {
6525 // get the negative mask
Yaowu Xuf883b422016-08-30 14:01:10 -07006526 mask = av1_get_contiguous_soft_mask(wedge_index, !wedge_sign, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006527 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
6528 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
6529 }
6530}
6531#endif // CONFIG_EXT_INTER
6532
6533// In some situations we want to discount tha pparent cost of a new motion
6534// vector. Where there is a subtle motion field and especially where there is
6535// low spatial complexity then it can be hard to cover the cost of a new motion
6536// vector in a single block, even if that motion vector reduces distortion.
6537// However, once established that vector may be usable through the nearest and
6538// near mv modes to reduce distortion in subsequent blocks and also improve
6539// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006540static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006541 int_mv this_mv,
6542 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6543 int ref_frame) {
6544 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6545 (this_mv.as_int != 0) &&
6546 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6547 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6548 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6549 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6550}
6551
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006552#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6553#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006554
6555// TODO(jingning): this mv clamping function should be block size dependent.
6556static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6557 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6558 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6559 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6560 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6561}
6562
6563#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006564static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006565 const BLOCK_SIZE bsize, const uint8_t *pred0,
6566 int stride0, const uint8_t *pred1, int stride1) {
6567 const struct macroblock_plane *const p = &x->plane[0];
6568 const uint8_t *src = p->src.buf;
6569 int src_stride = p->src.stride;
6570 const int f_index = bsize - BLOCK_8X8;
6571 const int bw = 4 << (b_width_log2_lookup[bsize]);
6572 const int bh = 4 << (b_height_log2_lookup[bsize]);
6573 uint32_t esq[2][4], var;
6574 int64_t tl, br;
6575
Yaowu Xuf883b422016-08-30 14:01:10 -07006576#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006577 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6578 pred0 = CONVERT_TO_BYTEPTR(pred0);
6579 pred1 = CONVERT_TO_BYTEPTR(pred1);
6580 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006581#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006582
6583 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6584 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
6585 stride0, &esq[0][1]);
6586 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6587 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6588 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6589 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6590 &esq[0][3]);
6591 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6592 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
6593 stride1, &esq[1][1]);
6594 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6595 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6596 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6597 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6598 &esq[1][3]);
6599 (void)var;
6600
6601 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6602 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6603 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6604 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6605 return (tl + br > 0);
6606}
6607#endif // CONFIG_EXT_INTER
6608
6609#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006610static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006611 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006612 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006613 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6614 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006615 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006616 const MACROBLOCKD *xd = &x->e_mbd;
6617 int bsl = mi_width_log2_lookup[bsize];
6618 int pred_filter_search =
6619 cpi->sf.cb_pred_filter_search
6620 ? (((mi_row + mi_col) >> bsl) +
6621 get_chessboard_index(cm->current_video_frame)) &
6622 0x1
6623 : 0;
6624 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6625 const int is_comp_pred = has_second_ref(mbmi);
6626 const int this_mode = mbmi->mode;
6627 int refs[2] = { mbmi->ref_frame[0],
6628 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006629 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006630 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006631 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6632 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6633
6634#if CONFIG_EXT_INTER
6635 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
6636 this_mode != NEW_NEWMV) ||
6637 (af == lf))
6638#else
6639 if ((this_mode != NEWMV) || (af == lf))
6640#endif // CONFIG_EXT_INTER
6641 best_filter = af;
6642 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006643 if (is_comp_pred) {
6644 if (cpi->sf.adaptive_mode_search) {
6645#if CONFIG_EXT_INTER
6646 switch (this_mode) {
6647 case NEAREST_NEARESTMV:
6648 if (single_filter[NEARESTMV][refs[0]] ==
6649 single_filter[NEARESTMV][refs[1]])
6650 best_filter = single_filter[NEARESTMV][refs[0]];
6651 break;
6652 case NEAREST_NEARMV:
6653 if (single_filter[NEARESTMV][refs[0]] ==
6654 single_filter[NEARMV][refs[1]])
6655 best_filter = single_filter[NEARESTMV][refs[0]];
6656 break;
6657 case NEAR_NEARESTMV:
6658 if (single_filter[NEARMV][refs[0]] ==
6659 single_filter[NEARESTMV][refs[1]])
6660 best_filter = single_filter[NEARMV][refs[0]];
6661 break;
6662 case NEAR_NEARMV:
6663 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6664 best_filter = single_filter[NEARMV][refs[0]];
6665 break;
6666 case ZERO_ZEROMV:
6667 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6668 best_filter = single_filter[ZEROMV][refs[0]];
6669 break;
6670 case NEW_NEWMV:
6671 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6672 best_filter = single_filter[NEWMV][refs[0]];
6673 break;
6674 case NEAREST_NEWMV:
6675 if (single_filter[NEARESTMV][refs[0]] ==
6676 single_filter[NEWMV][refs[1]])
6677 best_filter = single_filter[NEARESTMV][refs[0]];
6678 break;
6679 case NEAR_NEWMV:
6680 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6681 best_filter = single_filter[NEARMV][refs[0]];
6682 break;
6683 case NEW_NEARESTMV:
6684 if (single_filter[NEWMV][refs[0]] ==
6685 single_filter[NEARESTMV][refs[1]])
6686 best_filter = single_filter[NEWMV][refs[0]];
6687 break;
6688 case NEW_NEARMV:
6689 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6690 best_filter = single_filter[NEWMV][refs[0]];
6691 break;
6692 default:
6693 if (single_filter[this_mode][refs[0]] ==
6694 single_filter[this_mode][refs[1]])
6695 best_filter = single_filter[this_mode][refs[0]];
6696 break;
6697 }
6698#else
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#endif // CONFIG_EXT_INTER
6703 }
6704 }
Angie Chiang75c22092016-10-25 12:19:16 -07006705 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6706 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006707 }
6708 return best_filter;
6709}
6710#endif
6711
6712#if CONFIG_EXT_INTER
6713// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07006714static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006715 const BLOCK_SIZE bsize, const uint8_t *const p0,
6716 const uint8_t *const p1, int *const best_wedge_sign,
6717 int *const best_wedge_index) {
6718 const MACROBLOCKD *const xd = &x->e_mbd;
6719 const struct buf_2d *const src = &x->plane[0].src;
6720 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6721 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6722 const int N = bw * bh;
6723 int rate;
6724 int64_t dist;
6725 int64_t rd, best_rd = INT64_MAX;
6726 int wedge_index;
6727 int wedge_sign;
6728 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6729 const uint8_t *mask;
6730 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006731#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006732 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6733 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6734#else
6735 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006736#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006737
6738 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6739 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6740 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6741 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6742
6743 int64_t sign_limit;
6744
Yaowu Xuf883b422016-08-30 14:01:10 -07006745#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006746 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006747 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006748 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006749 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006750 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006751 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006752 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6753 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006754#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006755 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006756 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6757 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6758 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006759 }
6760
Yaowu Xuf883b422016-08-30 14:01:10 -07006761 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6762 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006763 (1 << WEDGE_WEIGHT_BITS) / 2;
6764
Yaowu Xuf883b422016-08-30 14:01:10 -07006765 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006766
6767 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006768 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
6769 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006770
Yaowu Xuf883b422016-08-30 14:01:10 -07006771 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6772 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006773 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6774
6775 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6776 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6777
6778 if (rd < best_rd) {
6779 *best_wedge_index = wedge_index;
6780 *best_wedge_sign = wedge_sign;
6781 best_rd = rd;
6782 }
6783 }
6784
6785 return best_rd;
6786}
6787
6788// Choose the best wedge index the specified sign
6789static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006790 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006791 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6792 const int wedge_sign, int *const best_wedge_index) {
6793 const MACROBLOCKD *const xd = &x->e_mbd;
6794 const struct buf_2d *const src = &x->plane[0].src;
6795 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6796 const int bh = 4 * num_4x4_blocks_high_lookup[bsize];
6797 const int N = bw * bh;
6798 int rate;
6799 int64_t dist;
6800 int64_t rd, best_rd = INT64_MAX;
6801 int wedge_index;
6802 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6803 const uint8_t *mask;
6804 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006805#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006806 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6807 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6808#else
6809 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07006810#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006811
6812 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6813 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6814
Yaowu Xuf883b422016-08-30 14:01:10 -07006815#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006816 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006817 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006818 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006819 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006820 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6821 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07006822#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006823 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006824 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6825 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006826 }
6827
6828 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006829 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
6830 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006831 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6832
6833 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6834 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6835
6836 if (rd < best_rd) {
6837 *best_wedge_index = wedge_index;
6838 best_rd = rd;
6839 }
6840 }
6841
6842 return best_rd;
6843}
6844
Yaowu Xuf883b422016-08-30 14:01:10 -07006845static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006846 const MACROBLOCK *const x,
6847 const BLOCK_SIZE bsize,
6848 const uint8_t *const p0,
6849 const uint8_t *const p1) {
6850 const MACROBLOCKD *const xd = &x->e_mbd;
6851 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6852 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6853
6854 int64_t rd;
6855 int wedge_index = -1;
6856 int wedge_sign = 0;
6857
6858 assert(is_interinter_wedge_used(bsize));
6859
6860 if (cpi->sf.fast_wedge_sign_estimate) {
6861 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6862 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6863 } else {
6864 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6865 }
6866
6867 mbmi->interinter_wedge_sign = wedge_sign;
6868 mbmi->interinter_wedge_index = wedge_index;
6869 return rd;
6870}
6871
Yaowu Xuf883b422016-08-30 14:01:10 -07006872static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006873 const MACROBLOCK *const x,
6874 const BLOCK_SIZE bsize,
6875 const uint8_t *const p0,
6876 const uint8_t *const p1) {
6877 const MACROBLOCKD *const xd = &x->e_mbd;
6878 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6879
6880 int64_t rd;
6881 int wedge_index = -1;
6882
6883 assert(is_interintra_wedge_used(bsize));
6884
6885 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6886
6887 mbmi->interintra_wedge_sign = 0;
6888 mbmi->interintra_wedge_index = wedge_index;
6889 return rd;
6890}
6891#endif // CONFIG_EXT_INTER
6892
6893static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08006894 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
6895 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006896 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
6897 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07006898#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07006899 uint8_t *above_pred_buf[3], int above_pred_stride[3],
6900 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07006901#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006902#if CONFIG_EXT_INTER
6903 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
6904 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
6905 int *compmode_interintra_cost, int *compmode_wedge_cost,
6906 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
6907#else
6908 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
6909#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07006910 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Angie Chiang76159122016-11-09 12:13:22 -08006911 int (*single_skippable)[TOTAL_REFS_PER_FRAME], const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07006912 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006913 MACROBLOCKD *xd = &x->e_mbd;
6914 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6915 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6916 const int is_comp_pred = has_second_ref(mbmi);
6917 const int this_mode = mbmi->mode;
6918 int_mv *frame_mv = mode_mv[this_mode];
6919 int i;
6920 int refs[2] = { mbmi->ref_frame[0],
6921 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
6922 int_mv cur_mv[2];
6923 int rate_mv = 0;
6924#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07006925 int pred_exists = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006926 const int bw = 4 * num_4x4_blocks_wide_lookup[bsize];
6927 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6928 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
6929 const unsigned int *const interintra_mode_cost =
6930 cpi->interintra_mode_cost[size_group_lookup[bsize]];
6931 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6932#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006933 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006934#endif
6935#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006936#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006937 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
6938#else
6939 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006940#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006941 uint8_t *tmp_buf;
6942
Yue Chencb60b182016-10-13 15:18:22 -07006943#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006944 int allow_motvar =
6945#if CONFIG_EXT_INTER
6946 !is_comp_interintra_pred &&
6947#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006948 is_motion_variation_allowed(mbmi);
Angie Chiang76159122016-11-09 12:13:22 -08006949 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
6950 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006951#if CONFIG_VAR_TX
6952 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
6953#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07006954 int64_t best_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006955 MB_MODE_INFO best_mbmi;
6956#if CONFIG_EXT_INTER
6957 int rate2_bmc_nocoeff;
6958 int rate_mv_bmc;
6959 MB_MODE_INFO best_bmc_mbmi;
6960#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07006961#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07006962 int64_t rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006963 uint8_t *orig_dst[MAX_MB_PLANE];
6964 int orig_dst_stride[MAX_MB_PLANE];
Angie Chiang75c22092016-10-25 12:19:16 -07006965 uint8_t *tmp_dst[MAX_MB_PLANE];
6966 int tmp_dst_stride[MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006967 int rs = 0;
Angie Chiang75c22092016-10-25 12:19:16 -07006968 InterpFilter assign_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006969
6970 int skip_txfm_sb = 0;
6971 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006972 int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
Angie Chiang76159122016-11-09 12:13:22 -08006973#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
6974 av1_invalid_rd_stats(&best_rd_stats);
6975#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006976
6977#if CONFIG_EXT_INTER
6978 *compmode_interintra_cost = 0;
6979 mbmi->use_wedge_interintra = 0;
6980 *compmode_wedge_cost = 0;
Sarah Parker6fddd182016-11-10 20:57:20 -08006981 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006982
6983 // is_comp_interintra_pred implies !is_comp_pred
6984 assert(!is_comp_interintra_pred || (!is_comp_pred));
6985 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
6986 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
6987#endif // CONFIG_EXT_INTER
6988
6989#if CONFIG_REF_MV
6990#if CONFIG_EXT_INTER
6991 if (is_comp_pred)
6992 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
6993 else
6994#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006995 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
6996 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006997#endif
6998
Yaowu Xuf883b422016-08-30 14:01:10 -07006999#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007000 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7001 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7002 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007003#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007004 tmp_buf = tmp_buf_;
7005
7006 if (is_comp_pred) {
7007 if (frame_mv[refs[0]].as_int == INVALID_MV ||
7008 frame_mv[refs[1]].as_int == INVALID_MV)
7009 return INT64_MAX;
7010 }
7011
Yue Chene9638cc2016-10-10 12:37:54 -07007012 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007013 if (have_newmv_in_inter_mode(this_mode)) {
7014 if (is_comp_pred) {
7015#if CONFIG_EXT_INTER
7016 for (i = 0; i < 2; ++i) {
7017 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
7018 }
7019
7020 if (this_mode == NEW_NEWMV) {
7021 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7022 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7023
7024 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7025 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
7026 single_newmv, &rate_mv, 0);
7027 } else {
7028#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007029 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007030#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007031 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007032 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007033 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007034#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007035 av1_set_mvcost(x, mbmi->ref_frame[1], 1, 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(
Zoe Liu82c8c922016-11-01 14:52:34 -07007038 &frame_mv[refs[1]].as_mv, &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007039 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7040 }
7041 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7042 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007043 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007044 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007045 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007046 } else {
7047 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007048 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007049 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007050 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007051 }
7052#else
7053 // Initialize mv using single prediction mode result.
7054 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7055 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7056
7057 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7058 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
7059 single_newmv, &rate_mv, 0);
7060 } else {
7061#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007062 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007063#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007064 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007065 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07007066 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007067#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007068 av1_set_mvcost(x, mbmi->ref_frame[1], 1, 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[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07007071 &mbmi_ext->ref_mvs[refs[1]][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 }
7074#endif // CONFIG_EXT_INTER
7075 } else {
7076#if CONFIG_EXT_INTER
7077 if (is_comp_interintra_pred) {
7078 x->best_mv = single_newmvs[mv_idx][refs[0]];
7079 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
7080 } else {
7081 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
7082 &rate_mv);
7083 single_newmvs[mv_idx][refs[0]] = x->best_mv;
7084 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
7085 }
7086#else
7087 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
7088 single_newmv[refs[0]] = x->best_mv;
7089#endif // CONFIG_EXT_INTER
7090
7091 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7092
7093 frame_mv[refs[0]] = x->best_mv;
7094 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7095
7096 // Estimate the rate implications of a new mv but discount this
7097 // under certain circumstances where we want to help initiate a weak
7098 // motion field, where the distortion gain for a single block may not
7099 // be enough to overcome the cost of a new mv.
7100 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007101 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007102 }
7103 }
Angie Chiang76159122016-11-09 12:13:22 -08007104 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007105 }
7106
7107 for (i = 0; i < is_comp_pred + 1; ++i) {
7108 cur_mv[i] = frame_mv[refs[i]];
7109// Clip "next_nearest" so that it does not extend to far out of image
7110#if CONFIG_EXT_INTER
7111 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
7112#else
7113 if (this_mode != NEWMV)
7114#endif // CONFIG_EXT_INTER
7115 clamp_mv2(&cur_mv[i].as_mv, xd);
7116
7117 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7118 mbmi->mv[i].as_int = cur_mv[i].as_int;
7119 }
7120
7121#if CONFIG_REF_MV
7122#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007123 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007124#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08007125 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007126#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007127 {
7128#if !CONFIG_EXT_INTER
7129 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
7130#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007131 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7132 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7133 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7134
7135 for (i = 0; i < 2; ++i) {
7136 clamp_mv2(&cur_mv[i].as_mv, xd);
7137 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7138 mbmi->mv[i].as_int = cur_mv[i].as_int;
7139 }
7140 }
7141 }
7142
7143#if CONFIG_EXT_INTER
7144 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7145 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
7146 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7147
7148 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7149 clamp_mv2(&cur_mv[0].as_mv, xd);
7150 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7151 mbmi->mv[0].as_int = cur_mv[0].as_int;
7152 }
7153
7154 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
7155 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7156
7157 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7158 clamp_mv2(&cur_mv[1].as_mv, xd);
7159 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7160 mbmi->mv[1].as_int = cur_mv[1].as_int;
7161 }
7162 }
7163
7164 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7165 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
7166 this_mode == NEAR_NEARMV) {
7167 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
7168
7169 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7170 clamp_mv2(&cur_mv[0].as_mv, xd);
7171 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
7172 mbmi->mv[0].as_int = cur_mv[0].as_int;
7173 }
7174
7175 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
7176 this_mode == NEAR_NEARMV) {
7177 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
7178
7179 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7180 clamp_mv2(&cur_mv[1].as_mv, xd);
7181 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
7182 mbmi->mv[1].as_int = cur_mv[1].as_int;
7183 }
7184 }
7185#else
7186 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007187 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007188 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7189 int ref_mv_idx = mbmi->ref_mv_idx + 1;
7190 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
7191 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
7192
7193 for (i = 0; i < 2; ++i) {
7194 clamp_mv2(&cur_mv[i].as_mv, xd);
7195 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
7196 mbmi->mv[i].as_int = cur_mv[i].as_int;
7197 }
7198 }
7199 }
7200#endif // CONFIG_EXT_INTER
7201#endif // CONFIG_REF_MV
7202
7203 // do first prediction into the destination buffer. Do the next
7204 // prediction into a temporary buffer. Then keep track of which one
7205 // of these currently holds the best predictor, and use the other
7206 // one for future predictions. In the end, copy from tmp_buf to
7207 // dst if necessary.
7208 for (i = 0; i < MAX_MB_PLANE; i++) {
Angie Chiang75c22092016-10-25 12:19:16 -07007209 tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
7210 tmp_dst_stride[i] = MAX_SB_SIZE;
7211 }
7212 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007213 orig_dst[i] = xd->plane[i].dst.buf;
7214 orig_dst_stride[i] = xd->plane[i].dst.stride;
7215 }
7216
7217 // We don't include the cost of the second reference here, because there
7218 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
7219 // words if you present them in that order, the second one is always known
7220 // if the first is known.
7221 //
7222 // Under some circumstances we discount the cost of new mv mode to encourage
7223 // initiation of a motion field.
7224 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
7225 refs[0])) {
7226#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007227 rd_stats->rate +=
7228 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
7229 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007230#else
Angie Chiang76159122016-11-09 12:13:22 -08007231 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7232 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007233#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7234 } else {
7235#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007236 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007237#else
Angie Chiang76159122016-11-09 12:13:22 -08007238 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007239#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
7240 }
7241
Angie Chiang76159122016-11-09 12:13:22 -08007242 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07007243#if CONFIG_EXT_INTER
7244 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
7245#else
7246 mbmi->mode != NEARESTMV
7247#endif // CONFIG_EXT_INTER
7248 )
7249 return INT64_MAX;
7250
Angie Chiang75c22092016-10-25 12:19:16 -07007251 if (cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007252#if !CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007253 assign_filter =
7254 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007255#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007256#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
7257 if (!av1_is_interp_needed(xd)) assign_filter = EIGHTTAP_REGULAR;
7258#endif
7259 } else {
7260 assign_filter = cm->interp_filter;
7261 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007262
Angie Chiang75c22092016-10-25 12:19:16 -07007263 { // Do interpolation filter search in the parentheses
7264 int tmp_rate;
7265 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007266#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007267 mbmi->interp_filter[0] =
7268 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7269 mbmi->interp_filter[1] =
7270 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7271 mbmi->interp_filter[2] =
7272 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
7273 mbmi->interp_filter[3] =
7274 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007275#else
Angie Chiang75c22092016-10-25 12:19:16 -07007276 mbmi->interp_filter =
7277 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007278#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007279 rs = av1_get_switchable_rate(cpi, xd);
7280 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7281 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7282 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7283 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007284
Angie Chiang75c22092016-10-25 12:19:16 -07007285 if (assign_filter == SWITCHABLE) {
7286 // do interp_filter search
7287 if (av1_is_interp_needed(xd)) {
7288 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007289#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007290 InterpFilter best_filter[4];
7291 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007292#else
Angie Chiang75c22092016-10-25 12:19:16 -07007293 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007294#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007295 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7296#if CONFIG_DUAL_FILTER
7297 // EIGHTTAP_REGULAR mode is calculated beforehand
7298 for (i = 1; i < SWITCHABLE_FILTERS * SWITCHABLE_FILTERS; ++i)
7299#else
7300 // EIGHTTAP_REGULAR mode is calculated beforehand
7301 for (i = 1; i < SWITCHABLE_FILTERS; ++i)
7302#endif
7303 {
7304 int tmp_skip_sb = 0;
7305 int64_t tmp_skip_sse = INT64_MAX;
7306 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07007307 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07007308#if CONFIG_DUAL_FILTER
7309 mbmi->interp_filter[0] = filter_sets[i][0];
7310 mbmi->interp_filter[1] = filter_sets[i][1];
7311 mbmi->interp_filter[2] = filter_sets[i][0];
7312 mbmi->interp_filter[3] = filter_sets[i][1];
7313#else
7314 mbmi->interp_filter = i;
7315#endif
7316 tmp_rs = av1_get_switchable_rate(cpi, xd);
7317 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
7318 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7319 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7320 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007321
Angie Chiang75c22092016-10-25 12:19:16 -07007322 if (tmp_rd < rd) {
7323 rd = tmp_rd;
7324 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007325#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007326 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007327#else
Angie Chiang75c22092016-10-25 12:19:16 -07007328 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007329#endif
Angie Chiang75c22092016-10-25 12:19:16 -07007330 skip_txfm_sb = tmp_skip_sb;
7331 skip_sse_sb = tmp_skip_sse;
7332 best_in_temp = !best_in_temp;
7333 if (best_in_temp) {
7334 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7335 } else {
7336 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7337 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007338 }
7339 }
Angie Chiang75c22092016-10-25 12:19:16 -07007340 if (best_in_temp) {
7341 restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
7342 } else {
7343 restore_dst_buf(xd, orig_dst, orig_dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007344 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007345#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07007346 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007347#else
Angie Chiang75c22092016-10-25 12:19:16 -07007348 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007349#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007350 } else {
Angie Chiang75c22092016-10-25 12:19:16 -07007351#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
7352 int tmp_rs;
7353 InterpFilter best_filter = mbmi->interp_filter;
7354 rs = av1_get_switchable_rate(cpi, xd);
7355 for (i = 1; i < SWITCHABLE_FILTERS; ++i) {
7356 mbmi->interp_filter = i;
7357 tmp_rs = av1_get_switchable_rate(cpi, xd);
7358 if (tmp_rs < rs) {
7359 rs = tmp_rs;
7360 best_filter = i;
7361 }
7362 }
7363 mbmi->interp_filter = best_filter;
7364#else
7365 assert(0);
7366#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007367 }
7368 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007369 }
7370
Yaowu Xuc27fc142016-08-22 16:08:15 -07007371#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007372#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007373 best_bmc_mbmi = *mbmi;
7374 rate_mv_bmc = rate_mv;
Angie Chiang76159122016-11-09 12:13:22 -08007375 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007376 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007377#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007378
7379 if (is_comp_pred && is_interinter_wedge_used(bsize)) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007380 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007381 int64_t dist_sum;
7382 int64_t best_rd_nowedge = INT64_MAX;
7383 int64_t best_rd_wedge = INT64_MAX;
7384 int tmp_skip_txfm_sb;
7385 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08007386 int compound_type_cost[COMPOUND_TYPES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007387
Sarah Parker6fddd182016-11-10 20:57:20 -08007388 mbmi->interinter_compound = COMPOUND_AVERAGE;
7389 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
7390 av1_compound_type_tree);
7391 rs2 = compound_type_cost[mbmi->interinter_compound];
Yaowu Xuf883b422016-08-30 14:01:10 -07007392 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
7393 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007394 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7395 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7396 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007397 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007398 best_rd_nowedge = rd;
7399
7400 // Disbale wedge search if source variance is small
7401 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7402 best_rd_nowedge / 3 < ref_best_rd) {
7403 uint8_t pred0[2 * MAX_SB_SQUARE];
7404 uint8_t pred1[2 * MAX_SB_SQUARE];
7405 uint8_t *preds0[1] = { pred0 };
7406 uint8_t *preds1[1] = { pred1 };
7407 int strides[1] = { bw };
7408
Sarah Parker6fddd182016-11-10 20:57:20 -08007409 mbmi->interinter_compound = COMPOUND_WEDGE;
Urvang Joshi368fbc92016-10-17 16:31:34 -07007410 rs2 = av1_cost_literal(get_interinter_wedge_bits(bsize)) +
Sarah Parker6fddd182016-11-10 20:57:20 -08007411 compound_type_cost[mbmi->interinter_compound];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007412
Yaowu Xuf883b422016-08-30 14:01:10 -07007413 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007414 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007415 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007416 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
7417
7418 // Choose the best wedge
7419 best_rd_wedge = pick_interinter_wedge(cpi, x, bsize, pred0, pred1);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007420 best_rd_wedge += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007421
7422 if (have_newmv_in_inter_mode(this_mode)) {
7423 int_mv tmp_mv[2];
7424 int rate_mvs[2], tmp_rate_mv = 0;
7425 if (this_mode == NEW_NEWMV) {
7426 int mv_idxs[2] = { 0, 0 };
7427 do_masked_motion_search_indexed(
7428 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7429 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 2);
7430 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7431 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7432 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7433 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7434 int mv_idxs[2] = { 0, 0 };
7435 do_masked_motion_search_indexed(
7436 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7437 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 0);
7438 tmp_rate_mv = rate_mvs[0];
7439 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7440 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7441 int mv_idxs[2] = { 0, 0 };
7442 do_masked_motion_search_indexed(
7443 cpi, x, mbmi->interinter_wedge_index, mbmi->interinter_wedge_sign,
7444 bsize, mi_row, mi_col, tmp_mv, rate_mvs, mv_idxs, 1);
7445 tmp_rate_mv = rate_mvs[1];
7446 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7447 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007448 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007449 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7450 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007451 rd =
7452 RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007453 if (rd < best_rd_wedge) {
7454 best_rd_wedge = rd;
7455 } else {
7456 mbmi->mv[0].as_int = cur_mv[0].as_int;
7457 mbmi->mv[1].as_int = cur_mv[1].as_int;
7458 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007459 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7460 strides, preds1, strides);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007461 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007462 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007463 rd =
7464 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7465 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7466 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007467 rd = RDCOST(x->rdmult, x->rddiv, rs2 + tmp_rate_mv + rate_sum,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007468 dist_sum);
7469 best_rd_wedge = rd;
7470
7471 if (best_rd_wedge < best_rd_nowedge) {
Sarah Parker6fddd182016-11-10 20:57:20 -08007472 mbmi->interinter_compound = COMPOUND_WEDGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007473 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7474 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007475 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007476 rate_mv = tmp_rate_mv;
7477 } else {
Sarah Parker6fddd182016-11-10 20:57:20 -08007478 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007479 mbmi->mv[0].as_int = cur_mv[0].as_int;
7480 mbmi->mv[1].as_int = cur_mv[1].as_int;
7481 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7482 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
7483 }
7484 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007485 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0, preds0,
7486 strides, preds1, strides);
7487 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007488 rd =
7489 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7490 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7491 if (rd != INT64_MAX)
Urvang Joshi368fbc92016-10-17 16:31:34 -07007492 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007493 best_rd_wedge = rd;
7494 if (best_rd_wedge < best_rd_nowedge) {
Sarah Parker6fddd182016-11-10 20:57:20 -08007495 mbmi->interinter_compound = COMPOUND_WEDGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007496 } else {
Sarah Parker6fddd182016-11-10 20:57:20 -08007497 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007498 }
7499 }
7500 }
7501 if (ref_best_rd < INT64_MAX &&
Yaowu Xuf883b422016-08-30 14:01:10 -07007502 AOMMIN(best_rd_wedge, best_rd_nowedge) / 3 > ref_best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007503 return INT64_MAX;
7504
7505 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007506
Sarah Parker6fddd182016-11-10 20:57:20 -08007507 *compmode_wedge_cost = compound_type_cost[mbmi->interinter_compound];
7508
7509 if (mbmi->interinter_compound)
7510 *compmode_wedge_cost +=
7511 av1_cost_literal(get_interinter_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007512 }
7513
7514 if (is_comp_interintra_pred) {
7515 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7516 int64_t best_interintra_rd = INT64_MAX;
7517 int rmode, rate_sum;
7518 int64_t dist_sum;
7519 int j;
7520 int64_t best_interintra_rd_nowedge = INT64_MAX;
7521 int64_t best_interintra_rd_wedge = INT64_MAX;
7522 int rwedge;
7523 int_mv tmp_mv;
7524 int tmp_rate_mv = 0;
7525 int tmp_skip_txfm_sb;
7526 int64_t tmp_skip_sse_sb;
7527 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7528 uint8_t *intrapred;
7529
Yaowu Xuf883b422016-08-30 14:01:10 -07007530#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007531 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7532 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7533 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007534#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007535 intrapred = intrapred_;
7536
7537 mbmi->ref_frame[1] = NONE;
7538 for (j = 0; j < MAX_MB_PLANE; j++) {
7539 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7540 xd->plane[j].dst.stride = bw;
7541 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007542 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007543 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7544 mbmi->ref_frame[1] = INTRA_FRAME;
7545 mbmi->use_wedge_interintra = 0;
7546
7547 for (j = 0; j < INTERINTRA_MODES; ++j) {
7548 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7549 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007550 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7551 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007552 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7553 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7554 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
7555 if (rd < best_interintra_rd) {
7556 best_interintra_rd = rd;
7557 best_interintra_mode = mbmi->interintra_mode;
7558 }
7559 }
7560 mbmi->interintra_mode = best_interintra_mode;
7561 rmode = interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuf883b422016-08-30 14:01:10 -07007562 av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
7563 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7564 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007565 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7566 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7567 if (rd != INT64_MAX)
7568 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7569 best_interintra_rd = rd;
7570
7571 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
7572 return INT64_MAX;
7573 }
7574 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007575 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007576 if (rd != INT64_MAX)
7577 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7578 dist_sum);
7579 best_interintra_rd_nowedge = rd;
7580
7581 // Disbale wedge search if source variance is small
7582 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7583 mbmi->use_wedge_interintra = 1;
7584
Yaowu Xuf883b422016-08-30 14:01:10 -07007585 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7586 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007587
7588 best_interintra_rd_wedge =
7589 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7590
7591 best_interintra_rd_wedge +=
7592 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7593 // Refine motion vector.
7594 if (have_newmv_in_inter_mode(this_mode)) {
7595 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007596 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007597 mbmi->interintra_wedge_index, 1, bsize);
7598 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
7599 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
7600 mbmi->mv[0].as_int = tmp_mv.as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07007601 av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007602 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7603 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7604 rd = RDCOST(x->rdmult, x->rddiv,
7605 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7606 if (rd < best_interintra_rd_wedge) {
7607 best_interintra_rd_wedge = rd;
7608 } else {
7609 tmp_mv.as_int = cur_mv[0].as_int;
7610 tmp_rate_mv = rate_mv;
7611 }
7612 } else {
7613 tmp_mv.as_int = cur_mv[0].as_int;
7614 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007615 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007616 }
7617 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007618 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007619 rd =
7620 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7621 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7622 if (rd != INT64_MAX)
7623 rd = RDCOST(x->rdmult, x->rddiv,
7624 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7625 best_interintra_rd_wedge = rd;
7626 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7627 mbmi->use_wedge_interintra = 1;
7628 best_interintra_rd = best_interintra_rd_wedge;
7629 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007630 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007631 rate_mv = tmp_rate_mv;
7632 } else {
7633 mbmi->use_wedge_interintra = 0;
7634 best_interintra_rd = best_interintra_rd_nowedge;
7635 mbmi->mv[0].as_int = cur_mv[0].as_int;
7636 }
7637 } else {
7638 mbmi->use_wedge_interintra = 0;
7639 best_interintra_rd = best_interintra_rd_nowedge;
7640 }
7641 }
7642
7643 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007644 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007645 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007646 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
7647 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007648 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007649 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7650 if (mbmi->use_wedge_interintra) {
7651 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007652 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007653 }
7654 }
7655 } else if (is_interintra_allowed(mbmi)) {
7656 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007657 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007658 }
7659
7660#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007661 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007662#if CONFIG_DUAL_FILTER
7663 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
7664#else
7665 mbmi->interp_filter = EIGHTTAP_REGULAR;
7666#endif
7667 pred_exists = 0;
7668 }
7669#endif // CONFIG_EXT_INTERP
Angie Chiang75c22092016-10-25 12:19:16 -07007670 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007671 int tmp_rate;
7672 int64_t tmp_dist;
Yaowu Xuf883b422016-08-30 14:01:10 -07007673 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007674 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7675 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7676 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7677 }
Angie Chiang75c22092016-10-25 12:19:16 -07007678#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007679
7680#if CONFIG_DUAL_FILTER
7681 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
7682#else
7683 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
7684#endif
7685
7686#if CONFIG_EXT_INTER
7687 if (modelled_rd != NULL) {
7688 if (is_comp_pred) {
7689 const int mode0 = compound_ref0_mode(this_mode);
7690 const int mode1 = compound_ref1_mode(this_mode);
7691 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07007692 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007693 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
7694 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7695 return INT64_MAX;
7696 }
7697 } else if (!is_comp_interintra_pred) {
7698 modelled_rd[this_mode][refs[0]] = rd;
7699 }
7700 }
7701#endif // CONFIG_EXT_INTER
7702
7703 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
7704 // if current pred_error modeled rd is substantially more than the best
7705 // so far, do not bother doing full rd
7706 if (rd / 2 > ref_best_rd) {
7707 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7708 return INT64_MAX;
7709 }
7710 }
7711
Angie Chiang76159122016-11-09 12:13:22 -08007712 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chencb60b182016-10-13 15:18:22 -07007713#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08007714 rate2_nocoeff = rd_stats->rate;
Yue Chencb60b182016-10-13 15:18:22 -07007715#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007716
Yue Chencb60b182016-10-13 15:18:22 -07007717#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007718 best_rd = INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007719 for (mbmi->motion_mode = SIMPLE_TRANSLATION;
7720 mbmi->motion_mode < (allow_motvar ? MOTION_MODES : 1);
7721 mbmi->motion_mode++) {
Angie Chianga2b56d32016-10-25 17:34:59 -07007722 int64_t tmp_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007723#if CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007724 int tmp_rate2 = mbmi->motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff
7725 : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007726#else
7727 int tmp_rate2 = rate2_nocoeff;
7728#endif // CONFIG_EXT_INTER
7729#if CONFIG_EXT_INTERP
7730#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007731 InterpFilter obmc_interp_filter[2][2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007732 { mbmi->interp_filter[0], mbmi->interp_filter[1] }, // obmc == 0
7733 { mbmi->interp_filter[0], mbmi->interp_filter[1] } // obmc == 1
7734 };
7735#else
James Zern7b9407a2016-05-18 23:48:05 -07007736 InterpFilter obmc_interp_filter[2] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007737 mbmi->interp_filter, // obmc == 0
7738 mbmi->interp_filter // obmc == 1
7739 };
7740#endif // CONFIG_DUAL_FILTER
7741#endif // CONFIG_EXT_INTERP
7742
Yue Chencb60b182016-10-13 15:18:22 -07007743#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007744 int tmp_rate;
7745 int64_t tmp_dist;
Yue Chencb60b182016-10-13 15:18:22 -07007746 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007747#if CONFIG_EXT_INTER
7748 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07007749 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007750#endif // CONFIG_EXT_INTER
7751 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007752 int tmp_rate_mv = 0;
7753
Yue Chene9638cc2016-10-10 12:37:54 -07007754 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007755#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007756 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007757#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07007758 &tmp_rate_mv);
7759 mbmi->mv[0].as_int = x->best_mv.as_int;
7760 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7761 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007762 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007763 }
7764#if CONFIG_EXT_INTER
7765 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7766#else
7767 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7768#endif // CONFIG_EXT_INTER
7769#if CONFIG_EXT_INTERP
7770#if CONFIG_DUAL_FILTER
7771 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7772 obmc_interp_filter[1][0] = mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7773 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7774 obmc_interp_filter[1][1] = mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7775#else
Yaowu Xuf883b422016-08-30 14:01:10 -07007776 if (!av1_is_interp_needed(xd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007777 obmc_interp_filter[1] = mbmi->interp_filter = EIGHTTAP_REGULAR;
7778#endif // CONFIG_DUAL_FILTER
7779 // This is not quite correct with CONFIG_DUAL_FILTER when a filter
7780 // is needed in only one direction
Yaowu Xuf883b422016-08-30 14:01:10 -07007781 if (!av1_is_interp_needed(xd)) tmp_rate2 -= rs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007782#endif // CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07007783 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007784#if CONFIG_EXT_INTER
7785 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07007786 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007787#endif // CONFIG_EXT_INTER
7788 }
Yue Chene9638cc2016-10-10 12:37:54 -07007789 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
7790 above_pred_stride, left_pred_buf,
7791 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007792 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7793 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7794 }
Yue Chencb60b182016-10-13 15:18:22 -07007795#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007796
7797#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07007798 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007799 // TODO(yuec): Add code
7800 }
7801#endif // CONFIG_WARPED_MOTION
7802 x->skip = 0;
7803
Angie Chiang76159122016-11-09 12:13:22 -08007804 rd_stats->rate = tmp_rate2;
7805 if (allow_motvar)
7806 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7807 rd_stats->dist = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007808#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007809 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007810 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07007811 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08007812
Yaowu Xu1e761992016-11-09 15:01:47 -08007813 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08007814 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007815#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08007816 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08007817 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007818 } else {
7819 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08007820 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007821 for (idy = 0; idy < xd->n8_h; ++idy)
7822 for (idx = 0; idx < xd->n8_w; ++idx)
7823 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08007824 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08007825 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7826 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08007827#else
Yaowu Xu1e761992016-11-09 15:01:47 -08007828 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08007829 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08007830/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007831#endif // CONFIG_VAR_TX
7832
Angie Chiang76159122016-11-09 12:13:22 -08007833 if (rd_stats_y->rate == INT_MAX) {
7834 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07007835#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7836 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007837 continue;
7838 } else {
Yue Chencb60b182016-10-13 15:18:22 -07007839#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007840 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7841 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007842#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007843 }
Yue Chencb60b182016-10-13 15:18:22 -07007844#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007845 }
7846
Angie Chiang76159122016-11-09 12:13:22 -08007847 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007848
Angie Chiang76159122016-11-09 12:13:22 -08007849 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7850 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007851/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07007852#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007853 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007854 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007855#else
7856 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08007857 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08007858#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07007859 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07007860#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007861 continue;
7862#else
Debargha Mukherjee0e119122016-11-04 12:10:23 -07007863 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7864 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07007865#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007866 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08007867 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08007868 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08007869#if CONFIG_RD_DEBUG
7870 // record transform block coefficient cost
7871 // TODO(angiebird): So far rd_debug tool only detects descrepancy of
7872 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
7873 // here because we already collect the coefficient cost. Move this part to
7874 // other place when we need to compare non-coefficient cost.
7875 mbmi->rd_stats = *rd_stats;
7876#endif
Yue Chencb60b182016-10-13 15:18:22 -07007877#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007878 if (rd_stats->skip) {
7879 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7880 rd_stats_y->rate = 0;
7881 rd_stats_uv->rate = 0;
7882 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007883 mbmi->skip = 0;
7884 // here mbmi->skip temporarily plays a role as what this_skip2 does
7885 } else if (!xd->lossless[mbmi->segment_id] &&
7886 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007887 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07007888 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08007889 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07007890 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08007891 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
7892 rd_stats->sse))) {
7893 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7894 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7895 rd_stats->dist = rd_stats->sse;
7896 rd_stats_y->rate = 0;
7897 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007898 mbmi->skip = 1;
7899 } else {
Angie Chiang76159122016-11-09 12:13:22 -08007900 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007901 mbmi->skip = 0;
7902 }
7903 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007904#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007905 } else {
7906 x->skip = 1;
7907 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07007908 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007909
7910// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07007911#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007912 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07007913#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007914 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007915
Angie Chiang76159122016-11-09 12:13:22 -08007916 rd_stats->dist = skip_sse_sb;
7917 rd_stats->sse = skip_sse_sb;
7918 rd_stats_y->rate = 0;
7919 rd_stats_uv->rate = 0;
7920 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007921 }
Sarah Parkere5299862016-08-16 14:57:37 -07007922#if CONFIG_GLOBAL_MOTION
7923 if (this_mode == ZEROMV) {
Angie Chiang76159122016-11-09 12:13:22 -08007924 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
7925 if (is_comp_pred)
7926 rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
Sarah Parkere5299862016-08-16 14:57:37 -07007927 }
7928#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007929
Yue Chencb60b182016-10-13 15:18:22 -07007930#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08007931 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07007932 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007933#if CONFIG_EXT_INTERP
7934#if CONFIG_DUAL_FILTER
Yue Chencb60b182016-10-13 15:18:22 -07007935 mbmi->interp_filter[0] = obmc_interp_filter[mbmi->motion_mode][0];
7936 mbmi->interp_filter[1] = obmc_interp_filter[mbmi->motion_mode][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007937#else
Yue Chencb60b182016-10-13 15:18:22 -07007938 mbmi->interp_filter = obmc_interp_filter[mbmi->motion_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007939#endif // CONFIG_DUAL_FILTER
7940#endif // CONFIG_EXT_INTERP
7941 best_mbmi = *mbmi;
7942 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08007943 best_rd_stats = *rd_stats;
7944 best_rd_stats_y = *rd_stats_y;
7945 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007946#if CONFIG_VAR_TX
7947 for (i = 0; i < MAX_MB_PLANE; ++i)
7948 memcpy(best_blk_skip[i], x->blk_skip[i],
7949 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7950#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07007951 best_xskip = x->skip;
7952 best_disable_skip = *disable_skip;
Yaowu Xuf883b422016-08-30 14:01:10 -07007953#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007954 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007955 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007956 cpi, &xd->plane[0].dst, bsize, xd->bd);
7957 } else {
7958 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007959 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007960 }
7961#else
7962 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007963 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
7964#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007965 }
7966 }
7967
7968 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08007969 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007970 restore_dst_buf(xd, orig_dst, orig_dst_stride);
7971 return INT64_MAX;
7972 }
7973 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08007974 *rd_stats = best_rd_stats;
7975 *rd_stats_y = best_rd_stats_y;
7976 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007977#if CONFIG_VAR_TX
7978 for (i = 0; i < MAX_MB_PLANE; ++i)
7979 memcpy(x->blk_skip[i], best_blk_skip[i],
7980 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7981#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07007982 x->skip = best_xskip;
7983 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07007984#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007985
Angie Chiang76159122016-11-09 12:13:22 -08007986 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007987
Yue Chencb60b182016-10-13 15:18:22 -07007988#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuf883b422016-08-30 14:01:10 -07007989#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007990 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007991 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007992 cpi, &xd->plane[0].dst, bsize, xd->bd);
7993 } else {
7994 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007995 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007996 }
7997#else
7998 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07007999 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8000#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008001#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008002
8003 restore_dst_buf(xd, orig_dst, orig_dst_stride);
8004 return 0; // The rate-distortion cost will be re-calculated by caller.
8005}
8006
Urvang Joshi52648442016-10-13 17:27:51 -07008007void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
8008 RD_COST *rd_cost, BLOCK_SIZE bsize,
8009 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
8010 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008011 MACROBLOCKD *const xd = &x->e_mbd;
8012 struct macroblockd_plane *const pd = xd->plane;
8013 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
8014 int y_skip = 0, uv_skip = 0;
8015 int64_t dist_y = 0, dist_uv = 0;
8016 TX_SIZE max_uv_tx_size;
8017 ctx->skip = 0;
8018 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
8019 xd->mi[0]->mbmi.ref_frame[1] = NONE;
8020
8021 if (bsize >= BLOCK_8X8) {
8022 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
8023 &y_skip, bsize, best_rd) >= best_rd) {
8024 rd_cost->rate = INT_MAX;
8025 return;
8026 }
8027 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008028 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07008029 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008030 rd_cost->rate = INT_MAX;
8031 return;
8032 }
8033 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008034 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
8035 [pd[1].subsampling_x][pd[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008036 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008037 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008038
8039 if (y_skip && uv_skip) {
8040 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07008041 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008042 rd_cost->dist = dist_y + dist_uv;
8043 } else {
8044 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07008045 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008046 rd_cost->dist = dist_y + dist_uv;
8047 }
8048
8049 ctx->mic = *xd->mi[0];
8050 ctx->mbmi_ext = *x->mbmi_ext;
8051 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
8052}
8053
Yaowu Xuc27fc142016-08-22 16:08:15 -07008054// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07008055int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008056 return (cpi->oxcf.pass == 2) &&
8057 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
8058 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
8059}
8060
8061// Checks to see if a super block is on a horizontal image edge.
8062// In most cases this is the "real" edge unless there are formatting
8063// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008064int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008065 int top_edge = 0;
8066 int bottom_edge = cpi->common.mi_rows;
8067 int is_active_h_edge = 0;
8068
8069 // For two pass account for any formatting bars detected.
8070 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008071 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008072
8073 // The inactive region is specified in MBs not mi units.
8074 // The image edge is in the following MB row.
8075 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
8076
8077 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008078 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008079 }
8080
8081 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
8082 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
8083 is_active_h_edge = 1;
8084 }
8085 return is_active_h_edge;
8086}
8087
8088// Checks to see if a super block is on a vertical image edge.
8089// In most cases this is the "real" edge unless there are formatting
8090// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008091int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008092 int left_edge = 0;
8093 int right_edge = cpi->common.mi_cols;
8094 int is_active_v_edge = 0;
8095
8096 // For two pass account for any formatting bars detected.
8097 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008098 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008099
8100 // The inactive region is specified in MBs not mi units.
8101 // The image edge is in the following MB row.
8102 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
8103
8104 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008105 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008106 }
8107
8108 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
8109 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
8110 is_active_v_edge = 1;
8111 }
8112 return is_active_v_edge;
8113}
8114
8115// Checks to see if a super block is at the edge of the active image.
8116// In most cases this is the "real" edge unless there are formatting
8117// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008118int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008119 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
8120 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008121}
8122
Urvang Joshib100db72016-10-12 16:28:56 -07008123#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07008124static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008125 MACROBLOCKD *const xd = &x->e_mbd;
8126 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8127 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
8128 const BLOCK_SIZE bsize = mbmi->sb_type;
8129 const int rows =
8130 (4 * num_4x4_blocks_high_lookup[bsize]) >> (xd->plane[1].subsampling_y);
8131 const int cols =
8132 (4 * num_4x4_blocks_wide_lookup[bsize]) >> (xd->plane[1].subsampling_x);
8133 int src_stride = x->plane[1].src.stride;
8134 const uint8_t *const src_u = x->plane[1].src.buf;
8135 const uint8_t *const src_v = x->plane[2].src.buf;
8136 float *const data = x->palette_buffer->kmeans_data_buf;
8137 float centroids[2 * PALETTE_MAX_SIZE];
8138 uint8_t *const color_map = xd->plane[1].color_index_map;
8139 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07008140#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008141 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
8142 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07008143#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008144 (void)cpi;
8145
8146 for (r = 0; r < rows; ++r) {
8147 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008148#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008149 if (cpi->common.use_highbitdepth) {
8150 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
8151 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
8152 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008153#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008154 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
8155 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07008156#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008157 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008158#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008159 }
8160 }
8161
8162 for (r = 1; r < 3; ++r) {
8163 for (c = 0; c < pmi->palette_size[1]; ++c) {
8164 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
8165 }
8166 }
8167
Yaowu Xuf883b422016-08-30 14:01:10 -07008168 av1_calc_indices(data, centroids, color_map, rows * cols,
8169 pmi->palette_size[1], 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008170}
Urvang Joshib100db72016-10-12 16:28:56 -07008171#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008172
hui su5db97432016-10-14 16:10:14 -07008173#if CONFIG_FILTER_INTRA
8174static void pick_filter_intra_interframe(
8175 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Urvang Joshi52648442016-10-13 17:27:51 -07008176 BLOCK_SIZE bsize, int *rate_uv_intra, int *rate_uv_tokenonly,
8177 int64_t *dist_uv, int *skip_uv, PREDICTION_MODE *mode_uv,
hui su5db97432016-10-14 16:10:14 -07008178 FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
8179#if CONFIG_EXT_INTRA
8180 int8_t *uv_angle_delta,
8181#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07008182#if CONFIG_PALETTE
8183 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
8184#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008185 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
8186 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
8187 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
8188#if CONFIG_SUPERTX
8189 int *returnrate_nocoef,
8190#endif // CONFIG_SUPERTX
8191 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07008192 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008193 MACROBLOCKD *const xd = &x->e_mbd;
8194 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008195#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008196 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008197#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008198 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
8199 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
8200 int dc_mode_index;
8201 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8202 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd, distortion_uv;
8203 TX_SIZE uv_tx;
8204
8205 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008206 if (av1_mode_order[i].mode == DC_PRED &&
8207 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008208 break;
8209 dc_mode_index = i;
8210 assert(i < MAX_MODES);
8211
8212 // TODO(huisu): use skip_mask for further speedup.
8213 (void)skip_mask;
8214 mbmi->mode = DC_PRED;
8215 mbmi->uv_mode = DC_PRED;
8216 mbmi->ref_frame[0] = INTRA_FRAME;
8217 mbmi->ref_frame[1] = NONE;
hui su5db97432016-10-14 16:10:14 -07008218 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8219 &skippable, bsize, intra_mode_cost[mbmi->mode],
8220 &this_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008221 return;
hui su5db97432016-10-14 16:10:14 -07008222 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008223 if (rate_y == INT_MAX) return;
8224
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008225 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
8226 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008227 if (rate_uv_intra[uv_tx] == INT_MAX) {
8228 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
8229 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
8230 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008231#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008232 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008233#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008234 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8235#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008236 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07008237#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008238 }
8239
8240 rate_uv = rate_uv_tokenonly[uv_tx];
8241 distortion_uv = dist_uv[uv_tx];
8242 skippable = skippable && skip_uv[uv_tx];
8243 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008244#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008245 if (cm->allow_screen_content_tools) {
8246 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8247 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8248 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8249 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8250 }
Urvang Joshib100db72016-10-12 16:28:56 -07008251#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008252#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008253 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07008254#endif // CONFIG_EXT_INTRA
8255 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8256 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8257 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8258 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8259 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008260 }
8261
8262 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8263 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008264#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008265 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07008266 rate2 += av1_cost_bit(
8267 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008268#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008269
8270 if (!xd->lossless[mbmi->segment_id]) {
8271 // super_block_yrd above includes the cost of the tx_size in the
8272 // tokenonly rate, but for intra blocks, tx_size is always coded
8273 // (prediction granularity), so we account for it in the full rate,
8274 // not the tokenonly rate.
clang-format67948d32016-09-07 22:40:40 -07008275 rate_y -= cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
Jingning Hanb0a71302016-10-25 16:28:49 -07008276 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008277 }
8278
hui su5db97432016-10-14 16:10:14 -07008279 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8280 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8281 rate2 += write_uniform_cost(
8282 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8283#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008284 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
8285 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
8286 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
8287 }
hui su5db97432016-10-14 16:10:14 -07008288#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008289 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008290 rate2 +=
8291 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8292 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8293 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8294 rate2 +=
8295 write_uniform_cost(FILTER_INTRA_MODES,
8296 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008297 }
8298 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07008299 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07008300#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008301 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008302 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008303 cpi, &xd->plane[0].dst, bsize, xd->bd);
8304 } else {
8305 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008306 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008307 }
8308#else
8309 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07008310 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
8311#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008312
8313 rate2 += ref_costs_single[INTRA_FRAME];
8314
8315 if (skippable) {
8316 rate2 -= (rate_y + rate_uv);
8317 rate_y = 0;
8318 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008319 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008320 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008321 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008322 }
8323 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008324
8325 if (this_rd < *best_intra_rd) {
8326 *best_intra_rd = this_rd;
8327 *best_intra_mode = mbmi->mode;
8328 }
8329 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008330 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008331
8332 if (this_rd < *best_rd) {
8333 *best_mode_index = dc_mode_index;
8334 mbmi->mv[0].as_int = 0;
8335 rd_cost->rate = rate2;
8336#if CONFIG_SUPERTX
8337 if (x->skip)
8338 *returnrate_nocoef = rate2;
8339 else
8340 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008341 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8342 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8343 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008344#endif // CONFIG_SUPERTX
8345 rd_cost->dist = distortion2;
8346 rd_cost->rdcost = this_rd;
8347 *best_rd = this_rd;
8348 *best_mbmode = *mbmi;
8349 *best_skip2 = 0;
8350 *best_mode_skippable = skippable;
8351 }
8352}
hui su5db97432016-10-14 16:10:14 -07008353#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008354
Yue Chencb60b182016-10-13 15:18:22 -07008355#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008356static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8357 const MACROBLOCKD *xd, int mi_row,
8358 int mi_col, const uint8_t *above,
8359 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008360 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008361#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008362
Urvang Joshi52648442016-10-13 17:27:51 -07008363void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008364 MACROBLOCK *x, int mi_row, int mi_col,
8365 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008366#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008367 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008368#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008369 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8370 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008371 const AV1_COMMON *const cm = &cpi->common;
8372 const RD_OPT *const rd_opt = &cpi->rd;
8373 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008374 MACROBLOCKD *const xd = &x->e_mbd;
8375 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008376#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008377 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008378#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008379 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8380 const struct segmentation *const seg = &cm->seg;
8381 PREDICTION_MODE this_mode;
8382 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8383 unsigned char segment_id = mbmi->segment_id;
8384 int comp_pred, i, k;
8385 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8386 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
8387#if CONFIG_EXT_INTER
8388 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
8389 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
8390 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8391#else
8392 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
8393#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07008394 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008395 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8396 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8397 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008398 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008399#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008400 AOM_LAST2_FLAG,
8401 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008402#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008403 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008404#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008405 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008406#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008407 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008408 };
8409 int64_t best_rd = best_rd_so_far;
8410 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8411 int64_t best_pred_diff[REFERENCE_MODES];
8412 int64_t best_pred_rd[REFERENCE_MODES];
8413 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008414#if CONFIG_REF_MV
8415 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8416 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8417#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008418 int best_mode_skippable = 0;
8419 int midx, best_mode_index = -1;
8420 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8421 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008422 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008423 int64_t best_intra_rd = INT64_MAX;
8424 unsigned int best_pred_sse = UINT_MAX;
8425 PREDICTION_MODE best_intra_mode = DC_PRED;
8426 int rate_uv_intra[TX_SIZES], rate_uv_tokenonly[TX_SIZES];
Urvang Joshi368fbc92016-10-17 16:31:34 -07008427 int64_t dist_uvs[TX_SIZES];
8428 int skip_uvs[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008429 PREDICTION_MODE mode_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008430#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008431 PALETTE_MODE_INFO pmi_uv[TX_SIZES];
Urvang Joshib100db72016-10-12 16:28:56 -07008432#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008433#if CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008434 int8_t uv_angle_delta[TX_SIZES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008435 int is_directional_mode, angle_stats_ready = 0;
8436 int rate_overhead, rate_dummy;
8437 uint8_t directional_mode_skip_mask[INTRA_MODES];
8438#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008439#if CONFIG_FILTER_INTRA
8440 int8_t dc_skipped = 1;
8441 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES];
8442#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008443 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008444 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8445 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8446 int best_skip2 = 0;
8447 uint8_t ref_frame_skip_mask[2] = { 0 };
8448#if CONFIG_EXT_INTER
8449 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8450 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8451 int64_t best_single_inter_rd = INT64_MAX;
8452#else
8453 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
8454#endif // CONFIG_EXT_INTER
8455 int mode_skip_start = sf->mode_skip_start + 1;
8456 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8457 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8458 int64_t mode_threshold[MAX_MODES];
8459 int *mode_map = tile_data->mode_map[bsize];
8460 const int mode_search_skip_flags = sf->mode_search_skip_flags;
8461 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
Yushin Cho77bba8d2016-11-04 16:36:56 -07008462#if CONFIG_PVQ
8463 od_rollback_buffer pre_buf;
8464#endif
8465
Urvang Joshib100db72016-10-12 16:28:56 -07008466#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467 const int rows = 4 * num_4x4_blocks_high_lookup[bsize];
8468 const int cols = 4 * num_4x4_blocks_wide_lookup[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008469#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8470#if CONFIG_PALETTE
8471 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008472 const MODE_INFO *above_mi = xd->above_mi;
8473 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008474#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008475#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008476#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008477 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8478 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8479#else
8480 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
8481 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008482#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008483 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
8484 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
8485 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
8486 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8487 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8488 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8489 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8490 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8491 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8492
Yaowu Xuf883b422016-08-30 14:01:10 -07008493#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008494 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8495 int len = sizeof(uint16_t);
8496 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
8497 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
8498 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
8499 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
8500 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
8501 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
8502 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008503#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008504 dst_buf1[0] = tmp_buf1;
8505 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
8506 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
8507 dst_buf2[0] = tmp_buf2;
8508 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
8509 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07008510#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008511 }
Yaowu Xuf883b422016-08-30 14:01:10 -07008512#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008513#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008514
Yaowu Xuf883b422016-08-30 14:01:10 -07008515 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008516
Urvang Joshib100db72016-10-12 16:28:56 -07008517#if CONFIG_PALETTE
8518 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008519 if (cm->allow_screen_content_tools) {
8520 if (above_mi)
8521 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8522 if (left_mi)
8523 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8524 }
Urvang Joshib100db72016-10-12 16:28:56 -07008525#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008526
8527#if CONFIG_EXT_INTRA
8528 memset(directional_mode_skip_mask, 0,
8529 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
8530#endif // CONFIG_EXT_INTRA
8531
8532 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8533 &comp_mode_p);
8534
8535 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
8536 for (i = 0; i < TX_SIZES; i++) rate_uv_intra[i] = INT_MAX;
8537 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8538 for (i = 0; i < MB_MODE_COUNT; ++i) {
8539 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
8540 single_inter_filter[i][k] = SWITCHABLE;
8541 single_skippable[i][k] = 0;
8542 }
8543 }
8544
8545 rd_cost->rate = INT_MAX;
8546#if CONFIG_SUPERTX
8547 *returnrate_nocoef = INT_MAX;
8548#endif // CONFIG_SUPERTX
8549
8550 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8551 x->pred_mv_sad[ref_frame] = INT_MAX;
8552 x->mbmi_ext->mode_context[ref_frame] = 0;
8553#if CONFIG_REF_MV && CONFIG_EXT_INTER
8554 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
8555#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8556 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8557 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8558 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8559 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8560 }
8561 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008562#if CONFIG_GLOBAL_MOTION
8563 frame_mv[ZEROMV][ref_frame].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07008564 gm_get_motion_vector(&cm->global_motion[ref_frame]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008565#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008566 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008567#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008568#if CONFIG_EXT_INTER
8569 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
8570 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
8571 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
8572#endif // CONFIG_EXT_INTER
8573 }
8574
8575#if CONFIG_REF_MV
8576 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8577 MODE_INFO *const mi = xd->mi[0];
8578 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8579 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008580 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8581 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008582#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008583 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008584#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008585 candidates, mi_row, mi_col, NULL, NULL,
8586 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008587 }
8588#endif // CONFIG_REF_MV
8589
Yue Chencb60b182016-10-13 15:18:22 -07008590#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008591 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
8592 dst_width1, dst_height1, dst_stride1);
8593 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
8594 dst_width2, dst_height2, dst_stride2);
8595 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07008596 x->mask_buf = mask2d_buf;
8597 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008598 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07008599 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07008600#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008601
8602 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8603 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8604// Skip checking missing references in both single and compound reference
8605// modes. Note that a mode will be skipped iff both reference frames
8606// are masked out.
8607#if CONFIG_EXT_REFS
8608 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8609 ref_frame_skip_mask[0] |= (1 << ref_frame);
8610 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8611 } else {
8612#endif // CONFIG_EXT_REFS
8613 ref_frame_skip_mask[0] |= (1 << ref_frame);
8614 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8615#if CONFIG_EXT_REFS
8616 }
8617#endif // CONFIG_EXT_REFS
8618 } else {
8619 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8620 // Skip fixed mv modes for poor references
8621 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8622 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8623 break;
8624 }
8625 }
8626 }
8627 // If the segment reference frame feature is enabled....
8628 // then do nothing if the current ref frame is not allowed..
8629 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8630 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8631 ref_frame_skip_mask[0] |= (1 << ref_frame);
8632 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8633 }
8634 }
8635
8636 // Disable this drop out case if the ref frame
8637 // segment level feature is enabled for this segment. This is to
8638 // prevent the possibility that we end up unable to pick any mode.
8639 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8640 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8641 // unless ARNR filtering is enabled in which case we want
8642 // an unfiltered alternative. We allow near/nearest as well
8643 // because they may result in zero-zero MVs but be cheaper.
8644 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008645 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008646 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8647#if CONFIG_EXT_REFS
8648 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8649 (1 << BWDREF_FRAME) |
8650#endif // CONFIG_EXT_REFS
8651 (1 << GOLDEN_FRAME);
8652 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8653 // TODO(zoeliu): To further explore whether following needs to be done for
8654 // BWDREF_FRAME as well.
8655 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008656#if CONFIG_GLOBAL_MOTION
8657 zeromv.as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -07008658 gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008659#else
8660 zeromv.as_int = 0;
8661#endif // CONFIG_GLOBAL_MOTION
8662 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008663 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008664 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008665 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8666#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008667 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008668 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008669 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008670 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008671 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008672 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008673 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008674 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8675#endif // CONFIG_EXT_INTER
8676 }
8677 }
8678
8679 if (cpi->rc.is_src_frame_alt_ref) {
8680 if (sf->alt_ref_search_fp) {
8681 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8682 mode_skip_mask[ALTREF_FRAME] = 0;
8683 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8684 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8685 }
8686 }
8687
8688 if (sf->alt_ref_search_fp)
8689 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8690 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8691 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8692
8693 if (sf->adaptive_mode_search) {
8694 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8695 cpi->rc.frames_since_golden >= 3)
8696 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
8697 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8698 }
8699
8700 if (bsize > sf->max_intra_bsize) {
8701 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8702 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8703 }
8704
8705 mode_skip_mask[INTRA_FRAME] |=
8706 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8707
8708 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8709 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8710 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8711
8712 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8713 while (midx > 4) {
8714 uint8_t end_pos = 0;
8715 for (i = 5; i < midx; ++i) {
8716 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8717 uint8_t tmp = mode_map[i];
8718 mode_map[i] = mode_map[i - 1];
8719 mode_map[i - 1] = tmp;
8720 end_pos = i;
8721 }
8722 }
8723 midx = end_pos;
8724 }
8725
8726 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
8727 x->use_default_intra_tx_type = 1;
8728 else
8729 x->use_default_intra_tx_type = 0;
8730
8731 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
8732 x->use_default_inter_tx_type = 1;
8733 else
8734 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07008735#if CONFIG_PVQ
8736 od_encode_checkpoint(&x->daala_enc, &pre_buf);
8737#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008738#if CONFIG_EXT_INTER
8739 for (i = 0; i < MB_MODE_COUNT; ++i)
8740 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
8741 modelled_rd[i][ref_frame] = INT64_MAX;
8742#endif // CONFIG_EXT_INTER
8743
8744 for (midx = 0; midx < MAX_MODES; ++midx) {
8745 int mode_index;
8746 int mode_excluded = 0;
8747 int64_t this_rd = INT64_MAX;
8748 int disable_skip = 0;
8749 int compmode_cost = 0;
8750#if CONFIG_EXT_INTER
8751 int compmode_interintra_cost = 0;
8752 int compmode_wedge_cost = 0;
8753#endif // CONFIG_EXT_INTER
8754 int rate2 = 0, rate_y = 0, rate_uv = 0;
8755 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
8756 int skippable = 0;
8757 int this_skip2 = 0;
8758 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759#if CONFIG_REF_MV
8760 uint8_t ref_frame_type;
8761#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07008762#if CONFIG_PVQ
8763 od_encode_rollback(&x->daala_enc, &pre_buf);
8764#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008765 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07008766 this_mode = av1_mode_order[mode_index].mode;
8767 ref_frame = av1_mode_order[mode_index].ref_frame[0];
8768 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008769#if CONFIG_REF_MV
8770 mbmi->ref_mv_idx = 0;
8771#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008772
8773#if CONFIG_EXT_INTER
8774 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
8775 // Mode must by compatible
8776 assert(is_interintra_allowed_mode(this_mode));
8777
8778 if (!is_interintra_allowed_bsize(bsize)) continue;
8779 }
8780
8781 if (is_inter_compound_mode(this_mode)) {
8782 frame_mv[this_mode][ref_frame].as_int =
8783 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
8784 frame_mv[this_mode][second_ref_frame].as_int =
8785 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
8786 }
8787#endif // CONFIG_EXT_INTER
8788
8789 // Look at the reference frame of the best mode so far and set the
8790 // skip mask to look at a subset of the remaining modes.
8791 if (midx == mode_skip_start && best_mode_index >= 0) {
8792 switch (best_mbmode.ref_frame[0]) {
8793 case INTRA_FRAME: break;
8794 case LAST_FRAME:
8795 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
8796 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8797 break;
8798#if CONFIG_EXT_REFS
8799 case LAST2_FRAME:
8800 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
8801 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8802 break;
8803 case LAST3_FRAME:
8804 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
8805 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8806 break;
8807#endif // CONFIG_EXT_REFS
8808 case GOLDEN_FRAME:
8809 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
8810 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8811 break;
8812#if CONFIG_EXT_REFS
8813 case BWDREF_FRAME:
8814 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
8815 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8816 break;
8817#endif // CONFIG_EXT_REFS
8818 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
8819#if CONFIG_EXT_REFS
8820 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8821#endif // CONFIG_EXT_REFS
8822 break;
8823 case NONE:
8824 case TOTAL_REFS_PER_FRAME:
8825 assert(0 && "Invalid Reference frame");
8826 break;
8827 }
8828 }
8829
8830 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07008831 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07008832 continue;
8833
8834 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
8835
8836 // Test best rd so far against threshold for trying this mode.
8837 if (best_mode_skippable && sf->schedule_mode_search)
8838 mode_threshold[mode_index] <<= 1;
8839
8840 if (best_rd < mode_threshold[mode_index]) continue;
8841
8842 comp_pred = second_ref_frame > INTRA_FRAME;
8843 if (comp_pred) {
8844 if (!cpi->allow_comp_inter_inter) continue;
8845
8846 // Skip compound inter modes if ARF is not available.
8847 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
8848
8849 // Do not allow compound prediction if the segment level reference frame
8850 // feature is in use as in this case there can only be one reference.
8851 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
8852
8853 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
8854 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
8855 continue;
8856
8857 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
8858 } else {
8859 if (ref_frame != INTRA_FRAME)
8860 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
8861 }
8862
8863 if (ref_frame == INTRA_FRAME) {
8864 if (sf->adaptive_mode_search)
8865 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
8866 continue;
8867
8868 if (this_mode != DC_PRED) {
8869 // Disable intra modes other than DC_PRED for blocks with low variance
8870 // Threshold for intra skipping based on source variance
8871 // TODO(debargha): Specialize the threshold for super block sizes
8872 const unsigned int skip_intra_var_thresh = 64;
8873 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
8874 x->source_variance < skip_intra_var_thresh)
8875 continue;
8876 // Only search the oblique modes if the best so far is
8877 // one of the neighboring directional modes
8878 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
8879 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
8880 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
8881 continue;
8882 }
8883 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
8884 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
8885 }
8886 }
Sarah Parkere5299862016-08-16 14:57:37 -07008887#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00008888 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07008889 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00008890 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008891#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008892 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07008893#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008894 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
8895 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
8896#if CONFIG_REF_MV && CONFIG_EXT_INTER
8897 mbmi_ext->compound_mode_context,
8898#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8899 frame_mv, this_mode, ref_frames, bsize, -1))
8900 continue;
8901 }
8902
8903 mbmi->mode = this_mode;
8904 mbmi->uv_mode = DC_PRED;
8905 mbmi->ref_frame[0] = ref_frame;
8906 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07008907#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008908 pmi->palette_size[0] = 0;
8909 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07008910#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008911#if CONFIG_FILTER_INTRA
8912 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
8913 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
8914#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008915 // Evaluate all sub-pel filters irrespective of whether we can use
8916 // them for this frame.
8917#if CONFIG_DUAL_FILTER
8918 for (i = 0; i < 4; ++i) {
8919 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
8920 ? EIGHTTAP_REGULAR
8921 : cm->interp_filter;
8922 }
8923#else
8924 mbmi->interp_filter =
8925 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
8926#endif
8927 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008928 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008929
8930 x->skip = 0;
8931 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
8932
8933 // Select prediction reference frames.
8934 for (i = 0; i < MAX_MB_PLANE; i++) {
8935 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
8936 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
8937 }
8938
8939#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07008940 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008941#endif // CONFIG_EXT_INTER
8942
8943 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008944 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008945 TX_SIZE uv_tx;
8946 struct macroblockd_plane *const pd = &xd->plane[1];
8947#if CONFIG_EXT_INTRA
8948 is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
8949 if (is_directional_mode) {
8950 if (!angle_stats_ready) {
8951 const int src_stride = x->plane[0].src.stride;
8952 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07008953#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008954 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8955 highbd_angle_estimation(src, src_stride, rows, cols,
8956 directional_mode_skip_mask);
8957 else
8958#endif
8959 angle_estimation(src, src_stride, rows, cols,
8960 directional_mode_skip_mask);
8961 angle_stats_ready = 1;
8962 }
8963 if (directional_mode_skip_mask[mbmi->mode]) continue;
8964 rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
8965 intra_mode_cost[mbmi->mode];
8966 rate_y = INT_MAX;
8967 this_rd =
8968 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8969 &skippable, bsize, rate_overhead, best_rd);
8970 } else {
8971 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008972 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
8973 rate_y = rd_stats_y.rate;
8974 distortion_y = rd_stats_y.dist;
8975 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008976 }
8977#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008978 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
8979 rate_y = rd_stats_y.rate;
8980 distortion_y = rd_stats_y.dist;
8981 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008982#endif // CONFIG_EXT_INTRA
8983
8984 if (rate_y == INT_MAX) continue;
8985
hui su5db97432016-10-14 16:10:14 -07008986#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008987 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07008988#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008989
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008990 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
8991 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008992 if (rate_uv_intra[uv_tx] == INT_MAX) {
8993 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07008994 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
8995 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008996#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008997 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008998#endif // CONFIG_PALETTE
8999
Yaowu Xuc27fc142016-08-22 16:08:15 -07009000#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009001 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9002#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009003#if CONFIG_FILTER_INTRA
9004 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9005#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009006 }
9007
9008 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07009009 distortion_uv = dist_uvs[uv_tx];
9010 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009011 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009012#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009013 if (cm->allow_screen_content_tools) {
9014 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9015 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9016 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9017 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9018 }
Urvang Joshib100db72016-10-12 16:28:56 -07009019#endif // CONFIG_PALETTE
9020
Yaowu Xuc27fc142016-08-22 16:08:15 -07009021#if CONFIG_EXT_INTRA
9022 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009023#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009024#if CONFIG_FILTER_INTRA
9025 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9026 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9027 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9028 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9029 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9030 }
9031#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009032
9033 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9034 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009035#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009036 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009037 rate2 += av1_cost_bit(
9038 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009039#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009040
9041 if (!xd->lossless[mbmi->segment_id]) {
9042 // super_block_yrd above includes the cost of the tx_size in the
9043 // tokenonly rate, but for intra blocks, tx_size is always coded
9044 // (prediction granularity), so we account for it in the full rate,
9045 // not the tokenonly rate.
Jingning Hanb0a71302016-10-25 16:28:49 -07009046 rate_y -=
9047 cpi->tx_size_cost[max_tx_size - TX_8X8][get_tx_size_context(xd)]
9048 [tx_size_to_depth(mbmi->tx_size)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009049 }
9050#if CONFIG_EXT_INTRA
9051 if (is_directional_mode) {
9052 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07009053 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009054 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9055 MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
9056 p_angle =
9057 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07009058 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009059 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
9060 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009061 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
9062 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
9063 MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
9064 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009065#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009066#if CONFIG_FILTER_INTRA
9067 if (mbmi->mode == DC_PRED) {
9068 rate2 +=
9069 av1_cost_bit(cm->fc->filter_intra_probs[0],
9070 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9071 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
9072 rate2 += write_uniform_cost(
9073 FILTER_INTRA_MODES,
9074 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9075 }
9076 }
9077 if (mbmi->uv_mode == DC_PRED) {
9078 rate2 +=
9079 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9080 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9081 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9082 rate2 += write_uniform_cost(
9083 FILTER_INTRA_MODES,
9084 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
9085 }
9086#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009087 if (this_mode != DC_PRED && this_mode != TM_PRED)
9088 rate2 += intra_cost_penalty;
9089 distortion2 = distortion_y + distortion_uv;
Angie Chiangff6d8902016-10-21 11:02:09 -07009090 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07009091#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009092 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009093 x->recon_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009094 cpi, &xd->plane[0].dst, bsize, xd->bd);
9095 } else {
9096 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009097 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009098 }
9099#else
9100 x->recon_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07009101 av1_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
9102#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009103 } else {
9104#if CONFIG_REF_MV
9105 int_mv backup_ref_mv[2];
9106
9107 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
9108 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
9109#endif
9110#if CONFIG_EXT_INTER
9111 if (second_ref_frame == INTRA_FRAME) {
9112 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009113 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07009114// TODO(debargha|geza.lore):
9115// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07009116#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009117 mbmi->angle_delta[0] = 0;
9118 mbmi->angle_delta[1] = 0;
9119 mbmi->intra_filter = INTRA_FILTER_LINEAR;
9120#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009121#if CONFIG_FILTER_INTRA
9122 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9123 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9124#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009125 }
9126#endif // CONFIG_EXT_INTER
9127#if CONFIG_REF_MV
9128 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009129 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009130
9131 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
9132 int ref;
9133 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9134 int_mv this_mv =
9135 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
9136 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
9137 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9138 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9139 }
9140 }
9141#endif
Angie Chiang76159122016-11-09 12:13:22 -08009142 {
9143 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
9144 av1_init_rd_stats(&rd_stats);
9145 rd_stats.rate = rate2;
9146 this_rd = handle_inter_mode(
9147 cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &disable_skip,
9148 frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009149#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009150 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009151#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009152#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009153 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
9154 &compmode_wedge_cost, modelled_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009155#else
Angie Chiang76159122016-11-09 12:13:22 -08009156 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009157#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009158 single_inter_filter, single_skippable, best_rd);
9159
9160 rate2 = rd_stats.rate;
9161 skippable = rd_stats.skip;
9162 distortion2 = rd_stats.dist;
9163 total_sse = rd_stats.sse;
9164 rate_y = rd_stats_y.rate;
9165 rate_uv = rd_stats_uv.rate;
9166 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009167
9168#if CONFIG_REF_MV
9169 // TODO(jingning): This needs some refactoring to improve code quality
9170 // and reduce redundant steps.
9171 if ((mbmi->mode == NEARMV &&
9172 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9173 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
9174 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
9175 MB_MODE_INFO backup_mbmi = *mbmi;
9176 int backup_skip = x->skip;
9177 int64_t tmp_ref_rd = this_rd;
9178 int ref_idx;
9179
9180 // TODO(jingning): This should be deprecated shortly.
9181 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
9182 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07009183 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009184
9185 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009186 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009187 // Dummy
9188 int_mv backup_fmv[2];
9189 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
9190 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
9191
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07009192 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009193
9194 if (this_rd < INT64_MAX) {
9195 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9196 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
9197 tmp_ref_rd =
9198 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009199 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07009200 distortion2);
9201 else
9202 tmp_ref_rd =
9203 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009204 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07009205 rate_y - rate_uv,
9206 total_sse);
9207 }
9208#if CONFIG_VAR_TX
9209 for (i = 0; i < MAX_MB_PLANE; ++i)
9210 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9211 sizeof(uint8_t) * ctx->num_4x4_blk);
9212#endif
9213
9214 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
9215 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009216 int dummy_disable_skip = 0;
9217 int ref;
9218 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009219 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009220
9221 mbmi->ref_mv_idx = 1 + ref_idx;
9222
9223 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9224 int_mv this_mv =
9225 (ref == 0)
9226 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9227 .this_mv
9228 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9229 .comp_mv;
9230 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
9231 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9232 }
9233
9234 cur_mv =
9235 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
9236 .this_mv;
9237 clamp_mv2(&cur_mv.as_mv, xd);
9238
9239 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format67948d32016-09-07 22:40:40 -07009240 int dummy_single_skippable[MB_MODE_COUNT]
9241 [TOTAL_REFS_PER_FRAME] = { { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009242#if CONFIG_EXT_INTER
9243 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
9244 { { 0 } } };
9245 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
9246 { 0 } };
9247 int dummy_compmode_interintra_cost = 0;
9248 int dummy_compmode_wedge_cost = 0;
9249#else
9250 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9251#endif
9252
9253 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009254 av1_init_rd_stats(&tmp_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009255 tmp_alt_rd = handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08009256 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
9257 &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07009258#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07009259 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -07009260#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009261#if CONFIG_EXT_INTER
9262 dummy_single_newmvs, dummy_single_newmvs_rate,
9263 &dummy_compmode_interintra_cost, &dummy_compmode_wedge_cost,
9264 NULL,
9265#else
9266 dummy_single_newmv,
9267#endif
Angie Chiang76159122016-11-09 12:13:22 -08009268 single_inter_filter, dummy_single_skippable, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009269 }
9270
9271 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
9272 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009273 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9274 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009275 tmp_rd_stats.rate +=
9276 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
9277 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009278 }
9279
9280 if (mbmi_ext->ref_mv_count[ref_frame_type] >
9281 mbmi->ref_mv_idx + idx_offset + 1 &&
9282 ref_idx < ref_set - 1) {
9283 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009284 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9285 mbmi->ref_mv_idx + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009286 tmp_rd_stats.rate += cpi->drl_mode_cost0[drl1_ctx][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009287 }
9288
9289 if (tmp_alt_rd < INT64_MAX) {
Yue Chencb60b182016-10-13 15:18:22 -07009290#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -08009291 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
9292 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009293#else
Angie Chiang76159122016-11-09 12:13:22 -08009294 if (RDCOST(x->rdmult, x->rddiv,
9295 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
9296 tmp_rd_stats.dist) <
9297 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009298 tmp_alt_rd =
9299 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009300 tmp_rd_stats.rate +
9301 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9302 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009303 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009304 tmp_alt_rd =
9305 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009306 tmp_rd_stats.rate +
9307 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9308 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
9309 tmp_rd_stats.sse);
Yue Chencb60b182016-10-13 15:18:22 -07009310#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009311 }
9312
9313 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -08009314 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009315 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -08009316 distortion2 = tmp_rd_stats.dist;
9317 skippable = tmp_rd_stats.skip;
9318 rate_y = tmp_rd_stats_y.rate;
9319 rate_uv = tmp_rd_stats_uv.rate;
9320 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009321 this_rd = tmp_alt_rd;
9322 tmp_ref_rd = tmp_alt_rd;
9323 backup_mbmi = *mbmi;
9324 backup_skip = x->skip;
9325#if CONFIG_VAR_TX
9326 for (i = 0; i < MAX_MB_PLANE; ++i)
9327 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9328 sizeof(uint8_t) * ctx->num_4x4_blk);
9329#endif
9330 } else {
9331 *mbmi = backup_mbmi;
9332 x->skip = backup_skip;
9333 }
9334 }
9335
9336 frame_mv[NEARMV][ref_frame] = backup_mv;
9337 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9338 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9339#if CONFIG_VAR_TX
9340 for (i = 0; i < MAX_MB_PLANE; ++i)
9341 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9342 sizeof(uint8_t) * ctx->num_4x4_blk);
9343#endif
9344 }
9345 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9346 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
9347#endif // CONFIG_REF_MV
9348
9349 if (this_rd == INT64_MAX) continue;
9350
Yaowu Xuf883b422016-08-30 14:01:10 -07009351 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009352
9353 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9354 }
9355
9356#if CONFIG_EXT_INTER
9357 rate2 += compmode_interintra_cost;
9358 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -07009359#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9360 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
9361#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009362 rate2 += compmode_wedge_cost;
9363#endif // CONFIG_EXT_INTER
9364
9365 // Estimate the reference frame signaling cost and add it
9366 // to the rolling cost variable.
9367 if (comp_pred) {
9368 rate2 += ref_costs_comp[ref_frame];
9369#if CONFIG_EXT_REFS
9370 rate2 += ref_costs_comp[second_ref_frame];
9371#endif // CONFIG_EXT_REFS
9372 } else {
9373 rate2 += ref_costs_single[ref_frame];
9374 }
9375
Yue Chencb60b182016-10-13 15:18:22 -07009376#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009377 if (ref_frame == INTRA_FRAME) {
9378#else
9379 if (!disable_skip) {
Yue Chencb60b182016-10-13 15:18:22 -07009380#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009381 if (skippable) {
9382 // Back out the coefficient coding costs
9383 rate2 -= (rate_y + rate_uv);
9384 rate_y = 0;
9385 rate_uv = 0;
9386 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009387 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009388 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009389#if CONFIG_REF_MV
9390 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9391 distortion2) <
9392 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
9393#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009394 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9395 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009396#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009397 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009398 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009399 } else {
9400 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009401 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009402 distortion2 = total_sse;
9403 assert(total_sse >= 0);
9404 rate2 -= (rate_y + rate_uv);
9405 this_skip2 = 1;
9406 rate_y = 0;
9407 rate_uv = 0;
9408 }
9409 } else {
9410 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009411 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009412 }
9413
9414 // Calculate the final RD estimate for this mode.
9415 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chencb60b182016-10-13 15:18:22 -07009416#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009417 } else {
9418 this_skip2 = mbmi->skip;
9419 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9420 if (this_skip2) {
9421 rate_y = 0;
9422 rate_uv = 0;
9423 }
Yue Chencb60b182016-10-13 15:18:22 -07009424#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009425 }
9426
Yaowu Xuc27fc142016-08-22 16:08:15 -07009427 if (ref_frame == INTRA_FRAME) {
9428 // Keep record of best intra rd
9429 if (this_rd < best_intra_rd) {
9430 best_intra_rd = this_rd;
9431 best_intra_mode = mbmi->mode;
9432 }
9433#if CONFIG_EXT_INTER
9434 } else if (second_ref_frame == NONE) {
9435 if (this_rd < best_single_inter_rd) {
9436 best_single_inter_rd = this_rd;
9437 best_single_inter_ref = mbmi->ref_frame[0];
9438 }
9439#endif // CONFIG_EXT_INTER
9440 }
9441
9442 if (!disable_skip && ref_frame == INTRA_FRAME) {
9443 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009444 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009445 }
9446
9447 // Did this mode help.. i.e. is it the new best mode
9448 if (this_rd < best_rd || x->skip) {
9449 if (!mode_excluded) {
9450 // Note index of best mode so far
9451 best_mode_index = mode_index;
9452
9453 if (ref_frame == INTRA_FRAME) {
9454 /* required for left and above block mv */
9455 mbmi->mv[0].as_int = 0;
9456 } else {
9457 best_pred_sse = x->pred_sse[ref_frame];
9458 }
9459
9460 rd_cost->rate = rate2;
9461#if CONFIG_SUPERTX
9462 if (x->skip)
9463 *returnrate_nocoef = rate2;
9464 else
9465 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009466 *returnrate_nocoef -= av1_cost_bit(
9467 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9468 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9469 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009470#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
9471 if (is_inter_block(mbmi) && is_motion_variation_allowed(mbmi))
9472 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
9473#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009474#endif // CONFIG_SUPERTX
9475 rd_cost->dist = distortion2;
9476 rd_cost->rdcost = this_rd;
9477 best_rd = this_rd;
9478 best_mbmode = *mbmi;
9479 best_skip2 = this_skip2;
9480 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009481 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9482 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009483 best_rate_uv = rate_uv;
9484
9485#if CONFIG_VAR_TX
9486 for (i = 0; i < MAX_MB_PLANE; ++i)
9487 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9488 sizeof(uint8_t) * ctx->num_4x4_blk);
9489#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009490 }
9491 }
9492
9493 /* keep record of best compound/single-only prediction */
9494 if (!disable_skip && ref_frame != INTRA_FRAME) {
9495 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9496
9497 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9498 single_rate = rate2 - compmode_cost;
9499 hybrid_rate = rate2;
9500 } else {
9501 single_rate = rate2;
9502 hybrid_rate = rate2 + compmode_cost;
9503 }
9504
9505 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9506 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9507
9508 if (!comp_pred) {
9509 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9510 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9511 } else {
9512 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9513 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9514 }
9515 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9516 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9517 }
9518
Yaowu Xuc27fc142016-08-22 16:08:15 -07009519 if (x->skip && !comp_pred) break;
9520 }
9521
9522 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9523 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9524 is_inter_mode(best_mbmode.mode)) ||
9525 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9526 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009527 int skip_blk = 0;
9528 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009529
9530 x->use_default_inter_tx_type = 0;
9531 x->use_default_intra_tx_type = 0;
9532
9533 *mbmi = best_mbmode;
9534
9535 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9536
9537 // Select prediction reference frames.
9538 for (i = 0; i < MAX_MB_PLANE; i++) {
9539 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9540 if (has_second_ref(mbmi))
9541 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9542 }
9543
9544 if (is_inter_mode(mbmi->mode)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009545 av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
Yue Chencb60b182016-10-13 15:18:22 -07009546#if CONFIG_MOTION_VAR
9547 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -07009548 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
9549 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -07009550#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009551 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009552#if CONFIG_VAR_TX
9553 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07009554 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009555 } else {
9556 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009557 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009558 for (idy = 0; idy < xd->n8_h; ++idy)
9559 for (idx = 0; idx < xd->n8_w; ++idx)
9560 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009561 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009562 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9563 }
9564
Angie Chiangb5dda482016-11-02 16:19:58 -07009565 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009566#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009567 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009568 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009569#endif // CONFIG_VAR_TX
9570 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009571 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009572 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009573 }
9574
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009575 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9576 (rd_stats_y.dist + rd_stats_uv.dist)) >
9577 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009578 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009579 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9580 rd_stats_uv.rate = 0;
9581 rd_stats_y.dist = rd_stats_y.sse;
9582 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009583 } else {
9584 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009585 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009586 }
9587
9588 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009589 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9590 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009591#if CONFIG_VAR_TX
9592 int idx, idy;
9593#endif
9594 best_mbmode.tx_type = mbmi->tx_type;
9595 best_mbmode.tx_size = mbmi->tx_size;
9596#if CONFIG_VAR_TX
9597 for (idy = 0; idy < xd->n8_h; ++idy)
9598 for (idx = 0; idx < xd->n8_w; ++idx)
9599 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9600
9601 for (i = 0; i < MAX_MB_PLANE; ++i)
9602 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9603 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07009604
9605 best_mbmode.min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009606#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009607 rd_cost->rate +=
9608 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
9609 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009610 rd_cost->rdcost =
9611 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9612 best_skip2 = skip_blk;
9613 }
9614 }
9615
Urvang Joshib100db72016-10-12 16:28:56 -07009616#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009617 // Only try palette mode when the best mode so far is an intra mode.
9618 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
9619 PREDICTION_MODE mode_selected;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009620 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009621#if CONFIG_SUPERTX
9622 int best_rate_nocoef;
9623#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009624 int64_t distortion2 = 0, dummy_rd = best_rd, this_rd;
Urvang Joshi626591d2016-10-24 14:13:55 -07009625 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009626 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009627 TX_SIZE best_tx_size, uv_tx;
9628 TX_TYPE best_tx_type;
9629 PALETTE_MODE_INFO palette_mode_info;
9630 uint8_t *const best_palette_color_map =
9631 x->palette_buffer->best_palette_color_map;
9632 uint8_t *const color_map = xd->plane[0].color_index_map;
9633
9634 mbmi->mode = DC_PRED;
9635 mbmi->uv_mode = DC_PRED;
9636 mbmi->ref_frame[0] = INTRA_FRAME;
9637 mbmi->ref_frame[1] = NONE;
9638 palette_mode_info.palette_size[0] = 0;
Urvang Joshi626591d2016-10-24 14:13:55 -07009639 rate_overhead_palette = rd_pick_palette_intra_sby(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009640 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
9641 &palette_mode_info, best_palette_color_map, &best_tx_size,
9642 &best_tx_type, &mode_selected, &dummy_rd);
9643 if (palette_mode_info.palette_size[0] == 0) goto PALETTE_EXIT;
9644
9645 pmi->palette_size[0] = palette_mode_info.palette_size[0];
9646 if (palette_mode_info.palette_size[0] > 0) {
9647 memcpy(pmi->palette_colors, palette_mode_info.palette_colors,
9648 PALETTE_MAX_SIZE * sizeof(palette_mode_info.palette_colors[0]));
9649 memcpy(color_map, best_palette_color_map,
9650 rows * cols * sizeof(best_palette_color_map[0]));
9651 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009652 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
9653 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009654 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9655 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009656 if (rate_uv_intra[uv_tx] == INT_MAX) {
9657 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009658 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9659 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009660 pmi_uv[uv_tx] = *pmi;
9661#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009662 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9663#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009664#if CONFIG_FILTER_INTRA
9665 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9666#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009667 }
9668 mbmi->uv_mode = mode_uv[uv_tx];
9669 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9670 if (pmi->palette_size[1] > 0)
9671 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9672 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9673 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9674#if CONFIG_EXT_INTRA
9675 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009676#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009677#if CONFIG_FILTER_INTRA
9678 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9679 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9680 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9681 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9682 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9683 }
9684#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009685 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
9686 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
9687 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009688 rate2 += ref_costs_single[INTRA_FRAME];
9689
9690 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009691 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009692#if CONFIG_SUPERTX
9693 best_rate_nocoef = rate2;
9694#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009695 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009696 } else {
9697#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009698 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009699#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07009700 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701 }
9702 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9703 if (this_rd < best_rd) {
9704 best_mode_index = 3;
9705 mbmi->mv[0].as_int = 0;
9706 rd_cost->rate = rate2;
9707#if CONFIG_SUPERTX
9708 *returnrate_nocoef = best_rate_nocoef;
9709#endif
9710 rd_cost->dist = distortion2;
9711 rd_cost->rdcost = this_rd;
9712 best_rd = this_rd;
9713 best_mbmode = *mbmi;
9714 best_skip2 = 0;
9715 best_mode_skippable = skippable;
9716 }
9717 }
9718PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -07009719#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009720
hui su5db97432016-10-14 16:10:14 -07009721#if CONFIG_FILTER_INTRA
9722 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -07009723 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -07009724 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -07009725#if CONFIG_PALETTE
9726 mbmi->palette_mode_info.palette_size[0] == 0 &&
9727#endif // CONFIG_PALETTE
9728 !dc_skipped && best_mode_index >= 0 &&
9729 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -07009730 pick_filter_intra_interframe(
Urvang Joshi368fbc92016-10-17 16:31:34 -07009731 cpi, x, ctx, bsize, rate_uv_intra, rate_uv_tokenonly, dist_uvs,
hui su5db97432016-10-14 16:10:14 -07009732 skip_uvs, mode_uv, filter_intra_mode_info_uv,
9733#if CONFIG_EXT_INTRA
9734 uv_angle_delta,
9735#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009736#if CONFIG_PALETTE
9737 pmi_uv, palette_ctx,
9738#endif // CONFIG_PALETTE
9739 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009740 &best_mode_index, &best_skip2, &best_mode_skippable,
9741#if CONFIG_SUPERTX
9742 returnrate_nocoef,
9743#endif // CONFIG_SUPERTX
9744 best_pred_rd, &best_mbmode, rd_cost);
9745 }
hui su5db97432016-10-14 16:10:14 -07009746#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009747
9748 // The inter modes' rate costs are not calculated precisely in some cases.
9749 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
9750 // ZEROMV. Here, checks are added for those cases, and the mode decisions
9751 // are corrected.
9752 if (best_mbmode.mode == NEWMV
9753#if CONFIG_EXT_INTER
9754 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
9755#endif // CONFIG_EXT_INTER
9756 ) {
9757 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
9758 best_mbmode.ref_frame[1] };
9759 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -07009760 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009761#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07009762 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -07009763#endif // CONFIG_REF_MV
9764#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee5f305852016-11-03 15:47:21 -07009765 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]]).as_int;
Sarah Parker70c4fab2016-11-04 12:35:57 -07009766 zeromv[1].as_int =
9767 comp_pred_mode
Debargha Mukherjee5f305852016-11-03 15:47:21 -07009768 ? gm_get_motion_vector(&cm->global_motion[refs[1]]).as_int
Sarah Parker70c4fab2016-11-04 12:35:57 -07009769 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009770#else
9771 zeromv[0].as_int = 0;
9772 zeromv[1].as_int = 0;
9773#endif // CONFIG_GLOBAL_MOTION
9774#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009775 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009776 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009777 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009778 : INT_MAX;
9779
9780 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9781 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9782 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
9783 best_mbmode.mode = NEARMV;
9784 best_mbmode.ref_mv_idx = i;
9785 }
9786 }
9787
9788 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
9789 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009790 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009791 best_mbmode.mode = ZEROMV;
9792 } else {
9793 int_mv nearestmv[2];
9794 int_mv nearmv[2];
9795
9796#if CONFIG_EXT_INTER
9797 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
9798 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
9799 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
9800 } else {
9801 nearmv[0] = frame_mv[NEARMV][refs[0]];
9802 nearmv[1] = frame_mv[NEARMV][refs[1]];
9803 }
9804#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009805 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -07009806 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009807 : INT_MAX;
9808
9809 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
9810 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
9811 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
9812
9813 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9814 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
9815 best_mbmode.mode = NEARMV;
9816 best_mbmode.ref_mv_idx = i;
9817 }
9818 }
9819#endif
9820 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
9821 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
9822 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
9823 } else {
9824 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
9825 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
9826 }
9827
9828 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9829 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9830#if CONFIG_EXT_INTER
9831 best_mbmode.mode = NEAREST_NEARESTMV;
9832 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
9833 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9834 best_mbmode.mode = NEAREST_NEARMV;
9835 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9836 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
9837 best_mbmode.mode = NEAR_NEARESTMV;
9838 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
9839 nearmv[1].as_int == best_mbmode.mv[1].as_int)
9840 best_mbmode.mode = NEAR_NEARMV;
9841 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9842 best_mbmode.mode = ZERO_ZEROMV;
9843#else
9844 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009845 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9846 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009847 best_mbmode.mode = ZEROMV;
9848#endif // CONFIG_EXT_INTER
9849 }
9850#else
9851#if CONFIG_EXT_INTER
9852 if (!comp_pred_mode) {
9853#endif // CONFIG_EXT_INTER
9854 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9855 ((comp_pred_mode &&
9856 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
9857 !comp_pred_mode))
9858 best_mbmode.mode = NEARESTMV;
9859 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
9860 ((comp_pred_mode &&
9861 frame_mv[NEARMV][refs[1]].as_int ==
9862 best_mbmode.mv[1].as_int) ||
9863 !comp_pred_mode))
9864 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -07009865 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
9866 ((comp_pred_mode &&
9867 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07009868 !comp_pred_mode))
9869 best_mbmode.mode = ZEROMV;
9870#if CONFIG_EXT_INTER
9871 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009872 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
9873 best_mbmode.mv[0].as_int &&
9874 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
9875 best_mbmode.mv[1].as_int)
9876 best_mbmode.mode = NEAREST_NEARESTMV;
9877 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
9878 best_mbmode.mv[0].as_int &&
9879 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
9880 best_mbmode.mv[1].as_int)
9881 best_mbmode.mode = NEAREST_NEARMV;
9882 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
9883 best_mbmode.mv[0].as_int &&
9884 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
9885 best_mbmode.mv[1].as_int)
9886 best_mbmode.mode = NEAR_NEARESTMV;
9887 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
9888 best_mbmode.mv[0].as_int &&
9889 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
9890 best_mbmode.mv[1].as_int)
9891 best_mbmode.mode = NEAR_NEARMV;
9892 else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
9893 best_mbmode.mode = ZERO_ZEROMV;
9894 }
9895#endif // CONFIG_EXT_INTER
9896#endif
9897 }
9898
9899#if CONFIG_REF_MV
9900 if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
9901#if CONFIG_EXT_INTER
9902 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
9903#else
9904 (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
9905#endif // CONFIG_EXT_INTER
9906 ) {
9907 int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
9908#if !CONFIG_EXT_INTER
9909 if (best_mbmode.ref_frame[1] > NONE)
9910 mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
9911#endif // !CONFIG_EXT_INTER
9912
9913 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) best_mbmode.mode = ZEROMV;
9914 }
9915#endif
9916
9917 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
9918 rd_cost->rate = INT_MAX;
9919 rd_cost->rdcost = INT64_MAX;
9920 return;
9921 }
9922
Yaowu Xuc27fc142016-08-22 16:08:15 -07009923#if CONFIG_DUAL_FILTER
9924 assert((cm->interp_filter == SWITCHABLE) ||
9925 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
9926 !is_inter_block(&best_mbmode));
9927 assert((cm->interp_filter == SWITCHABLE) ||
9928 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
9929 !is_inter_block(&best_mbmode));
9930 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
9931 assert((cm->interp_filter == SWITCHABLE) ||
9932 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
9933 !is_inter_block(&best_mbmode));
9934 assert((cm->interp_filter == SWITCHABLE) ||
9935 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
9936 !is_inter_block(&best_mbmode));
9937 }
9938#else
9939 assert((cm->interp_filter == SWITCHABLE) ||
9940 (cm->interp_filter == best_mbmode.interp_filter) ||
9941 !is_inter_block(&best_mbmode));
9942#endif
9943
9944 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -07009945 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
9946 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009947
9948 // macroblock modes
9949 *mbmi = best_mbmode;
9950 x->skip |= best_skip2;
9951
9952#if CONFIG_REF_MV
9953 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
9954 if (mbmi->mode != NEWMV)
9955 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
9956 else
9957 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
9958 }
9959#endif
9960
9961 for (i = 0; i < REFERENCE_MODES; ++i) {
9962 if (best_pred_rd[i] == INT64_MAX)
9963 best_pred_diff[i] = INT_MIN;
9964 else
9965 best_pred_diff[i] = best_rd - best_pred_rd[i];
9966 }
9967
9968 x->skip |= best_mode_skippable;
9969
9970 assert(best_mode_index >= 0);
9971
9972 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
9973 best_mode_skippable);
9974
Urvang Joshib100db72016-10-12 16:28:56 -07009975#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009976 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
9977 restore_uv_color_map(cpi, x);
9978 }
Urvang Joshib100db72016-10-12 16:28:56 -07009979#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009980}
9981
Urvang Joshi52648442016-10-13 17:27:51 -07009982void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
9983 TileDataEnc *tile_data, MACROBLOCK *x,
9984 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07009985 PICK_MODE_CONTEXT *ctx,
9986 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009987 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009988 MACROBLOCKD *const xd = &x->e_mbd;
9989 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9990 unsigned char segment_id = mbmi->segment_id;
9991 const int comp_pred = 0;
9992 int i;
9993 int64_t best_pred_diff[REFERENCE_MODES];
9994 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9995 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009996 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -07009997 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009998 int64_t this_rd = INT64_MAX;
9999 int rate2 = 0;
10000 const int64_t distortion2 = 0;
10001
10002 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10003 &comp_mode_p);
10004
10005 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
10006 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
10007 x->pred_mv_sad[i] = INT_MAX;
10008
10009 rd_cost->rate = INT_MAX;
10010
10011 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
10012
Urvang Joshib100db72016-10-12 16:28:56 -070010013#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010014 mbmi->palette_mode_info.palette_size[0] = 0;
10015 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010016#endif // CONFIG_PALETTE
10017
hui su5db97432016-10-14 16:10:14 -070010018#if CONFIG_FILTER_INTRA
10019 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10020 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10021#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010022 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070010023 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010024 mbmi->uv_mode = DC_PRED;
10025 mbmi->ref_frame[0] = LAST_FRAME;
10026 mbmi->ref_frame[1] = NONE;
Sarah Parkere5299862016-08-16 14:57:37 -070010027#if CONFIG_GLOBAL_MOTION
10028 mbmi->mv[0].as_int =
Debargha Mukherjee5f305852016-11-03 15:47:21 -070010029 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]]).as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070010030#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010031 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010032#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070010033 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070010034 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070010035
Yaowu Xuc27fc142016-08-22 16:08:15 -070010036#if CONFIG_REF_MV
10037 mbmi->ref_mv_idx = 0;
10038 mbmi->pred_mv[0].as_int = 0;
10039#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010040
10041 if (cm->interp_filter != BILINEAR) {
10042 best_filter = EIGHTTAP_REGULAR;
10043 if (cm->interp_filter == SWITCHABLE &&
10044#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010045 av1_is_interp_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010046#endif // CONFIG_EXT_INTERP
10047 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
10048 int rs;
10049 int best_rs = INT_MAX;
10050 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
10051#if CONFIG_DUAL_FILTER
10052 int k;
10053 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
10054#else
10055 mbmi->interp_filter = i;
10056#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010057 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010058 if (rs < best_rs) {
10059 best_rs = rs;
10060#if CONFIG_DUAL_FILTER
10061 best_filter = mbmi->interp_filter[0];
10062#else
10063 best_filter = mbmi->interp_filter;
10064#endif
10065 }
10066 }
10067 }
10068 }
10069 // Set the appropriate filter
10070 if (cm->interp_filter == SWITCHABLE) {
10071#if CONFIG_DUAL_FILTER
10072 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
10073#else
10074 mbmi->interp_filter = best_filter;
10075#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010076 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010077 } else {
10078#if CONFIG_DUAL_FILTER
10079 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
10080#else
10081 mbmi->interp_filter = cm->interp_filter;
10082#endif
10083 }
10084
10085 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070010086 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010087
10088 // Estimate the reference frame signaling cost and add it
10089 // to the rolling cost variable.
10090 rate2 += ref_costs_single[LAST_FRAME];
10091 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10092
10093 rd_cost->rate = rate2;
10094 rd_cost->dist = distortion2;
10095 rd_cost->rdcost = this_rd;
10096
10097 if (this_rd >= best_rd_so_far) {
10098 rd_cost->rate = INT_MAX;
10099 rd_cost->rdcost = INT64_MAX;
10100 return;
10101 }
10102
10103#if CONFIG_DUAL_FILTER
10104 assert((cm->interp_filter == SWITCHABLE) ||
10105 (cm->interp_filter == mbmi->interp_filter[0]));
10106#else
10107 assert((cm->interp_filter == SWITCHABLE) ||
10108 (cm->interp_filter == mbmi->interp_filter));
10109#endif
10110
Yaowu Xuf883b422016-08-30 14:01:10 -070010111 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10112 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010113
Yaowu Xuf883b422016-08-30 14:01:10 -070010114 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010115
10116 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
10117}
10118
Urvang Joshi52648442016-10-13 17:27:51 -070010119void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
10120 TileDataEnc *tile_data, struct macroblock *x,
10121 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070010122 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010123#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010124 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010125#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010126 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
10127 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010128 const AV1_COMMON *const cm = &cpi->common;
10129 const RD_OPT *const rd_opt = &cpi->rd;
10130 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010131 MACROBLOCKD *const xd = &x->e_mbd;
10132 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10133 const struct segmentation *const seg = &cm->seg;
10134 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
10135 unsigned char segment_id = mbmi->segment_id;
10136 int comp_pred, i;
10137 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
10138 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
10139 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
10140 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070010141 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010142#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010143 AOM_LAST2_FLAG,
10144 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010145#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010146 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010147#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010148 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010149#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070010150 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070010151 };
10152 int64_t best_rd = best_rd_so_far;
10153 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
10154 int64_t best_pred_diff[REFERENCE_MODES];
10155 int64_t best_pred_rd[REFERENCE_MODES];
10156 MB_MODE_INFO best_mbmode;
10157 int ref_index, best_ref_index = 0;
10158 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10159 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010160 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010161#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070010162 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010163#else
James Zern7b9407a2016-05-18 23:48:05 -070010164 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165#endif
Jingning Han3f167252016-06-07 16:11:42 -070010166 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
10167 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010168 int skip_uv;
10169 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070010170 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070010171 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
10172#if CONFIG_EXT_INTER
10173 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
10174#else
10175 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
10176#endif // CONFIG_EXT_INTER
10177 b_mode_info best_bmodes[4];
10178 int best_skip2 = 0;
10179 int ref_frame_skip_mask[2] = { 0 };
10180 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070010181 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070010182#if CONFIG_PVQ
10183 od_rollback_buffer pre_buf;
10184
10185 od_encode_checkpoint(&x->daala_enc, &pre_buf);
10186#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010187
10188#if CONFIG_SUPERTX
10189 best_rd_so_far = INT64_MAX;
10190 best_rd = best_rd_so_far;
10191 best_yrd = best_rd_so_far;
10192#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010193 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010194
hui su5db97432016-10-14 16:10:14 -070010195#if CONFIG_FILTER_INTRA
10196 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10197 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10198#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070010199 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010200#if CONFIG_EXT_INTER
Sarah Parker6fddd182016-11-10 20:57:20 -080010201 mbmi->interinter_compound = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010202 mbmi->use_wedge_interintra = 0;
10203#endif // CONFIG_EXT_INTER
10204
10205 for (i = 0; i < 4; i++) {
10206 int j;
10207#if CONFIG_EXT_INTER
10208 int k;
10209
10210 for (k = 0; k < 2; k++)
10211 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10212 seg_mvs[i][k][j].as_int = INVALID_MV;
10213#else
10214 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
10215 seg_mvs[i][j].as_int = INVALID_MV;
10216#endif // CONFIG_EXT_INTER
10217 }
10218
10219 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10220 &comp_mode_p);
10221
10222 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
10223 rate_uv_intra = INT_MAX;
10224
10225 rd_cost->rate = INT_MAX;
10226#if CONFIG_SUPERTX
10227 *returnrate_nocoef = INT_MAX;
10228#endif
10229
10230 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
10231 x->mbmi_ext->mode_context[ref_frame] = 0;
10232#if CONFIG_REF_MV && CONFIG_EXT_INTER
10233 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
10234#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
10235 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
10236 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
10237 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
10238 } else {
10239 ref_frame_skip_mask[0] |= (1 << ref_frame);
10240 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10241 }
10242 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
10243#if CONFIG_EXT_INTER
10244 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
10245#endif // CONFIG_EXT_INTER
10246 frame_mv[ZEROMV][ref_frame].as_int = 0;
10247 }
10248
Urvang Joshib100db72016-10-12 16:28:56 -070010249#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010250 mbmi->palette_mode_info.palette_size[0] = 0;
10251 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010252#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010253
10254 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
10255 int mode_excluded = 0;
10256 int64_t this_rd = INT64_MAX;
10257 int disable_skip = 0;
10258 int compmode_cost = 0;
10259 int rate2 = 0, rate_y = 0, rate_uv = 0;
10260 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
10261 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010262 int this_skip2 = 0;
10263 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010264
Yushin Cho77bba8d2016-11-04 16:36:56 -070010265#if CONFIG_PVQ
10266 od_encode_rollback(&x->daala_enc, &pre_buf);
10267#endif
10268
Yaowu Xuf883b422016-08-30 14:01:10 -070010269 ref_frame = av1_ref_order[ref_index].ref_frame[0];
10270 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010271
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010272#if CONFIG_REF_MV
10273 mbmi->ref_mv_idx = 0;
10274#endif
10275
Yaowu Xuc27fc142016-08-22 16:08:15 -070010276 // Look at the reference frame of the best mode so far and set the
10277 // skip mask to look at a subset of the remaining modes.
10278 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
10279 if (ref_index == 3) {
10280 switch (best_mbmode.ref_frame[0]) {
10281 case INTRA_FRAME: break;
10282 case LAST_FRAME:
10283 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
10284#if CONFIG_EXT_REFS
10285 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10286 (1 << BWDREF_FRAME) |
10287#endif // CONFIG_EXT_REFS
10288 (1 << ALTREF_FRAME);
10289 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10290 break;
10291#if CONFIG_EXT_REFS
10292 case LAST2_FRAME:
10293 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
10294 (1 << GOLDEN_FRAME) |
10295 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10296 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10297 break;
10298 case LAST3_FRAME:
10299 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10300 (1 << GOLDEN_FRAME) |
10301 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
10302 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10303 break;
10304#endif // CONFIG_EXT_REFS
10305 case GOLDEN_FRAME:
10306 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10307#if CONFIG_EXT_REFS
10308 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10309 (1 << BWDREF_FRAME) |
10310#endif // CONFIG_EXT_REFS
10311 (1 << ALTREF_FRAME);
10312 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10313 break;
10314#if CONFIG_EXT_REFS
10315 case BWDREF_FRAME:
10316 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
10317 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
10318 (1 << ALTREF_FRAME);
10319 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
10320 break;
10321#endif // CONFIG_EXT_REFS
10322 case ALTREF_FRAME:
10323 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
10324#if CONFIG_EXT_REFS
10325 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
10326 (1 << BWDREF_FRAME) |
10327#endif // CONFIG_EXT_REFS
10328 (1 << GOLDEN_FRAME);
10329#if CONFIG_EXT_REFS
10330 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
10331#endif // CONFIG_EXT_REFS
10332 break;
10333 case NONE:
10334 case TOTAL_REFS_PER_FRAME:
10335 assert(0 && "Invalid Reference frame");
10336 break;
10337 }
10338 }
10339 }
10340
10341 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010342 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010343 continue;
10344
10345 // Test best rd so far against threshold for trying this mode.
10346 if (!internal_active_edge &&
10347 rd_less_than_thresh(best_rd,
10348 rd_opt->threshes[segment_id][bsize][ref_index],
10349 tile_data->thresh_freq_fact[bsize][ref_index]))
10350 continue;
10351
10352 comp_pred = second_ref_frame > INTRA_FRAME;
10353 if (comp_pred) {
10354 if (!cpi->allow_comp_inter_inter) continue;
10355 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10356 // Do not allow compound prediction if the segment level reference frame
10357 // feature is in use as in this case there can only be one reference.
10358 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10359
10360 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10361 best_mbmode.ref_frame[0] == INTRA_FRAME)
10362 continue;
10363 }
10364
10365 // TODO(jingning, jkoleszar): scaling reference frame not supported for
10366 // sub8x8 blocks.
10367 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010368 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010369 continue;
10370
10371 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010372 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010373 continue;
10374
10375 if (comp_pred)
10376 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10377 else if (ref_frame != INTRA_FRAME)
10378 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10379
10380 // If the segment reference frame feature is enabled....
10381 // then do nothing if the current ref frame is not allowed..
10382 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
10383 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
10384 continue;
10385 // Disable this drop out case if the ref frame
10386 // segment level feature is enabled for this segment. This is to
10387 // prevent the possibility that we end up unable to pick any mode.
10388 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
10389 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
10390 // unless ARNR filtering is enabled in which case we want
10391 // an unfiltered alternative. We allow near/nearest as well
10392 // because they may result in zero-zero MVs but be cheaper.
10393 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
10394 continue;
10395 }
10396
10397 mbmi->tx_size = TX_4X4;
10398 mbmi->uv_mode = DC_PRED;
10399 mbmi->ref_frame[0] = ref_frame;
10400 mbmi->ref_frame[1] = second_ref_frame;
10401// Evaluate all sub-pel filters irrespective of whether we can use
10402// them for this frame.
10403#if CONFIG_DUAL_FILTER
10404 for (i = 0; i < 4; ++i)
10405 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10406 ? EIGHTTAP_REGULAR
10407 : cm->interp_filter;
10408#else
10409 mbmi->interp_filter =
10410 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
10411#endif
10412 x->skip = 0;
10413 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10414
10415 // Select prediction reference frames.
10416 for (i = 0; i < MAX_MB_PLANE; i++) {
10417 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10418 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10419 }
10420
10421#if CONFIG_VAR_TX
10422 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070010423 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010424#endif
10425
10426 if (ref_frame == INTRA_FRAME) {
10427 int rate;
10428 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070010429 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010430 continue;
10431 rate2 += rate;
10432 rate2 += intra_cost_penalty;
10433 distortion2 += distortion_y;
10434
10435 if (rate_uv_intra == INT_MAX) {
10436 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
10437 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
10438 }
10439 rate2 += rate_uv_intra;
10440 rate_uv = rate_uv_tokenonly;
10441 distortion2 += dist_uv;
10442 distortion_uv = dist_uv;
10443 mbmi->uv_mode = mode_uv;
10444 } else {
10445 int rate;
10446 int64_t distortion;
10447 int64_t this_rd_thresh;
10448 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
10449 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
10450 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
10451 int tmp_best_skippable = 0;
10452 int switchable_filter_index;
10453 int_mv *second_ref =
10454 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
10455 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
10456 MB_MODE_INFO tmp_best_mbmode;
10457#if CONFIG_DUAL_FILTER
10458#if CONFIG_EXT_INTERP
10459 BEST_SEG_INFO bsi[25];
10460#else
10461 BEST_SEG_INFO bsi[9];
10462#endif
10463#else
10464 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
10465#endif
10466 int pred_exists = 0;
10467 int uv_skippable;
10468#if CONFIG_EXT_INTER
10469 int_mv compound_seg_newmvs[4][2];
10470 for (i = 0; i < 4; i++) {
10471 compound_seg_newmvs[i][0].as_int = INVALID_MV;
10472 compound_seg_newmvs[i][1].as_int = INVALID_MV;
10473 }
10474#endif // CONFIG_EXT_INTER
10475
10476 this_rd_thresh = (ref_frame == LAST_FRAME)
10477 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
10478 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
10479#if CONFIG_EXT_REFS
10480 this_rd_thresh = (ref_frame == LAST2_FRAME)
10481 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
10482 : this_rd_thresh;
10483 this_rd_thresh = (ref_frame == LAST3_FRAME)
10484 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
10485 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070010486 this_rd_thresh = (ref_frame == BWDREF_FRAME)
10487 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
10488 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010489#endif // CONFIG_EXT_REFS
10490 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
10491 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
10492 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010493
10494 // TODO(any): Add search of the tx_type to improve rd performance at the
10495 // expense of speed.
10496 mbmi->tx_type = DCT_DCT;
10497
10498 if (cm->interp_filter != BILINEAR) {
10499#if CONFIG_DUAL_FILTER
10500 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10501 tmp_best_filter[1] = EIGHTTAP_REGULAR;
10502 tmp_best_filter[2] = EIGHTTAP_REGULAR;
10503 tmp_best_filter[3] = EIGHTTAP_REGULAR;
10504#else
10505 tmp_best_filter = EIGHTTAP_REGULAR;
10506#endif
10507 if (x->source_variance < sf->disable_filter_search_var_thresh) {
10508#if CONFIG_DUAL_FILTER
10509 tmp_best_filter[0] = EIGHTTAP_REGULAR;
10510#else
10511 tmp_best_filter = EIGHTTAP_REGULAR;
10512#endif
10513 } else if (sf->adaptive_pred_interp_filter == 1 &&
10514 ctx->pred_interp_filter < SWITCHABLE) {
10515#if CONFIG_DUAL_FILTER
10516 tmp_best_filter[0] = ctx->pred_interp_filter;
10517#else
10518 tmp_best_filter = ctx->pred_interp_filter;
10519#endif
10520 } else if (sf->adaptive_pred_interp_filter == 2) {
10521#if CONFIG_DUAL_FILTER
10522 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
10523 ? ctx->pred_interp_filter
10524 : 0;
10525#else
10526 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
10527 ? ctx->pred_interp_filter
10528 : 0;
10529#endif
10530 } else {
10531#if CONFIG_DUAL_FILTER
10532 for (switchable_filter_index = 0;
10533#if CONFIG_EXT_INTERP
10534 switchable_filter_index < 25;
10535#else
10536 switchable_filter_index < 9;
10537#endif
10538 ++switchable_filter_index) {
10539#else
10540 for (switchable_filter_index = 0;
10541 switchable_filter_index < SWITCHABLE_FILTERS;
10542 ++switchable_filter_index) {
10543#endif
10544 int newbest, rs;
10545 int64_t rs_rd;
10546 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
10547#if CONFIG_DUAL_FILTER
10548 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
10549 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
10550 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
10551 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
10552#else
10553 mbmi->interp_filter = switchable_filter_index;
10554#endif
10555 tmp_rd = rd_pick_best_sub8x8_mode(
10556 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10557 &rate, &rate_y, &distortion, &skippable, &total_sse,
10558 (int)this_rd_thresh, seg_mvs,
10559#if CONFIG_EXT_INTER
10560 compound_seg_newmvs,
10561#endif // CONFIG_EXT_INTER
10562 bsi, switchable_filter_index, mi_row, mi_col);
10563#if CONFIG_EXT_INTERP
10564#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010565 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010566 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10567 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) // invalid config
10568 continue;
10569#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010570 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010571 mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
10572 continue;
10573#endif
10574#endif // CONFIG_EXT_INTERP
10575 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070010576 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010577 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
10578 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
10579
10580 newbest = (tmp_rd < tmp_best_rd);
10581 if (newbest) {
10582#if CONFIG_DUAL_FILTER
10583 tmp_best_filter[0] = mbmi->interp_filter[0];
10584 tmp_best_filter[1] = mbmi->interp_filter[1];
10585 tmp_best_filter[2] = mbmi->interp_filter[2];
10586 tmp_best_filter[3] = mbmi->interp_filter[3];
10587#else
10588 tmp_best_filter = mbmi->interp_filter;
10589#endif
10590 tmp_best_rd = tmp_rd;
10591 }
10592 if ((newbest && cm->interp_filter == SWITCHABLE) ||
10593 (
10594#if CONFIG_DUAL_FILTER
10595 mbmi->interp_filter[0] == cm->interp_filter
10596#else
10597 mbmi->interp_filter == cm->interp_filter
10598#endif
10599 && cm->interp_filter != SWITCHABLE)) {
10600 tmp_best_rdu = tmp_rd;
10601 tmp_best_rate = rate;
10602 tmp_best_ratey = rate_y;
10603 tmp_best_distortion = distortion;
10604 tmp_best_sse = total_sse;
10605 tmp_best_skippable = skippable;
10606 tmp_best_mbmode = *mbmi;
10607 for (i = 0; i < 4; i++) {
10608 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
10609 }
10610 pred_exists = 1;
10611 }
10612 } // switchable_filter_index loop
10613 }
10614 }
10615
10616 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
10617
10618#if CONFIG_DUAL_FILTER
10619 mbmi->interp_filter[0] =
10620 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
10621 : cm->interp_filter);
10622 mbmi->interp_filter[1] =
10623 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
10624 : cm->interp_filter);
10625 mbmi->interp_filter[2] =
10626 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
10627 : cm->interp_filter);
10628 mbmi->interp_filter[3] =
10629 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
10630 : cm->interp_filter);
10631#else
10632 mbmi->interp_filter =
10633 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
10634 : cm->interp_filter);
10635#endif
10636
10637 if (!pred_exists) {
10638 // Handles the special case when a filter that is not in the
10639 // switchable list (bilinear) is indicated at the frame level
10640 tmp_rd = rd_pick_best_sub8x8_mode(
10641 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
10642 &rate, &rate_y, &distortion, &skippable, &total_sse,
10643 (int)this_rd_thresh, seg_mvs,
10644#if CONFIG_EXT_INTER
10645 compound_seg_newmvs,
10646#endif // CONFIG_EXT_INTER
10647 bsi, 0, mi_row, mi_col);
10648#if CONFIG_EXT_INTERP
10649#if CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010650 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010651 (mbmi->interp_filter[0] != EIGHTTAP_REGULAR ||
10652 mbmi->interp_filter[1] != EIGHTTAP_REGULAR)) {
10653 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
10654 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
10655 }
10656#else
Yaowu Xuf883b422016-08-30 14:01:10 -070010657 if (!av1_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010658 mbmi->interp_filter != EIGHTTAP_REGULAR)
10659 mbmi->interp_filter = EIGHTTAP_REGULAR;
10660#endif // CONFIG_DUAL_FILTER
10661#endif // CONFIG_EXT_INTERP
10662 if (tmp_rd == INT64_MAX) continue;
10663 } else {
10664 total_sse = tmp_best_sse;
10665 rate = tmp_best_rate;
10666 rate_y = tmp_best_ratey;
10667 distortion = tmp_best_distortion;
10668 skippable = tmp_best_skippable;
10669 *mbmi = tmp_best_mbmode;
10670 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
10671 }
10672 // Add in the cost of the transform type
10673 if (!xd->lossless[mbmi->segment_id]) {
10674 int rate_tx_type = 0;
10675#if CONFIG_EXT_TX
10676 if (get_ext_tx_types(mbmi->tx_size, bsize, 1) > 1) {
10677 const int eset = get_ext_tx_set(mbmi->tx_size, bsize, 1);
10678 rate_tx_type =
10679 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
10680 }
10681#else
10682 if (mbmi->tx_size < TX_32X32) {
10683 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
10684 }
10685#endif
10686 rate += rate_tx_type;
10687 rate_y += rate_tx_type;
10688 }
10689
10690 rate2 += rate;
10691 distortion2 += distortion;
10692
10693 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070010694 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010695
10696 if (!mode_excluded)
10697 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
10698 : cm->reference_mode == COMPOUND_REFERENCE;
10699
Yaowu Xuf883b422016-08-30 14:01:10 -070010700 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010701
10702 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070010703 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010704 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
10705
10706 if (tmp_best_rdu > 0) {
10707 // If even the 'Y' rd value of split is higher than best so far
10708 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070010709 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070010710 RD_STATS rd_stats_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010711 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010712#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070010713 is_cost_valid_uv =
10714 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080010715#else
10716 is_cost_valid_uv =
10717 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
10718#endif
Angie Chiangb5dda482016-11-02 16:19:58 -070010719 rate_uv = rd_stats_uv.rate;
10720 distortion_uv = rd_stats_uv.dist;
10721 uv_skippable = rd_stats_uv.skip;
10722 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080010723
Angie Chiangb5dda482016-11-02 16:19:58 -070010724 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010725 rate2 += rate_uv;
10726 distortion2 += distortion_uv;
10727 skippable = skippable && uv_skippable;
10728 total_sse += uv_sse;
10729 } else {
10730 continue;
10731 }
10732 }
10733
10734 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10735
10736 // Estimate the reference frame signaling cost and add it
10737 // to the rolling cost variable.
10738 if (second_ref_frame > INTRA_FRAME) {
10739 rate2 += ref_costs_comp[ref_frame];
10740#if CONFIG_EXT_REFS
10741 rate2 += ref_costs_comp[second_ref_frame];
10742#endif // CONFIG_EXT_REFS
10743 } else {
10744 rate2 += ref_costs_single[ref_frame];
10745 }
10746
10747 if (!disable_skip) {
10748 // Skip is never coded at the segment level for sub8x8 blocks and instead
10749 // always coded in the bitstream at the mode info level.
10750
10751 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
10752 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10753 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
10754 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010755 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010756 } else {
10757 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010758 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010759 distortion2 = total_sse;
10760 assert(total_sse >= 0);
10761 rate2 -= (rate_y + rate_uv);
10762 rate_y = 0;
10763 rate_uv = 0;
10764 this_skip2 = 1;
10765 }
10766 } else {
10767 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010768 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010769 }
10770
10771 // Calculate the final RD estimate for this mode.
10772 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10773 }
10774
10775 if (!disable_skip && ref_frame == INTRA_FRAME) {
10776 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010777 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010778 }
10779
10780 // Did this mode help.. i.e. is it the new best mode
10781 if (this_rd < best_rd || x->skip) {
10782 if (!mode_excluded) {
10783 // Note index of best mode so far
10784 best_ref_index = ref_index;
10785
10786 if (ref_frame == INTRA_FRAME) {
10787 /* required for left and above block mv */
10788 mbmi->mv[0].as_int = 0;
10789 }
10790
10791 rd_cost->rate = rate2;
10792#if CONFIG_SUPERTX
10793 *returnrate_nocoef = rate2 - rate_y - rate_uv;
10794 if (!disable_skip)
10795 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070010796 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
10797 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10798 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010799 assert(*returnrate_nocoef > 0);
10800#endif // CONFIG_SUPERTX
10801 rd_cost->dist = distortion2;
10802 rd_cost->rdcost = this_rd;
10803 best_rd = this_rd;
10804 best_yrd =
10805 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
10806 best_mbmode = *mbmi;
10807 best_skip2 = this_skip2;
10808
10809#if CONFIG_VAR_TX
10810 for (i = 0; i < MAX_MB_PLANE; ++i)
10811 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
10812#endif
10813
10814 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010815 }
10816 }
10817
10818 /* keep record of best compound/single-only prediction */
10819 if (!disable_skip && ref_frame != INTRA_FRAME) {
10820 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10821
10822 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10823 single_rate = rate2 - compmode_cost;
10824 hybrid_rate = rate2;
10825 } else {
10826 single_rate = rate2;
10827 hybrid_rate = rate2 + compmode_cost;
10828 }
10829
10830 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10831 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10832
10833 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
10834 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10835 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
10836 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10837
10838 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10839 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10840 }
10841
Yaowu Xuc27fc142016-08-22 16:08:15 -070010842 if (x->skip && !comp_pred) break;
10843 }
10844
10845 if (best_rd >= best_rd_so_far) {
10846 rd_cost->rate = INT_MAX;
10847 rd_cost->rdcost = INT64_MAX;
10848#if CONFIG_SUPERTX
10849 *returnrate_nocoef = INT_MAX;
10850#endif // CONFIG_SUPERTX
10851 return;
10852 }
10853
Yaowu Xuc27fc142016-08-22 16:08:15 -070010854 if (best_rd == INT64_MAX) {
10855 rd_cost->rate = INT_MAX;
10856 rd_cost->dist = INT64_MAX;
10857 rd_cost->rdcost = INT64_MAX;
10858#if CONFIG_SUPERTX
10859 *returnrate_nocoef = INT_MAX;
10860#endif // CONFIG_SUPERTX
10861 return;
10862 }
10863
10864#if CONFIG_DUAL_FILTER
10865 assert((cm->interp_filter == SWITCHABLE) ||
10866 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10867 !is_inter_block(&best_mbmode));
10868#else
10869 assert((cm->interp_filter == SWITCHABLE) ||
10870 (cm->interp_filter == best_mbmode.interp_filter) ||
10871 !is_inter_block(&best_mbmode));
10872#endif
10873
Yaowu Xuf883b422016-08-30 14:01:10 -070010874 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10875 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010876
10877 // macroblock modes
10878 *mbmi = best_mbmode;
10879#if CONFIG_VAR_TX && CONFIG_EXT_TX && CONFIG_RECT_TX
10880 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
10881#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
10882
10883 x->skip |= best_skip2;
10884 if (!is_inter_block(&best_mbmode)) {
10885 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
10886 } else {
10887 for (i = 0; i < 4; ++i)
10888 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
10889
Yaowu Xuc27fc142016-08-22 16:08:15 -070010890#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070010891 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
10892 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010893#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010894 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
10895 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010896 }
10897
10898 for (i = 0; i < REFERENCE_MODES; ++i) {
10899 if (best_pred_rd[i] == INT64_MAX)
10900 best_pred_diff[i] = INT_MIN;
10901 else
10902 best_pred_diff[i] = best_rd - best_pred_rd[i];
10903 }
10904
10905 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
10906}
10907
Yue Chencb60b182016-10-13 15:18:22 -070010908#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010909// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070010910//
10911// The OBMC predictor is computed as:
10912//
10913// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010914// AOM_BLEND_A64(Mh(x),
10915// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010916// PLeft(x, y))
10917//
Yaowu Xuf883b422016-08-30 14:01:10 -070010918// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070010919// rounding, this can be written as:
10920//
Yaowu Xuf883b422016-08-30 14:01:10 -070010921// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010922// Mh(x) * Mv(y) * P(x,y) +
10923// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010924// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010925//
10926// Where :
10927//
Yaowu Xuf883b422016-08-30 14:01:10 -070010928// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
10929// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010930//
10931// This function computes 'wsrc' and 'mask' as:
10932//
10933// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010934// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010935// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010936// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010937//
10938// mask(x, y) = Mh(x) * Mv(y)
10939//
10940// These can then be used to efficiently approximate the error for any
10941// predictor P in the context of the provided neighbouring predictors by
10942// computing:
10943//
10944// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010945// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010946//
Yaowu Xuf883b422016-08-30 14:01:10 -070010947static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010948 const MACROBLOCKD *xd, int mi_row,
10949 int mi_col, const uint8_t *above,
10950 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070010951 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010952 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
10953 int row, col, i;
10954 const int bw = 8 * xd->n8_w;
10955 const int bh = 8 * xd->n8_h;
Yue Chene9638cc2016-10-10 12:37:54 -070010956 int32_t *mask_buf = x->mask_buf;
10957 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010958 const int wsrc_stride = bw;
10959 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070010960 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
10961#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010962 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
10963#else
10964 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010965#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010966
10967 // plane 0 should not be subsampled
10968 assert(xd->plane[0].subsampling_x == 0);
10969 assert(xd->plane[0].subsampling_y == 0);
10970
Yaowu Xuf883b422016-08-30 14:01:10 -070010971 av1_zero_array(wsrc_buf, bw * bh);
10972 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010973
10974 // handle above row
10975 if (xd->up_available) {
10976 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010977 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010978 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010979 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010980
10981 assert(miw > 0);
10982
10983 i = 0;
10984 do { // for each mi in the above row
10985 const int mi_col_offset = i;
10986 const MB_MODE_INFO *const above_mbmi =
10987 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
10988 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070010989 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010990 const int neighbor_bw = mi_step * MI_SIZE;
10991
10992 if (is_neighbor_overlappable(above_mbmi)) {
10993 const int tmp_stride = above_stride;
10994 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
10995 int32_t *mask = mask_buf + (i * MI_SIZE);
10996
10997 if (!is_hbd) {
10998 const uint8_t *tmp = above;
10999
11000 for (row = 0; row < overlap; ++row) {
11001 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011002 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011003 for (col = 0; col < neighbor_bw; ++col) {
11004 wsrc[col] = m1 * tmp[col];
11005 mask[col] = m0;
11006 }
11007 wsrc += wsrc_stride;
11008 mask += mask_stride;
11009 tmp += tmp_stride;
11010 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011011#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011012 } else {
11013 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11014
11015 for (row = 0; row < overlap; ++row) {
11016 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011017 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011018 for (col = 0; col < neighbor_bw; ++col) {
11019 wsrc[col] = m1 * tmp[col];
11020 mask[col] = m0;
11021 }
11022 wsrc += wsrc_stride;
11023 mask += mask_stride;
11024 tmp += tmp_stride;
11025 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011026#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011027 }
11028 }
11029
11030 above += neighbor_bw;
11031 i += mi_step;
11032 } while (i < miw);
11033 }
11034
11035 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011036 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11037 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011038 }
11039
11040 // handle left column
11041 if (xd->left_available) {
11042 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011043 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011044 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011045 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011046
11047 assert(mih > 0);
11048
11049 i = 0;
11050 do { // for each mi in the left column
11051 const int mi_row_offset = i;
11052 const MB_MODE_INFO *const left_mbmi =
11053 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
11054 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070011055 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011056 const int neighbor_bh = mi_step * MI_SIZE;
11057
11058 if (is_neighbor_overlappable(left_mbmi)) {
11059 const int tmp_stride = left_stride;
11060 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11061 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11062
11063 if (!is_hbd) {
11064 const uint8_t *tmp = left;
11065
11066 for (row = 0; row < neighbor_bh; ++row) {
11067 for (col = 0; col < overlap; ++col) {
11068 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011069 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11070 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11071 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11072 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011073 }
11074 wsrc += wsrc_stride;
11075 mask += mask_stride;
11076 tmp += tmp_stride;
11077 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011078#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011079 } else {
11080 const uint16_t *tmp = CONVERT_TO_SHORTPTR(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#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011095 }
11096 }
11097
11098 left += neighbor_bh * left_stride;
11099 i += mi_step;
11100 } while (i < mih);
11101 }
11102
11103 if (!is_hbd) {
11104 const uint8_t *src = x->plane[0].src.buf;
11105
11106 for (row = 0; row < bh; ++row) {
11107 for (col = 0; col < bw; ++col) {
11108 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11109 }
11110 wsrc_buf += wsrc_stride;
11111 src += x->plane[0].src.stride;
11112 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011113#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011114 } else {
11115 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11116
11117 for (row = 0; row < bh; ++row) {
11118 for (col = 0; col < bw; ++col) {
11119 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11120 }
11121 wsrc_buf += wsrc_stride;
11122 src += x->plane[0].src.stride;
11123 }
Yaowu Xuf883b422016-08-30 14:01:10 -070011124#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011125 }
11126}
Yue Chencb60b182016-10-13 15:18:22 -070011127#endif // CONFIG_MOTION_VAR