blob: d9e1b273c99b8d3c388b3b279b40445dd9e2f701 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <assert.h>
13#include <math.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_dsp_rtcd.h"
Jingning Han1aab8182016-06-03 11:09:06 -070016#include "./av1_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_dsp/blend.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
22#include "aom_ports/system_state.h"
23
24#include "av1/common/common.h"
25#include "av1/common/common_data.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconinter.h"
33#include "av1/common/reconintra.h"
34#include "av1/common/scan.h"
35#include "av1/common/seg_common.h"
Yue Chen69f18e12016-09-08 14:48:15 -070036#if CONFIG_WARPED_MOTION
37#include "av1/common/warped_motion.h"
38#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070039
Jingning Han1aab8182016-06-03 11:09:06 -070040#include "av1/encoder/aq_variance.h"
Tom Finegan17ce8b12017-02-08 12:46:31 -080041#include "av1/encoder/av1_quantize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070042#include "av1/encoder/cost.h"
43#include "av1/encoder/encodemb.h"
44#include "av1/encoder/encodemv.h"
45#include "av1/encoder/encoder.h"
46#include "av1/encoder/hybrid_fwd_txfm.h"
47#include "av1/encoder/mcomp.h"
Urvang Joshib100db72016-10-12 16:28:56 -070048#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070049#include "av1/encoder/palette.h"
Urvang Joshib100db72016-10-12 16:28:56 -070050#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070051#include "av1/encoder/ratectrl.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/rdopt.h"
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070054#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070055#if CONFIG_PVQ
56#include "av1/encoder/pvq_encoder.h"
57#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -080058#if CONFIG_PVQ || CONFIG_DAALA_DIST
59#include "av1/common/pvq.h"
60#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070061#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080062#define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS)
Angie Chiang5678ad92016-11-21 09:38:40 -080063static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
Angie Chiangd91ab372016-11-21 18:16:49 -080064 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 0 }, { 1, 1 },
65 { 1, 2 }, { 1, 3 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
66 { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070067};
Angie Chiang5678ad92016-11-21 09:38:40 -080068#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070069
70#if CONFIG_EXT_REFS
71
72#define LAST_FRAME_MODE_MASK \
73 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
74 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
75#define LAST2_FRAME_MODE_MASK \
76 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
77 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
78#define LAST3_FRAME_MODE_MASK \
79 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
80 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
81#define GOLDEN_FRAME_MODE_MASK \
82 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
83 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
84#define BWDREF_FRAME_MODE_MASK \
85 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
86 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
87#define ALTREF_FRAME_MODE_MASK \
88 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
89 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
90
91#else
92
93#define LAST_FRAME_MODE_MASK \
94 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
95#define GOLDEN_FRAME_MODE_MASK \
96 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
97#define ALTREF_FRAME_MODE_MASK \
98 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
99
100#endif // CONFIG_EXT_REFS
101
102#if CONFIG_EXT_REFS
103#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
104#else
105#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
106#endif // CONFIG_EXT_REFS
107
108#define MIN_EARLY_TERM_INDEX 3
109#define NEW_MV_DISCOUNT_FACTOR 8
110
111#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700112#define ANGLE_SKIP_THRESH 10
113#define FILTER_FAST_SEARCH 1
114#endif // CONFIG_EXT_INTRA
115
116const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
117 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
118
119typedef struct {
120 PREDICTION_MODE mode;
121 MV_REFERENCE_FRAME ref_frame[2];
122} MODE_DEFINITION;
123
124typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
125
126struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700127 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128 MACROBLOCK *x;
129 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
130 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800131 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132 int64_t this_rd;
133 int64_t best_rd;
134 int exit_early;
135 int use_fast_coef_costing;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700136 const SCAN_ORDER *scan_order;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137};
138
139#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700140static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500141 { NEARESTMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700142#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500143 { NEARESTMV, { LAST2_FRAME, NONE_FRAME } },
144 { NEARESTMV, { LAST3_FRAME, NONE_FRAME } },
145 { NEARESTMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700146#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500147 { NEARESTMV, { ALTREF_FRAME, NONE_FRAME } },
148 { NEARESTMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700149
Emil Keyder01770b32017-01-20 18:03:11 -0500150 { DC_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700151
Emil Keyder01770b32017-01-20 18:03:11 -0500152 { NEWMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700153#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500154 { NEWMV, { LAST2_FRAME, NONE_FRAME } },
155 { NEWMV, { LAST3_FRAME, NONE_FRAME } },
156 { NEWMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700157#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500158 { NEWMV, { ALTREF_FRAME, NONE_FRAME } },
159 { NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160
Emil Keyder01770b32017-01-20 18:03:11 -0500161 { NEARMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700162#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500163 { NEARMV, { LAST2_FRAME, NONE_FRAME } },
164 { NEARMV, { LAST3_FRAME, NONE_FRAME } },
165 { NEARMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700166#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500167 { NEARMV, { ALTREF_FRAME, NONE_FRAME } },
168 { NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169
170#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -0500171 { NEWFROMNEARMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500173 { NEWFROMNEARMV, { LAST2_FRAME, NONE_FRAME } },
174 { NEWFROMNEARMV, { LAST3_FRAME, NONE_FRAME } },
175 { NEWFROMNEARMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500177 { NEWFROMNEARMV, { ALTREF_FRAME, NONE_FRAME } },
178 { NEWFROMNEARMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700179#endif // CONFIG_EXT_INTER
180
Emil Keyder01770b32017-01-20 18:03:11 -0500181 { ZEROMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700182#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500183 { ZEROMV, { LAST2_FRAME, NONE_FRAME } },
184 { ZEROMV, { LAST3_FRAME, NONE_FRAME } },
185 { ZEROMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500187 { ZEROMV, { GOLDEN_FRAME, NONE_FRAME } },
188 { ZEROMV, { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700189
190// TODO(zoeliu): May need to reconsider the order on the modes to check
191
192#if CONFIG_EXT_INTER
193 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
194#if CONFIG_EXT_REFS
195 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
196 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
197#endif // CONFIG_EXT_REFS
198 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
199#if CONFIG_EXT_REFS
200 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
201 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
202 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
203 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
204#endif // CONFIG_EXT_REFS
205
206#else // CONFIG_EXT_INTER
207
208 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
209#if CONFIG_EXT_REFS
210 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
211 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
212#endif // CONFIG_EXT_REFS
213 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
214#if CONFIG_EXT_REFS
215 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
216 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
217 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
218 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
219#endif // CONFIG_EXT_REFS
220#endif // CONFIG_EXT_INTER
221
Emil Keyder01770b32017-01-20 18:03:11 -0500222 { TM_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700223
Urvang Joshi6be4a542016-11-03 15:24:05 -0700224#if CONFIG_ALT_INTRA
Emil Keyder01770b32017-01-20 18:03:11 -0500225 { SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700226#endif // CONFIG_ALT_INTRA
227
Yaowu Xuc27fc142016-08-22 16:08:15 -0700228#if CONFIG_EXT_INTER
229 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
230 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
231 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
232 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
233 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
234 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
235 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
236 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
237 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
238
239#if CONFIG_EXT_REFS
240 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
241 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
242 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
243 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
244 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
247 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
248 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
249
250 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
251 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
252 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
253 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
254 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
257 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
258 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
259#endif // CONFIG_EXT_REFS
260
261 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
262 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
263 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
264 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
265 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
269 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
270
271#if CONFIG_EXT_REFS
272 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
273 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
274 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
275 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
276 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
277 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
278 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
279 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
280 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
281
282 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
283 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
284 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
285 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
286 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
287 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
289 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
290 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
291
292 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
293 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
294 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
295 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
296 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
297 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
299 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
300 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
301
302 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
303 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
304 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
305 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
306 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
307 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
310 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
311#endif // CONFIG_EXT_REFS
312
313#else // CONFIG_EXT_INTER
314
315 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
316 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
317#if CONFIG_EXT_REFS
318 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
319 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
320 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
321 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
322#endif // CONFIG_EXT_REFS
323 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
324 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
325
326#if CONFIG_EXT_REFS
327 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
328 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
329 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
330 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
331 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
332 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
333 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
334 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
335#endif // CONFIG_EXT_REFS
336
337 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
338#if CONFIG_EXT_REFS
339 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
340 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
341#endif // CONFIG_EXT_REFS
342 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
343
344#if CONFIG_EXT_REFS
345 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
346 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
347 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
348 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
349#endif // CONFIG_EXT_REFS
350
351#endif // CONFIG_EXT_INTER
352
Emil Keyder01770b32017-01-20 18:03:11 -0500353 { H_PRED, { INTRA_FRAME, NONE_FRAME } },
354 { V_PRED, { INTRA_FRAME, NONE_FRAME } },
355 { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
356 { D207_PRED, { INTRA_FRAME, NONE_FRAME } },
357 { D153_PRED, { INTRA_FRAME, NONE_FRAME } },
358 { D63_PRED, { INTRA_FRAME, NONE_FRAME } },
359 { D117_PRED, { INTRA_FRAME, NONE_FRAME } },
360 { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700361
362#if CONFIG_EXT_INTER
363 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
364 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
365 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
366 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
367
368#if CONFIG_EXT_REFS
369 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
370 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
371 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
372 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
373
374 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
375 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
376 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
377 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
378#endif // CONFIG_EXT_REFS
379
380 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
381 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
382 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
383 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
384
385#if CONFIG_EXT_REFS
386 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
387 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
388 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
389 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
390#endif // CONFIG_EXT_REFS
391
392 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
393 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
394 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
395 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
396#endif // CONFIG_EXT_INTER
397};
398
Yaowu Xuf883b422016-08-30 14:01:10 -0700399static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500400 { { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700401#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500402 { { LAST2_FRAME, NONE_FRAME } }, { { LAST3_FRAME, NONE_FRAME } },
403 { { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500405 { { GOLDEN_FRAME, NONE_FRAME } }, { { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700406
407 { { LAST_FRAME, ALTREF_FRAME } },
408#if CONFIG_EXT_REFS
409 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
410#endif // CONFIG_EXT_REFS
411 { { GOLDEN_FRAME, ALTREF_FRAME } },
412
413#if CONFIG_EXT_REFS
414 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
415 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
416#endif // CONFIG_EXT_REFS
417
Emil Keyder01770b32017-01-20 18:03:11 -0500418 { { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700419};
420
hui su5db97432016-10-14 16:10:14 -0700421#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700422static INLINE int write_uniform_cost(int n, int v) {
423 int l = get_unsigned_bits(n), m = (1 << l) - n;
424 if (l == 0) return 0;
425 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700426 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700428 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429}
hui su5db97432016-10-14 16:10:14 -0700430#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700431
432// constants for prune 1 and prune 2 decision boundaries
433#define FAST_EXT_TX_CORR_MID 0.0
434#define FAST_EXT_TX_EDST_MID 0.1
435#define FAST_EXT_TX_CORR_MARGIN 0.5
436#define FAST_EXT_TX_EDST_MARGIN 0.3
437
438static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
439 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
440#if CONFIG_EXT_TX
441 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
442 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
443#endif // CONFIG_EXT_TX
444};
445
446static const TX_TYPE_1D htx_tab[TX_TYPES] = {
447 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
448#if CONFIG_EXT_TX
449 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
450 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
451#endif // CONFIG_EXT_TX
452};
453
Yushin Cho7a428ba2017-01-12 16:28:49 -0800454#if CONFIG_DAALA_DIST
455static int od_compute_var_4x4(od_coeff *x, int stride) {
456 int sum;
457 int s2;
458 int i;
459 sum = 0;
460 s2 = 0;
461 for (i = 0; i < 4; i++) {
462 int j;
463 for (j = 0; j < 4; j++) {
464 int t;
465
466 t = x[i * stride + j];
467 sum += t;
468 s2 += t * t;
469 }
470 }
471 // TODO(yushin) : Check wheter any changes are required for high bit depth.
472 return (s2 - (sum * sum >> 4)) >> 4;
473}
474
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500475/* OD_DIST_LP_MID controls the frequency weighting filter used for computing
476 the distortion. For a value X, the filter is [1 X 1]/(X + 2) and
477 is applied both horizontally and vertically. For X=5, the filter is
478 a good approximation for the OD_QM8_Q4_HVS quantization matrix. */
479#define OD_DIST_LP_MID (5)
480#define OD_DIST_LP_NORM (OD_DIST_LP_MID + 2)
481
Yushin Cho7a428ba2017-01-12 16:28:49 -0800482static double od_compute_dist_8x8(int qm, int use_activity_masking, od_coeff *x,
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500483 od_coeff *y, od_coeff *e_lp, int stride) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800484 double sum;
485 int min_var;
486 double mean_var;
487 double var_stat;
488 double activity;
489 double calibration;
490 int i;
491 int j;
492 double vardist;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800493
494 vardist = 0;
495 OD_ASSERT(qm != OD_FLAT_QM);
496#if 1
497 min_var = INT_MAX;
498 mean_var = 0;
499 for (i = 0; i < 3; i++) {
500 for (j = 0; j < 3; j++) {
501 int varx;
502 int vary;
503 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
504 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
505 min_var = OD_MINI(min_var, varx);
506 mean_var += 1. / (1 + varx);
507 /* The cast to (double) is to avoid an overflow before the sqrt.*/
508 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
509 }
510 }
511 /* We use a different variance statistic depending on whether activity
512 masking is used, since the harmonic mean appeared slghtly worse with
513 masking off. The calibration constant just ensures that we preserve the
514 rate compared to activity=1. */
515 if (use_activity_masking) {
516 calibration = 1.95;
517 var_stat = 9. / mean_var;
518 } else {
519 calibration = 1.62;
520 var_stat = min_var;
521 }
522 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
523 activity masking constant. */
524 activity = calibration * pow(.25 + var_stat, -1. / 6);
525#else
526 activity = 1;
527#endif
528 sum = 0;
529 for (i = 0; i < 8; i++) {
530 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500531 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800532 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500533 /* Normalize the filter to unit DC response. */
534 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
535 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800536 return activity * activity * (sum + vardist);
537}
538
539// Note : Inputs x and y are in a pixel domain
540static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
541 od_coeff *y, int bsize_w, int bsize_h,
542 int qindex) {
543 int i;
544 double sum;
545 sum = 0;
546
Yushin Cho7a428ba2017-01-12 16:28:49 -0800547 assert(bsize_w >= 8 && bsize_h >= 8);
548
549 if (qm == OD_FLAT_QM) {
550 for (i = 0; i < bsize_w * bsize_h; i++) {
551 double tmp;
552 tmp = x[i] - y[i];
553 sum += tmp * tmp;
554 }
555 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500556 int j;
557 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
558 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
559 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
560 int mid = OD_DIST_LP_MID;
561 for (i = 0; i < bsize_h; i++) {
562 for (j = 0; j < bsize_w; j++) {
563 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
564 }
565 }
566 for (i = 0; i < bsize_h; i++) {
567 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
568 tmp[i * bsize_w + bsize_w - 1] =
569 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
570 for (j = 1; j < bsize_w - 1; j++) {
571 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
572 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
573 }
574 }
575 for (j = 0; j < bsize_w; j++) {
576 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
577 e_lp[(bsize_h - 1) * bsize_w + j] =
578 mid * tmp[(bsize_h - 1) * bsize_w + j] +
579 2 * tmp[(bsize_h - 2) * bsize_w + j];
580 }
581 for (i = 1; i < bsize_h - 1; i++) {
582 for (j = 0; j < bsize_w; j++) {
583 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
584 tmp[(i - 1) * bsize_w + j] +
585 tmp[(i + 1) * bsize_w + j];
586 }
587 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800588 for (i = 0; i < bsize_h; i += 8) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800589 for (j = 0; j < bsize_w; j += 8) {
590 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500591 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
592 bsize_w);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800593 }
594 }
David Michael Barrd091b802017-01-21 16:05:46 +0900595 /* Scale according to linear regression against SSE, for 8x8 blocks. */
596 if (activity_masking) {
597 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
598 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
599 } else {
600 sum *= qindex >= 128
601 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
602 : qindex <= 43
603 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
604 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
605 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800606 }
607 return sum;
608}
609
610static int64_t av1_daala_dist(const uint8_t *src, int src_stride,
611 const uint8_t *dst, int dst_stride, int tx_size,
612 int qm, int use_activity_masking, int qindex) {
613 int i, j;
614 int64_t d;
615 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
616 const int bsw = block_size_wide[tx_bsize];
617 const int bsh = block_size_high[tx_bsize];
618 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
619 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
620
621 assert(qm == OD_HVS_QM);
622
623 for (j = 0; j < bsh; j++)
624 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
625
626 for (j = 0; j < bsh; j++)
627 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
628
629 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
630 qindex);
631 return d;
632}
633#endif // #if CONFIG_DAALA_DIST
634
Yaowu Xuf883b422016-08-30 14:01:10 -0700635static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636 uint8_t *src, int src_stride,
637 uint8_t *dst, int dst_stride,
638 double *hordist, double *verdist) {
Jingning Han73db4ac2016-11-30 11:23:27 -0800639 int bw = block_size_wide[bsize];
640 int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
642 unsigned int var[16];
643 double total = 0;
644
645 const int f_index = bsize - BLOCK_16X16;
646 if (f_index < 0) {
647 int i, j, index;
648 int w_shift = bw == 8 ? 1 : 2;
649 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700650#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700651 if (cpi->common.use_highbitdepth) {
652 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
653 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
654 for (i = 0; i < bh; ++i)
655 for (j = 0; j < bw; ++j) {
656 index = (j >> w_shift) + ((i >> h_shift) << 2);
657 esq[index] +=
658 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
659 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
660 }
661 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700662#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663
664 for (i = 0; i < bh; ++i)
665 for (j = 0; j < bw; ++j) {
666 index = (j >> w_shift) + ((i >> h_shift) << 2);
667 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
668 (src[j + i * src_stride] - dst[j + i * dst_stride]);
669 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700670#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700671 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700672#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700673 } else {
674 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
675 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
676 dst_stride, &esq[1]);
677 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
678 dst_stride, &esq[2]);
679 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
680 dst + 3 * bw / 4, dst_stride, &esq[3]);
681 src += bh / 4 * src_stride;
682 dst += bh / 4 * dst_stride;
683
684 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
685 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
686 dst_stride, &esq[5]);
687 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
688 dst_stride, &esq[6]);
689 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
690 dst + 3 * bw / 4, dst_stride, &esq[7]);
691 src += bh / 4 * src_stride;
692 dst += bh / 4 * dst_stride;
693
694 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
695 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
696 dst_stride, &esq[9]);
697 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
698 dst_stride, &esq[10]);
699 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
700 dst + 3 * bw / 4, dst_stride, &esq[11]);
701 src += bh / 4 * src_stride;
702 dst += bh / 4 * dst_stride;
703
704 var[12] =
705 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
706 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
707 dst_stride, &esq[13]);
708 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
709 dst_stride, &esq[14]);
710 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
711 dst + 3 * bw / 4, dst_stride, &esq[15]);
712 }
713
714 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
715 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
716 esq[14] + esq[15];
717 if (total > 0) {
718 const double e_recip = 1.0 / total;
719 hordist[0] =
720 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
721 e_recip;
722 hordist[1] =
723 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
724 e_recip;
725 hordist[2] =
726 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
727 e_recip;
728 verdist[0] =
729 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
730 e_recip;
731 verdist[1] =
732 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
733 e_recip;
734 verdist[2] =
735 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
736 e_recip;
737 } else {
738 hordist[0] = verdist[0] = 0.25;
739 hordist[1] = verdist[1] = 0.25;
740 hordist[2] = verdist[2] = 0.25;
741 }
742 (void)var[0];
743 (void)var[1];
744 (void)var[2];
745 (void)var[3];
746 (void)var[4];
747 (void)var[5];
748 (void)var[6];
749 (void)var[7];
750 (void)var[8];
751 (void)var[9];
752 (void)var[10];
753 (void)var[11];
754 (void)var[12];
755 (void)var[13];
756 (void)var[14];
757 (void)var[15];
758}
759
Yaowu Xuf883b422016-08-30 14:01:10 -0700760static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
761 int src_stride, uint8_t *dst, int dst_stride,
762 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700763 int prune_bitmask = 0;
764 double svm_proj_h = 0, svm_proj_v = 0;
765 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
766 hdist, vdist);
767
768 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
769 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
770 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
771 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
772 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
773 prune_bitmask |= 1 << FLIPADST_1D;
774 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
775 prune_bitmask |= 1 << ADST_1D;
776
777 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
778 prune_bitmask |= 1 << (FLIPADST_1D + 8);
779 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
780 prune_bitmask |= 1 << (ADST_1D + 8);
781
782 return prune_bitmask;
783}
784
785#if CONFIG_EXT_TX
786static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
787 double *hcorr, double *vcorr) {
788 // Returns hor/ver correlation coefficient
789 const int num = (h - 1) * (w - 1);
790 double num_r;
791 int i, j;
792 int64_t xy_sum = 0, xz_sum = 0;
793 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
794 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
795 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
796 *hcorr = *vcorr = 1;
797
798 assert(num > 0);
799 num_r = 1.0 / num;
800 for (i = 1; i < h; ++i) {
801 for (j = 1; j < w; ++j) {
802 const int16_t x = diff[i * stride + j];
803 const int16_t y = diff[i * stride + j - 1];
804 const int16_t z = diff[(i - 1) * stride + j];
805 xy_sum += x * y;
806 xz_sum += x * z;
807 x_sum += x;
808 y_sum += y;
809 z_sum += z;
810 x2_sum += x * x;
811 y2_sum += y * y;
812 z2_sum += z * z;
813 }
814 }
815 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
816 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
817 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
818 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
819 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
820 if (x_var_n > 0 && y_var_n > 0) {
821 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
822 *hcorr = *hcorr < 0 ? 0 : *hcorr;
823 }
824 if (x_var_n > 0 && z_var_n > 0) {
825 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
826 *vcorr = *vcorr < 0 ? 0 : *vcorr;
827 }
828}
829
830int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
831 double *vcorr) {
832 int prune_bitmask = 0;
833 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
834
835 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
836 prune_bitmask |= 1 << IDTX_1D;
837 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
838 prune_bitmask |= 1 << DCT_1D;
839
840 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
841 prune_bitmask |= 1 << (IDTX_1D + 8);
842 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
843 prune_bitmask |= 1 << (DCT_1D + 8);
844 return prune_bitmask;
845}
846
847// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700848static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700849 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
850 int dct_idtx) {
851 struct macroblock_plane *const p = &x->plane[0];
852 struct macroblockd_plane *const pd = &xd->plane[0];
853 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
854 const int bw = 4 << (b_width_log2_lookup[bs]);
855 const int bh = 4 << (b_height_log2_lookup[bs]);
856 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
857 double hcorr, vcorr;
858 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700859 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700860
861 if (adst_flipadst)
862 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
863 pd->dst.buf, pd->dst.stride, hdist, vdist);
864 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
865
866 return prune;
867}
868#endif // CONFIG_EXT_TX
869
870// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700871static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700872 MACROBLOCK *x, MACROBLOCKD *xd) {
873 struct macroblock_plane *const p = &x->plane[0];
874 struct macroblockd_plane *const pd = &xd->plane[0];
875 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700876 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700877 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
878 pd->dst.stride, hdist, vdist);
879}
880
Yaowu Xuf883b422016-08-30 14:01:10 -0700881static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882 MACROBLOCKD *xd, int tx_set) {
883#if CONFIG_EXT_TX
884 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
885#else
886 const int tx_set_1D[TX_TYPES_1D] = { 0 };
887#endif
888
889 switch (cpi->sf.tx_type_search.prune_mode) {
890 case NO_PRUNE: return 0; break;
891 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700892 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700893 return 0;
894 return prune_one_for_sby(cpi, bsize, x, xd);
895 break;
896#if CONFIG_EXT_TX
897 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700898 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
900 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
901 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700902 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
904 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
905 break;
906#endif
907 }
908 assert(0);
909 return 0;
910}
911
912static int do_tx_type_search(TX_TYPE tx_type, int prune) {
913// TODO(sarahparker) implement for non ext tx
914#if CONFIG_EXT_TX
915 return !(((prune >> vtx_tab[tx_type]) & 1) |
916 ((prune >> (htx_tab[tx_type] + 8)) & 1));
917#else
918 // temporary to avoid compiler warnings
919 (void)vtx_tab;
920 (void)htx_tab;
921 (void)tx_type;
922 (void)prune;
923 return 1;
924#endif
925}
926
Yaowu Xuf883b422016-08-30 14:01:10 -0700927static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
929 int plane, int64_t sse, int *rate,
930 int64_t *dist) {
931 const struct macroblockd_plane *const pd = &xd->plane[plane];
932 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700933#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700935#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700936 3;
937
938 // Fast approximate the modelling function.
939 if (cpi->sf.simple_model_rd_from_var) {
940 const int64_t square_error = sse;
941 int quantizer = (pd->dequant[1] >> dequant_shift);
942
943 if (quantizer < 120)
944 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700945 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 else
947 *rate = 0;
948 *dist = (square_error * quantizer) >> 8;
949 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700950 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
951 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 }
953
954 *dist <<= 4;
955}
956
Yaowu Xuf883b422016-08-30 14:01:10 -0700957static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
959 int plane_to, int *out_rate_sum,
960 int64_t *out_dist_sum, int *skip_txfm_sb,
961 int64_t *skip_sse_sb) {
962 // Note our transform coeffs are 8 times an orthogonal transform.
963 // Hence quantizer step is also 8 times. To get effective quantizer
964 // we need to divide by 8 before sending to modeling function.
965 int plane;
966 const int ref = xd->mi[0]->mbmi.ref_frame[0];
967
968 int64_t rate_sum = 0;
969 int64_t dist_sum = 0;
970 int64_t total_sse = 0;
971
972 x->pred_sse[ref] = 0;
973
974 for (plane = plane_from; plane <= plane_to; ++plane) {
975 struct macroblock_plane *const p = &x->plane[plane];
976 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han31b6a4f2017-02-23 11:05:53 -0800977#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -0800978 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
979#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Jingning Han9ce464c2017-02-20 15:36:30 -0800981#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700982
983 unsigned int sse;
984 int rate;
985 int64_t dist;
986
Jingning Han9ce464c2017-02-20 15:36:30 -0800987#if CONFIG_CB4X4
988 if (x->skip_chroma_rd && plane) continue;
989#endif
990
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991 // TODO(geza): Write direct sse functions that do not compute
992 // variance as well.
993 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
994 &sse);
995
996 if (plane == 0) x->pred_sse[ref] = sse;
997
998 total_sse += sse;
999
1000 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
1001
1002 rate_sum += rate;
1003 dist_sum += dist;
1004 }
1005
1006 *skip_txfm_sb = total_sse == 0;
1007 *skip_sse_sb = total_sse << 4;
1008 *out_rate_sum = (int)rate_sum;
1009 *out_dist_sum = dist_sum;
1010}
1011
Yushin Cho77bba8d2016-11-04 16:36:56 -07001012#if CONFIG_PVQ
1013// Without PVQ, av1_block_error_c() return two kind of errors,
1014// 1) reconstruction (i.e. decoded) error and
1015// 2) Squared sum of transformed residue (i.e. 'coeff')
1016// However, if PVQ is enabled, coeff does not keep the transformed residue
1017// but instead a transformed original is kept.
1018// Hence, new parameter ref vector (i.e. transformed predicted signal)
1019// is required to derive the residue signal,
1020// i.e. coeff - ref = residue (all transformed).
1021
1022// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1023// a separate function that does not do the extra computations for ssz.
Yushin Cho7a428ba2017-01-12 16:28:49 -08001024static int64_t av1_block_error2_c(const tran_low_t *coeff,
1025 const tran_low_t *dqcoeff,
1026 const tran_low_t *ref, intptr_t block_size,
1027 int64_t *ssz) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001028 int64_t error;
1029
1030 // Use the existing sse codes for calculating distortion of decoded signal:
1031 // i.e. (orig - decoded)^2
1032 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1033 // prediction residue^2 = (orig - ref)^2
1034 *ssz = av1_block_error_fp(coeff, ref, block_size);
1035
1036 return error;
1037}
1038#endif
1039
Yaowu Xuf883b422016-08-30 14:01:10 -07001040int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
1041 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001042 int i;
1043 int64_t error = 0, sqcoeff = 0;
1044
1045 for (i = 0; i < block_size; i++) {
1046 const int diff = coeff[i] - dqcoeff[i];
1047 error += diff * diff;
1048 sqcoeff += coeff[i] * coeff[i];
1049 }
1050
1051 *ssz = sqcoeff;
1052 return error;
1053}
1054
Yaowu Xuf883b422016-08-30 14:01:10 -07001055int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
1056 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001057 int i;
1058 int64_t error = 0;
1059
1060 for (i = 0; i < block_size; i++) {
1061 const int diff = coeff[i] - dqcoeff[i];
1062 error += diff * diff;
1063 }
1064
1065 return error;
1066}
1067
Yaowu Xuf883b422016-08-30 14:01:10 -07001068#if CONFIG_AOM_HIGHBITDEPTH
1069int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
1070 const tran_low_t *dqcoeff, intptr_t block_size,
1071 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072 int i;
1073 int64_t error = 0, sqcoeff = 0;
1074 int shift = 2 * (bd - 8);
1075 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1076
1077 for (i = 0; i < block_size; i++) {
1078 const int64_t diff = coeff[i] - dqcoeff[i];
1079 error += diff * diff;
1080 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
1081 }
1082 assert(error >= 0 && sqcoeff >= 0);
1083 error = (error + rounding) >> shift;
1084 sqcoeff = (sqcoeff + rounding) >> shift;
1085
1086 *ssz = sqcoeff;
1087 return error;
1088}
Yaowu Xuf883b422016-08-30 14:01:10 -07001089#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001090
Yushin Cho77bba8d2016-11-04 16:36:56 -07001091#if !CONFIG_PVQ
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001092/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093 * decide whether to include cost of a trailing EOB node or not (i.e. we
1094 * can skip this if the last coefficient in this transform block, e.g. the
1095 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1096 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -07001097int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1098 int block, int coeff_ctx, TX_SIZE tx_size,
1099 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001100 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001101 MACROBLOCKD *const xd = &x->e_mbd;
1102 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1103 const struct macroblock_plane *p = &x->plane[plane];
1104 const struct macroblockd_plane *pd = &xd->plane[plane];
1105 const PLANE_TYPE type = pd->plane_type;
1106 const uint16_t *band_count = &band_count_table[tx_size][1];
1107 const int eob = p->eobs[block];
1108 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1109 const int tx_size_ctx = txsize_sqr_map[tx_size];
1110 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1111 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1112 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001114 int c, cost;
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001115#if CONFIG_NEW_TOKENSET
1116 const int ref = is_inter_block(mbmi);
1117 aom_prob *blockz_probs =
1118 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
1119#endif
1120
Yaowu Xuf883b422016-08-30 14:01:10 -07001121#if CONFIG_AOM_HIGHBITDEPTH
1122 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001124 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125#endif
1126
1127#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1128 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001129 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001131 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001132
1133 if (eob == 0) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001134#if CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001135 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001136 cost = av1_cost_bit(blockz_probs[pt], 0);
1137#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138 cost = token_costs[0][0][pt][EOB_TOKEN];
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001139#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140 } else {
1141 if (use_fast_coef_costing) {
1142 int band_left = *band_count++;
1143
1144 // dc token
1145 int v = qcoeff[0];
1146 int16_t prev_t;
Yaowu Xuf883b422016-08-30 14:01:10 -07001147 cost = av1_get_token_cost(v, &prev_t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148 cost += (*token_costs)[0][pt][prev_t];
1149
Yaowu Xuf883b422016-08-30 14:01:10 -07001150 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151 ++token_costs;
1152
1153 // ac tokens
1154 for (c = 1; c < eob; c++) {
1155 const int rc = scan[c];
1156 int16_t t;
1157
1158 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -07001159 cost += av1_get_token_cost(v, &t, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 cost += (*token_costs)[!prev_t][!prev_t][t];
1161 prev_t = t;
1162 if (!--band_left) {
1163 band_left = *band_count++;
1164 ++token_costs;
1165 }
1166 }
1167
1168 // eob token
1169 if (band_left) cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
1170
1171 } else { // !use_fast_coef_costing
1172 int band_left = *band_count++;
1173
1174 // dc token
1175 int v = qcoeff[0];
1176 int16_t tok;
1177 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Yaowu Xuf883b422016-08-30 14:01:10 -07001178 cost = av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179 cost += (*token_costs)[0][pt][tok];
1180
Yaowu Xuf883b422016-08-30 14:01:10 -07001181 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182 ++token_costs;
1183
1184 tok_cost_ptr = &((*token_costs)[!tok]);
1185
1186 // ac tokens
1187 for (c = 1; c < eob; c++) {
1188 const int rc = scan[c];
1189
1190 v = qcoeff[rc];
Yaowu Xuf883b422016-08-30 14:01:10 -07001191 cost += av1_get_token_cost(v, &tok, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001192 pt = get_coef_context(nb, token_cache, c);
1193 cost += (*tok_cost_ptr)[pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -07001194 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001195 if (!--band_left) {
1196 band_left = *band_count++;
1197 ++token_costs;
1198 }
1199 tok_cost_ptr = &((*token_costs)[!tok]);
1200 }
1201
1202 // eob token
1203 if (band_left) {
1204 pt = get_coef_context(nb, token_cache, c);
1205 cost += (*token_costs)[0][pt][EOB_TOKEN];
1206 }
1207 }
1208 }
1209
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210 return cost;
1211}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001212#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213
Yaowu Xuf883b422016-08-30 14:01:10 -07001214static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1215 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001216 int64_t *out_dist, int64_t *out_sse) {
1217 MACROBLOCKD *const xd = &x->e_mbd;
1218 const struct macroblock_plane *const p = &x->plane[plane];
1219 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001220#if CONFIG_DAALA_DIST
1221 int qm = OD_HVS_QM;
1222 int use_activity_masking = 0;
1223#if CONFIG_PVQ
1224 use_activity_masking = x->daala_enc.use_activity_masking;
1225#endif
1226#endif
1227
1228 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229 // Transform domain distortion computation is more accurate as it does
1230 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001231 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001232 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001233 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1235 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001236#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001237 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001238#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001239#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001240 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001241 *out_dist =
1242 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1243 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001244#elif CONFIG_PVQ
1245 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1246 &this_sse) >>
1247 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248#else
1249 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001250 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001251#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252 *out_sse = this_sse >> shift;
1253 } else {
1254 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001255 const int bsw = block_size_wide[tx_bsize];
1256 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001257 const int src_stride = x->plane[plane].src.stride;
1258 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001259 // Scale the transform block index to pixel unit.
1260 const int src_idx = (blk_row * src_stride + blk_col)
1261 << tx_size_wide_log2[0];
1262 const int dst_idx = (blk_row * dst_stride + blk_col)
1263 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1265 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1266 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1267 const uint16_t eob = p->eobs[block];
1268
1269 unsigned int tmp;
1270
1271 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001272 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001273
Yushin Cho7a428ba2017-01-12 16:28:49 -08001274#if CONFIG_DAALA_DIST
1275 if (plane == 0) {
1276 if (bsw >= 8 && bsh >= 8)
1277 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1278 use_activity_masking, x->qindex);
1279 else
1280 tmp = 0;
1281 } else
1282#endif
1283 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1284
Yaowu Xuc27fc142016-08-22 16:08:15 -07001285 *out_sse = (int64_t)tmp * 16;
1286
1287 if (eob) {
1288 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001289#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001290 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1291 uint8_t *recon = (uint8_t *)recon16;
1292#else
1293 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001294#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001295
Luc Trudeau005feb62017-02-22 13:34:01 -05001296 const PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001297
1298 INV_TXFM_PARAM inv_txfm_param;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001299 const int block_raster_idx =
1300 av1_block_index_to_raster_order(tx_size, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001301
Urvang Joshifeb925f2016-12-05 10:37:29 -08001302 inv_txfm_param.tx_type =
1303 get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001304 inv_txfm_param.tx_size = tx_size;
1305 inv_txfm_param.eob = eob;
1306 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1307
Yaowu Xuf883b422016-08-30 14:01:10 -07001308#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1310 recon = CONVERT_TO_BYTEPTR(recon);
1311 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001312 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313 NULL, 0, bsw, bsh, xd->bd);
1314 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1315 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001316#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001317 {
Yushin Cho721868c2016-11-14 16:04:33 +09001318#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001319 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001321#else
1322 int i, j;
1323
1324 for (j = 0; j < bsh; j++)
1325 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
1326#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001327 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1328 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001329#if CONFIG_DAALA_DIST
1330 if (plane == 0) {
1331 if (bsw >= 8 && bsh >= 8)
1332 tmp = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, tx_size, qm,
1333 use_activity_masking, x->qindex);
1334 else
1335 tmp = 0;
1336 } else
1337#endif
1338 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001339 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001340 *out_dist = (int64_t)tmp * 16;
1341 }
1342}
1343
Yushin Cho77bba8d2016-11-04 16:36:56 -07001344#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001345static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001346 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001347 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1348 tx_size, args->scan_order->scan,
1349 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001350 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001351}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001352#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001353
1354static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1355 TX_SIZE tx_size) {
1356 uint64_t sse;
1357 switch (tx_size) {
Jingning Han2194eec2016-12-01 15:20:16 -08001358#if CONFIG_CB4X4
1359 case TX_2X2:
1360 sse = aom_sum_squares_2d_i16_c(diff, diff_stride, tx_size_wide[tx_size]);
1361 break;
1362#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001364 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1365 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001366 break;
1367 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001368 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1369 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370 break;
1371 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001372 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1373 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001374 break;
1375 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001376 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1377 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001378 break;
1379 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001380 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1381 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001382 break;
1383 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001384 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1385 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001386 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001387 default:
1388 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001389 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390 break;
1391 }
1392 return sse;
1393}
1394
1395static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1396 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1397 struct rdcost_block_args *args = arg;
1398 MACROBLOCK *const x = args->x;
1399 MACROBLOCKD *const xd = &x->e_mbd;
1400 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001401 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001403 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1404 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001405 RD_STATS this_rd_stats;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001406#if CONFIG_DAALA_DIST
1407 int qm = OD_HVS_QM;
1408 int use_activity_masking = 0;
1409#if CONFIG_PVQ
1410 use_activity_masking = x->daala_enc.use_activity_masking;
1411#endif
1412#endif
1413
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001414 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415
1416 if (args->exit_early) return;
1417
1418 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001419 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001420 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001421 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001422 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001423 &b_args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001424 if (args->cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001425 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1426 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001427 } else {
1428 // Note that the encode block_intra call above already calls
1429 // inv_txfm_add, so we can't just call dist_block here.
1430 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001431 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432 const struct macroblock_plane *const p = &x->plane[plane];
1433 const struct macroblockd_plane *const pd = &xd->plane[plane];
1434
1435 const int src_stride = p->src.stride;
1436 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001437 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001438
Jingning Han81492262016-12-05 15:48:47 -08001439 const uint8_t *src =
1440 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1441 const uint8_t *dst =
1442 &pd->dst
1443 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1444 const int16_t *diff = &p->src_diff[(blk_row * diff_stride + blk_col)
1445 << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001446 unsigned int tmp;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001447
1448#if CONFIG_DAALA_DIST
1449 if (plane == 0) {
1450 const int bsw = block_size_wide[tx_bsize];
1451 const int bsh = block_size_high[tx_bsize];
1452
1453 if (bsw >= 8 && bsh >= 8) {
1454 const int16_t *pred = &pd->pred[(blk_row * diff_stride + blk_col)
1455 << tx_size_wide_log2[0]];
1456 int i, j;
1457 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1458
1459 for (j = 0; j < bsh; j++)
1460 for (i = 0; i < bsw; i++)
1461 pred8[j * bsw + i] = pred[j * diff_stride + i];
1462
1463 this_rd_stats.sse =
1464 av1_daala_dist(src, src_stride, pred8, bsw, tx_size, qm,
1465 use_activity_masking, x->qindex);
1466 } else {
1467 this_rd_stats.sse = 0;
1468 }
1469 } else
1470#endif
1471 {
1472 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001473
Yaowu Xuf883b422016-08-30 14:01:10 -07001474#if CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001475 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1476 this_rd_stats.sse =
1477 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001478#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001479 }
1480
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001481 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482
Yushin Cho7a428ba2017-01-12 16:28:49 -08001483#if CONFIG_DAALA_DIST
1484 if (plane == 0) {
1485 const int bsw = block_size_wide[tx_bsize];
1486 const int bsh = block_size_high[tx_bsize];
1487
1488 if (bsw >= 8 && bsh >= 8)
1489 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1490 use_activity_masking, x->qindex);
1491 else
1492 tmp = 0;
1493 } else
1494#endif
1495 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001496 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497 }
1498 } else {
1499// full forward transform and quantization
1500#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001501 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1502 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001503#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001504 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001505 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001506#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001507#if !CONFIG_PVQ
Yaowu Xufd873802016-12-12 09:37:54 -08001508 if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id]) {
1509 args->t_above[blk_col] = args->t_left[blk_row] =
1510 (av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx) > 0);
1511 } else {
1512 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1513 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1514 }
Yushin Cho721868c2016-11-14 16:04:33 +09001515#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001516 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1517 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518 }
1519
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001520 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521 if (args->this_rd + rd > args->best_rd) {
1522 args->exit_early = 1;
1523 return;
1524 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001525#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001526 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001527#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001528 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1529 this_rd_stats.rate);
1530#endif
Angie Chiang3963d632016-11-10 18:41:40 -08001531
Yushin Cho77bba8d2016-11-04 16:36:56 -07001532#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001533 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001534 args->t_above[blk_col] = !x->pvq_skip[plane];
1535 args->t_left[blk_row] = !x->pvq_skip[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001536#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001537 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1538 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001539
1540 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001541 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542
Yushin Cho7a428ba2017-01-12 16:28:49 -08001543#if CONFIG_DAALA_DIST
1544 if (plane == 0 && tx_size <= TX_4X4) {
1545 rd = 0;
1546 x->rate_4x4[block] = this_rd_stats.rate;
1547 }
1548#endif
1549
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001550#if !CONFIG_PVQ
1551 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1552#else
1553 this_rd_stats.skip &= x->pvq_skip[plane];
1554#endif
1555 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001556
Yaowu Xuc27fc142016-08-22 16:08:15 -07001557 args->this_rd += rd;
1558
1559 if (args->this_rd > args->best_rd) {
1560 args->exit_early = 1;
1561 return;
1562 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001563}
1564
Yushin Cho7a428ba2017-01-12 16:28:49 -08001565#if CONFIG_DAALA_DIST
1566static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
1567 int blk_col, BLOCK_SIZE plane_bsize,
1568 TX_SIZE tx_size, void *arg) {
1569 struct rdcost_block_args *args = arg;
1570 MACROBLOCK *const x = args->x;
1571 MACROBLOCKD *const xd = &x->e_mbd;
1572 // MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1573 // const AV1_COMMON *cm = &args->cpi->common;
1574 int64_t rd1, rd2, rd;
1575 RD_STATS this_rd_stats;
1576 int qm = OD_HVS_QM;
1577 int use_activity_masking = 0;
1578
1579#if CONFIG_PVQ
1580 use_activity_masking = x->daala_enc.use_activity_masking;
1581#endif
1582 av1_init_rd_stats(&this_rd_stats);
1583
1584 if (args->exit_early) return;
1585
1586 {
1587 const struct macroblock_plane *const p = &x->plane[plane];
1588 const struct macroblockd_plane *const pd = &xd->plane[plane];
1589
1590 const int src_stride = p->src.stride;
1591 const int dst_stride = pd->dst.stride;
1592 const int diff_stride = block_size_wide[plane_bsize];
1593
1594 const uint8_t *src =
1595 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1596 const uint8_t *dst =
1597 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1598
1599 unsigned int tmp;
1600
1601 int qindex = x->qindex;
1602
1603 const int16_t *pred =
1604 &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
1605 int i, j;
1606 const int tx_blk_size = 1 << (tx_size + 2);
1607 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1608
1609 for (j = 0; j < tx_blk_size; j++)
1610 for (i = 0; i < tx_blk_size; i++)
1611 pred8[j * tx_blk_size + i] = pred[j * diff_stride + i];
1612
1613 this_rd_stats.sse =
1614 av1_daala_dist(src, src_stride, pred8, tx_blk_size, tx_size, qm,
1615 use_activity_masking, qindex);
1616
1617 this_rd_stats.sse = this_rd_stats.sse * 16;
1618
1619 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1620 use_activity_masking, qindex);
1621
1622 this_rd_stats.dist = (int64_t)tmp * 16;
1623 }
1624
1625 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
1626 if (args->this_rd + rd > args->best_rd) {
1627 args->exit_early = 1;
1628 return;
1629 }
1630
1631 {
1632 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
1633 // The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
1634 this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
1635 x->rate_4x4[block - max_blocks_wide] +
1636 x->rate_4x4[block - 1] + x->rate_4x4[block];
1637 }
1638 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1639 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
1640
1641 rd = AOMMIN(rd1, rd2);
1642
1643 args->rd_stats.dist += this_rd_stats.dist;
1644 args->rd_stats.sse += this_rd_stats.sse;
1645
1646 args->this_rd += rd;
1647
1648 if (args->this_rd > args->best_rd) {
1649 args->exit_early = 1;
1650 return;
1651 }
1652}
1653#endif // #if CONFIG_DAALA_DIST
1654
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001655static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1656 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1657 BLOCK_SIZE bsize, TX_SIZE tx_size,
1658 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001659 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001660 MACROBLOCKD *const xd = &x->e_mbd;
1661 const struct macroblockd_plane *const pd = &xd->plane[plane];
1662 TX_TYPE tx_type;
1663 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001664 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001665 args.x = x;
1666 args.cpi = cpi;
1667 args.best_rd = ref_best_rd;
1668 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001669 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001670
1671 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1672
Yaowu Xuf883b422016-08-30 14:01:10 -07001673 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001674
1675 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001676 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001677 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001678
Yushin Cho7a428ba2017-01-12 16:28:49 -08001679#if CONFIG_DAALA_DIST
1680 if (plane == 0 &&
1681 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
1682 av1_foreach_8x8_transformed_block_in_plane(
1683 xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
1684 else
1685#endif
1686 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1687 &args);
1688
Yaowu Xuc27fc142016-08-22 16:08:15 -07001689 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001690 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001691 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001692 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001693 }
1694}
1695
1696#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001697void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1698 int64_t *distortion, int *skippable,
1699 int64_t *sse, int64_t ref_best_rd, int plane,
1700 BLOCK_SIZE bsize, TX_SIZE tx_size,
1701 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001702 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001703 MACROBLOCKD *const xd = &x->e_mbd;
1704 const struct macroblockd_plane *const pd = &xd->plane[plane];
1705 struct rdcost_block_args args;
1706 TX_TYPE tx_type;
1707
Yaowu Xuf883b422016-08-30 14:01:10 -07001708 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001709 args.cpi = cpi;
1710 args.x = x;
1711 args.best_rd = ref_best_rd;
1712 args.use_fast_coef_costing = use_fast_coef_casting;
1713
1714#if CONFIG_EXT_TX
1715 assert(tx_size < TX_SIZES);
1716#endif // CONFIG_EXT_TX
1717
1718 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1719
Yaowu Xuf883b422016-08-30 14:01:10 -07001720 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001721
1722 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001723 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001724 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001725
1726 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1727 &args);
1728
1729 if (args.exit_early) {
1730 *rate = INT_MAX;
1731 *distortion = INT64_MAX;
1732 *sse = INT64_MAX;
1733 *skippable = 0;
1734 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001735 *distortion = args.rd_stats.dist;
1736 *rate = args.rd_stats.rate;
1737 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001738 *skippable = !x->plane[plane].eobs[0];
1739 }
1740}
1741#endif // CONFIG_SUPERTX
1742
Urvang Joshifeb925f2016-12-05 10:37:29 -08001743static int tx_size_cost(const AV1_COMP *const cpi, MACROBLOCK *x,
1744 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1745 const AV1_COMMON *const cm = &cpi->common;
1746 MACROBLOCKD *const xd = &x->e_mbd;
1747 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1748
1749 const int tx_select =
1750 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1751
1752 if (tx_select) {
1753 const int is_inter = is_inter_block(mbmi);
1754 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1755 : intra_tx_size_cat_lookup[bsize];
1756 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1757 const int depth = tx_size_to_depth(coded_tx_size);
1758 const int tx_size_ctx = get_tx_size_context(xd);
1759 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1760 return r_tx_size;
1761 } else {
1762 return 0;
1763 }
1764}
1765
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001766static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1767 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1768 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001769 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001770 MACROBLOCKD *const xd = &x->e_mbd;
1771 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1772 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001773 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001774 int s0, s1;
1775 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001776 const int tx_select =
1777 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001778
1779 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780
1781 assert(skip_prob > 0);
1782#if CONFIG_EXT_TX && CONFIG_RECT_TX
1783 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1784#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1785
Yaowu Xuf883b422016-08-30 14:01:10 -07001786 s0 = av1_cost_bit(skip_prob, 0);
1787 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001788
1789 mbmi->tx_type = tx_type;
1790 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001791 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001793 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001794#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001795 if (get_ext_tx_types(tx_size, bs, is_inter, cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08001797 const int ext_tx_set =
1798 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001799 if (is_inter) {
1800 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001801 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001802 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1803 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001804 } else {
1805 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Urvang Joshifeb925f2016-12-05 10:37:29 -08001806 rd_stats->rate +=
1807 cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1808 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001809 }
1810 }
1811#else
1812 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1813 !FIXED_TX_TYPE) {
1814 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001815 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001817 rd_stats->rate +=
1818 cpi->intra_tx_type_costs[mbmi->tx_size]
1819 [intra_mode_to_tx_type_context[mbmi->mode]]
1820 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001821 }
1822 }
1823#endif // CONFIG_EXT_TX
1824
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001825 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001826 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001827 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001829 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1830 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001831 }
1832 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001833 rd = RDCOST(x->rdmult, x->rddiv,
1834 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835 }
1836
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001837 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001838
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001839 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1840 !(rd_stats->skip))
1841 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842
1843 return rd;
1844}
1845
Urvang Joshi52648442016-10-13 17:27:51 -07001846static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001847 MACROBLOCK *x, RD_STATS *rd_stats,
1848 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001849#if CONFIG_PVQ
1850 od_rollback_buffer buf,
1851#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001852 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001853 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001854 MACROBLOCKD *const xd = &x->e_mbd;
1855 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001856 int64_t rd = INT64_MAX;
1857 int n;
1858 int start_tx, end_tx;
1859 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1860 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1861 TX_SIZE best_tx_size = max_tx_size;
1862 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1863 const int is_inter = is_inter_block(mbmi);
1864#if CONFIG_EXT_TX
1865#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001866 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001867#endif // CONFIG_RECT_TX
1868 int ext_tx_set;
1869#endif // CONFIG_EXT_TX
1870
1871 if (tx_select) {
1872#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001873 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001874#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1875 start_tx = max_tx_size;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001876 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877 } else {
1878 const TX_SIZE chosen_tx_size =
1879 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1880#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001881 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1882 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1884 start_tx = chosen_tx_size;
1885 end_tx = chosen_tx_size;
1886 }
1887
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001888 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889
1890 mbmi->tx_type = tx_type;
1891
1892#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001893 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001894 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001895 RD_STATS this_rd_stats;
Sarah Parkere68a3e42017-02-16 14:03:24 -08001896 ext_tx_set =
1897 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08001898 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
1899 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001900 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001901 rect_tx_size);
1902 best_tx_size = rect_tx_size;
1903 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001904 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905 }
1906 }
1907#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1908
1909 last_rd = INT64_MAX;
1910 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001911 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912#if CONFIG_EXT_TX && CONFIG_RECT_TX
1913 if (is_rect_tx(n)) break;
1914#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1915 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1916 if (!is_inter && x->use_default_intra_tx_type &&
1917 tx_type != get_default_tx_type(0, xd, 0, n))
1918 continue;
1919 if (is_inter && x->use_default_inter_tx_type &&
1920 tx_type != get_default_tx_type(0, xd, 0, n))
1921 continue;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001922 if (max_tx_size >= TX_32X32 && n == TX_4X4) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001923#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001924 ext_tx_set = get_ext_tx_set(n, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001925 if (is_inter) {
1926 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1927 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1928 if (!do_tx_type_search(tx_type, prune)) continue;
1929 }
1930 } else {
1931 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1932 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1933 }
1934 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1935 }
1936#else // CONFIG_EXT_TX
1937 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1938 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1939 !do_tx_type_search(tx_type, prune))
1940 continue;
1941#endif // CONFIG_EXT_TX
1942
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001943 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001944#if CONFIG_PVQ
1945 od_encode_rollback(&x->daala_enc, &buf);
1946#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001947 // Early termination in transform size search.
1948 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001949 (rd == INT64_MAX ||
1950 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001951 (n < (int)max_tx_size && rd > last_rd)))
1952 break;
1953
1954 last_rd = rd;
1955 if (rd < best_rd) {
1956 best_tx_size = n;
1957 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001958 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001959 }
1960 }
1961 mbmi->tx_size = best_tx_size;
1962
1963 return best_rd;
1964}
1965
1966#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001967static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1968 MACROBLOCK *x, int *r, int64_t *d, int *s,
1969 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001970 RD_STATS rd_stats;
1971 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1972 max_txsize_lookup[bs]);
1973 *r = rd_stats.rate;
1974 *d = rd_stats.dist;
1975 *s = rd_stats.skip;
1976 *sse = rd_stats.sse;
1977 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001978}
1979#endif // CONFIG_EXT_INTER
1980
Urvang Joshi52648442016-10-13 17:27:51 -07001981static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001982 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001983 BLOCK_SIZE bs) {
1984 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985 MACROBLOCKD *const xd = &x->e_mbd;
1986 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1987 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001988 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001989 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1990 int s0 = av1_cost_bit(skip_prob, 0);
1991 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001992 const int is_inter = is_inter_block(mbmi);
1993 int prune = 0;
1994#if CONFIG_EXT_TX
1995 int ext_tx_set;
1996#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001997 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001998
1999 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002000#if CONFIG_VAR_TX
2001 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
2002#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002003#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002004 ext_tx_set =
2005 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006#endif // CONFIG_EXT_TX
2007
2008 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2009#if CONFIG_EXT_TX
2010 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2011#else
2012 prune = prune_tx_types(cpi, bs, x, xd, 0);
2013#endif
2014#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002015 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2016 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002017 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002018#if CONFIG_PVQ
2019 od_rollback_buffer pre_buf, post_buf;
2020
2021 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2022 od_encode_checkpoint(&x->daala_enc, &post_buf);
2023#endif
2024
2025 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002026 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002027 if (is_inter) {
2028 if (x->use_default_inter_tx_type &&
2029 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2030 continue;
2031 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2032 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2033 if (!do_tx_type_search(tx_type, prune)) continue;
2034 }
2035 } else {
2036 if (x->use_default_intra_tx_type &&
2037 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2038 continue;
2039 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2040 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2041 }
2042 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2043 }
2044
2045 mbmi->tx_type = tx_type;
2046
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002047 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002048 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002049#if CONFIG_PVQ
2050 od_encode_rollback(&x->daala_enc, &pre_buf);
2051#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002052 if (this_rd_stats.rate == INT_MAX) continue;
Sarah Parkere68a3e42017-02-16 14:03:24 -08002053 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter,
2054 cm->reduced_tx_set_used) > 1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055 if (is_inter) {
2056 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002057 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002058 cpi->inter_tx_type_costs[ext_tx_set]
2059 [txsize_sqr_map[mbmi->tx_size]]
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002060 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061 } else {
2062 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002063 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002064 cpi->intra_tx_type_costs[ext_tx_set]
2065 [txsize_sqr_map[mbmi->tx_size]]
2066 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002067 }
2068 }
2069
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002070 if (this_rd_stats.skip)
2071 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002072 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002073 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2074 this_rd_stats.dist);
2075 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2076 !this_rd_stats.skip)
2077 this_rd =
2078 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002079
2080 if (this_rd < best_rd) {
2081 best_rd = this_rd;
2082 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002083 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002084#if CONFIG_PVQ
2085 od_encode_checkpoint(&x->daala_enc, &post_buf);
2086#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002087 }
2088 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002089#if CONFIG_PVQ
2090 od_encode_rollback(&x->daala_enc, &post_buf);
2091#endif
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002092 } else {
2093 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002094 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2095 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002096 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002097#else // CONFIG_EXT_TX
2098 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2099 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002100 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101 if (!is_inter && x->use_default_intra_tx_type &&
2102 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2103 continue;
2104 if (is_inter && x->use_default_inter_tx_type &&
2105 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2106 continue;
2107 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002108 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002110 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002111 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002112 this_rd_stats.rate +=
2113 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002114 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2115 !do_tx_type_search(tx_type, prune))
2116 continue;
2117 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002118 this_rd_stats.rate +=
2119 cpi->intra_tx_type_costs[mbmi->tx_size]
2120 [intra_mode_to_tx_type_context[mbmi->mode]]
2121 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002122 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002123 if (this_rd_stats.skip)
2124 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002125 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002126 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2127 this_rd_stats.dist);
2128 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2129 this_rd =
2130 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002131
2132 if (this_rd < best_rd) {
2133 best_rd = this_rd;
2134 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002135 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002136 }
2137 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002138 } else {
2139 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002140 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2141 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002142 }
2143#endif // CONFIG_EXT_TX
2144 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145}
2146
Urvang Joshi52648442016-10-13 17:27:51 -07002147static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002148 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002149 BLOCK_SIZE bs) {
2150 MACROBLOCKD *const xd = &x->e_mbd;
2151 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2152
2153 mbmi->tx_size = TX_4X4;
2154 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002155#if CONFIG_VAR_TX
2156 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
2157#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002158
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002159 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2160 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002161}
2162
Urvang Joshi52648442016-10-13 17:27:51 -07002163static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002164 MACROBLOCK *x, RD_STATS *rd_stats,
2165 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002166 MACROBLOCKD *const xd = &x->e_mbd;
2167 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002168 int64_t rd = INT64_MAX;
2169 int64_t best_rd = INT64_MAX;
2170 TX_SIZE best_tx = max_txsize_lookup[bs];
2171 const int is_inter = is_inter_block(mbmi);
2172 TX_TYPE tx_type, best_tx_type = DCT_DCT;
2173 int prune = 0;
2174
Yushin Cho77bba8d2016-11-04 16:36:56 -07002175#if CONFIG_PVQ
2176 od_rollback_buffer buf;
2177#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002178 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2179 // passing -1 in for tx_type indicates that all 1D
2180 // transforms should be considered for pruning
2181 prune = prune_tx_types(cpi, bs, x, xd, -1);
2182
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002183 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002184
Yushin Cho77bba8d2016-11-04 16:36:56 -07002185#if CONFIG_PVQ
2186 od_encode_checkpoint(&x->daala_enc, &buf);
2187#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002188 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002189 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002190#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07002191 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002192#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002193 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08002194 tx_type,
2195#if CONFIG_PVQ
2196 buf,
2197#endif
2198 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002199 if (rd < best_rd) {
2200 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002201 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002202 best_tx_type = tx_type;
2203 best_tx = mbmi->tx_size;
2204 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002205#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2206 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2207#endif // USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07002208 }
2209
2210 mbmi->tx_size = best_tx;
2211 mbmi->tx_type = best_tx_type;
2212
Jingning Hane67b38a2016-11-04 10:30:00 -07002213#if CONFIG_VAR_TX
2214 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
2215#endif
2216
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217#if !CONFIG_EXT_TX
2218 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
2219#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002220#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002221 if (best_rd != INT64_MAX) {
Guillaume Martres930118c2016-12-06 20:26:22 -10002222 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx);
Yushin Cho05f540a2016-11-08 22:12:51 -08002223 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002224#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002225}
2226
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002227static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2228 RD_STATS *rd_stats, BLOCK_SIZE bs,
2229 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002230 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002231 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232
2233 assert(bs == xd->mi[0]->mbmi.sb_type);
2234
Yunqing Wang2615d6e2016-12-16 21:23:50 -08002235 if (xd->lossless[0]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002236 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002237 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002238 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002239 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002240 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002241 }
2242}
2243
2244static int conditional_skipintra(PREDICTION_MODE mode,
2245 PREDICTION_MODE best_intra_mode) {
2246 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2247 best_intra_mode != D135_PRED)
2248 return 1;
2249 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2250 best_intra_mode != D45_PRED)
2251 return 1;
2252 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2253 best_intra_mode != D45_PRED)
2254 return 1;
2255 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2256 best_intra_mode != D135_PRED)
2257 return 1;
2258 return 0;
2259}
2260
hui su308a6392017-01-12 14:49:57 -08002261// Model based RD estimation for luma intra blocks.
2262static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002263 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002264 MACROBLOCKD *const xd = &x->e_mbd;
2265 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2266 RD_STATS this_rd_stats;
2267 int row, col;
2268 int64_t temp_sse, this_rd;
2269 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2270 const int stepr = tx_size_high_unit[tx_size];
2271 const int stepc = tx_size_wide_unit[tx_size];
2272 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2273 const int max_blocks_high = max_block_high(xd, bsize, 0);
2274 mbmi->tx_size = tx_size;
2275 // Prediction.
2276 for (row = 0; row < max_blocks_high; row += stepr) {
2277 for (col = 0; col < max_blocks_wide; col += stepc) {
2278 struct macroblockd_plane *const pd = &xd->plane[0];
2279 uint8_t *dst =
2280 &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
David Barker839467f2017-01-19 11:06:15 +00002281 av1_predict_intra_block(xd, pd->width, pd->height,
2282 txsize_to_bsize[tx_size], mbmi->mode, dst,
2283 pd->dst.stride, dst, pd->dst.stride, col, row, 0);
hui su308a6392017-01-12 14:49:57 -08002284 }
2285 }
2286 // RD estimation.
2287 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2288 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002289#if CONFIG_EXT_INTRA
2290 if (av1_is_directional_mode(mbmi->mode, bsize)) {
2291 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
2292 mode_cost += write_uniform_cost(2 * max_angle_delta + 1,
2293 max_angle_delta + mbmi->angle_delta[0]);
2294 }
2295#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002296#if CONFIG_FILTER_INTRA
2297 if (mbmi->mode == DC_PRED) {
2298 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2299 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2300 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2301 mode_cost += (av1_cost_bit(prob, 1) +
2302 write_uniform_cost(FILTER_INTRA_MODES, mode));
2303 } else {
2304 mode_cost += av1_cost_bit(prob, 0);
2305 }
2306 }
2307#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002308 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2309 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002310 return this_rd;
2311}
2312
Urvang Joshib100db72016-10-12 16:28:56 -07002313#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002314// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2315// new_height'. Extra rows and columns are filled in by copying last valid
2316// row/column.
2317static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2318 int orig_height, int new_width,
2319 int new_height) {
2320 int j;
2321 assert(new_width >= orig_width);
2322 assert(new_height >= orig_height);
2323 if (new_width == orig_width && new_height == orig_height) return;
2324
2325 for (j = orig_height - 1; j >= 0; --j) {
2326 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2327 // Copy last column to extra columns.
2328 memset(color_map + j * new_width + orig_width,
2329 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2330 }
2331 // Copy last row to extra rows.
2332 for (j = orig_height; j < new_height; ++j) {
2333 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2334 new_width);
2335 }
2336}
2337
hui sude0c70a2017-01-09 17:12:17 -08002338static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2339 BLOCK_SIZE bsize, int palette_ctx,
2340 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2341 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002342 int64_t *best_rd, int64_t *best_model_rd,
2343 int *rate, int *rate_tokenonly,
2344 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002345 int rate_overhead = 0;
2346 MACROBLOCKD *const xd = &x->e_mbd;
2347 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002348 MB_MODE_INFO *const mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002349 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002350 const int src_stride = x->plane[0].src.stride;
2351 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002352 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002353 int block_width, block_height, rows, cols;
2354 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2355 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002356
2357 assert(cpi->common.allow_screen_content_tools);
2358
Yaowu Xuf883b422016-08-30 14:01:10 -07002359#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002360 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002361 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2362 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002363 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002364#endif // CONFIG_AOM_HIGHBITDEPTH
2365 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002366#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002367 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002368#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002369
2370 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002371 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002372 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002373 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002374 float *const data = x->palette_buffer->kmeans_data_buf;
2375 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002376 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002377 RD_STATS tokenonly_rd_stats;
2378 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002379 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07002380#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002381 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2382 if (cpi->common.use_highbitdepth)
2383 lb = ub = src16[0];
2384 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002385#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002386 lb = ub = src[0];
2387
Yaowu Xuf883b422016-08-30 14:01:10 -07002388#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002389 if (cpi->common.use_highbitdepth) {
2390 for (r = 0; r < rows; ++r) {
2391 for (c = 0; c < cols; ++c) {
2392 val = src16[r * src_stride + c];
2393 data[r * cols + c] = val;
2394 if (val < lb)
2395 lb = val;
2396 else if (val > ub)
2397 ub = val;
2398 }
2399 }
2400 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002401#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002402 for (r = 0; r < rows; ++r) {
2403 for (c = 0; c < cols; ++c) {
2404 val = src[r * src_stride + c];
2405 data[r * cols + c] = val;
2406 if (val < lb)
2407 lb = val;
2408 else if (val > ub)
2409 ub = val;
2410 }
2411 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002412#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002414#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002415
2416 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002417#if CONFIG_FILTER_INTRA
2418 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2419#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002420
2421 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2422
2423 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2424 --n) {
2425 for (i = 0; i < n; ++i)
2426 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07002427 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
2428 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002429
Yaowu Xuf883b422016-08-30 14:01:10 -07002430#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 if (cpi->common.use_highbitdepth)
2432 for (i = 0; i < k; ++i)
2433 pmi->palette_colors[i] =
2434 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2435 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002436#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002437 for (i = 0; i < k; ++i)
2438 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2439 pmi->palette_size[0] = k;
2440
Yaowu Xuf883b422016-08-30 14:01:10 -07002441 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002442 extend_palette_color_map(color_map, cols, rows, block_width,
2443 block_height);
hui su78c611a2017-01-13 17:06:04 -08002444 palette_mode_cost =
2445 dc_mode_cost + cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08002446 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002447 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002448 av1_cost_bit(
2449 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450 1);
2451 for (i = 0; i < rows; ++i) {
2452 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002453 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002454 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002455 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002456 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002457 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2458 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002459 }
2460 }
hui su78c611a2017-01-13 17:06:04 -08002461 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2462 if (*best_model_rd != INT64_MAX &&
2463 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2464 continue;
2465 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2466 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2467 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2468 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002469 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002470 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002471 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002472 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002473 if (this_rd < *best_rd) {
2474 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002476 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002477 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002478 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002479 if (rate) *rate = this_rate;
2480 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2481 if (distortion) *distortion = tokenonly_rd_stats.dist;
2482 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002483 }
2484 }
2485 }
hui sude0c70a2017-01-09 17:12:17 -08002486
2487 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2488 memcpy(color_map, best_palette_color_map,
2489 rows * cols * sizeof(best_palette_color_map[0]));
2490 }
2491 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002492 return rate_overhead;
2493}
Urvang Joshib100db72016-10-12 16:28:56 -07002494#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002495
Urvang Joshifeb925f2016-12-05 10:37:29 -08002496// Wrappers to make function pointers usable.
2497static void inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2498 int stride, int eob, TX_TYPE tx_type,
2499 int lossless) {
2500 (void)lossless;
2501 av1_inv_txfm_add_4x8(input, dest, stride, eob, tx_type);
2502}
2503
2504static void inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2505 int stride, int eob, TX_TYPE tx_type,
2506 int lossless) {
2507 (void)lossless;
2508 av1_inv_txfm_add_8x4(input, dest, stride, eob, tx_type);
2509}
2510
2511typedef void (*inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int, int,
2512 TX_TYPE, int);
2513#if CONFIG_AOM_HIGHBITDEPTH
2514
2515void highbd_inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2516 int stride, int eob, int bd,
2517 TX_TYPE tx_type, int is_lossless) {
2518 (void)is_lossless;
2519 av1_highbd_inv_txfm_add_4x8(input, dest, stride, eob, bd, tx_type);
2520}
2521
2522void highbd_inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2523 int stride, int eob, int bd,
2524 TX_TYPE tx_type, int is_lossless) {
2525 (void)is_lossless;
2526 av1_highbd_inv_txfm_add_8x4(input, dest, stride, eob, bd, tx_type);
2527}
2528
2529typedef void (*highbd_inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int,
2530 int, int, TX_TYPE, int);
2531#endif // CONFIG_AOM_HIGHBITDEPTH
2532
2533static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002534 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2535 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2536 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002537 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002538 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002539 PREDICTION_MODE mode;
2540 MACROBLOCKD *const xd = &x->e_mbd;
2541 int64_t best_rd = rd_thresh;
2542 struct macroblock_plane *p = &x->plane[0];
2543 struct macroblockd_plane *pd = &xd->plane[0];
2544 const int src_stride = p->src.stride;
2545 const int dst_stride = pd->dst.stride;
2546 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002547 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002548#if CONFIG_CB4X4
2549 // TODO(jingning): This is a temporal change. The whole function should be
2550 // out when cb4x4 is enabled.
2551 ENTROPY_CONTEXT ta[4], tempa[4];
2552 ENTROPY_CONTEXT tl[4], templ[4];
2553#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002554 ENTROPY_CONTEXT ta[2], tempa[2];
2555 ENTROPY_CONTEXT tl[2], templ[2];
Jingning Han276c2942016-12-05 12:37:02 -08002556#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002557
2558 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2559 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2560 const int tx_width_unit = tx_size_wide_unit[tx_size];
2561 const int tx_height_unit = tx_size_high_unit[tx_size];
2562 const int pred_block_width = block_size_wide[bsize];
2563 const int pred_block_height = block_size_high[bsize];
2564 const int tx_width = tx_size_wide[tx_size];
2565 const int tx_height = tx_size_high[tx_size];
2566 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2567 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002568 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002569 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570 uint8_t best_dst[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002571 inv_txfm_func_ptr inv_txfm_func =
2572 (tx_size == TX_4X4) ? av1_inv_txfm_add_4x4
2573 : (tx_size == TX_4X8) ? inv_txfm_add_4x8_wrapper
2574 : inv_txfm_add_8x4_wrapper;
Yaowu Xuf883b422016-08-30 14:01:10 -07002575#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002576 uint16_t best_dst16[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002577 highbd_inv_txfm_func_ptr highbd_inv_txfm_func =
2578 (tx_size == TX_4X4)
2579 ? av1_highbd_inv_txfm_add_4x4
2580 : (tx_size == TX_4X8) ? highbd_inv_txfm_add_4x8_wrapper
2581 : highbd_inv_txfm_add_8x4_wrapper;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002582#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002583 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2584#if CONFIG_EXT_TX && CONFIG_RECT_TX
2585 const int sub_bsize = bsize;
2586#else
2587 const int sub_bsize = BLOCK_4X4;
2588#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002589
Yushin Cho77bba8d2016-11-04 16:36:56 -07002590#if CONFIG_PVQ
2591 od_rollback_buffer pre_buf, post_buf;
2592 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2593 od_encode_checkpoint(&x->daala_enc, &post_buf);
2594#endif
2595
Urvang Joshifeb925f2016-12-05 10:37:29 -08002596 assert(bsize < BLOCK_8X8);
2597 assert(tx_width < 8 || tx_height < 8);
2598#if CONFIG_EXT_TX && CONFIG_RECT_TX
2599 assert(tx_width == pred_block_width && tx_height == pred_block_height);
2600#else
2601 assert(tx_width == 4 && tx_height == 4);
2602#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2603
2604 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2605 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2606
2607 xd->mi[0]->mbmi.tx_size = tx_size;
2608
Urvang Joshib100db72016-10-12 16:28:56 -07002609#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002610 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002611#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002612
Yaowu Xuf883b422016-08-30 14:01:10 -07002613#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002614 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2615 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2616 int64_t this_rd;
2617 int ratey = 0;
2618 int64_t distortion = 0;
2619 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002620 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002621
Urvang Joshifeb925f2016-12-05 10:37:29 -08002622 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2623 (1 << mode)))
2624 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002625
2626 // Only do the oblique modes if the best so far is
2627 // one of the neighboring directional modes
2628 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2629 if (conditional_skipintra(mode, *best_mode)) continue;
2630 }
2631
Urvang Joshifeb925f2016-12-05 10:37:29 -08002632 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2633 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634
Urvang Joshifeb925f2016-12-05 10:37:29 -08002635 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2636 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2637 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2638 const int block =
2639 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002640 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2641 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002642 int16_t *const src_diff = av1_raster_block_offset_int16(
2643 BLOCK_8X8, block_raster_idx, p->src_diff);
2644 int skip;
2645 assert(block < 4);
2646 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2647 idx == 0 && idy == 0));
2648 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2649 block == 0 || block == 2));
2650 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002651 av1_predict_intra_block(
2652 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2653 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002654 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2655 src_stride, dst, dst_stride, xd->bd);
2656 if (is_lossless) {
2657 TX_TYPE tx_type =
2658 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2659 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002660 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002661 combine_entropy_contexts(tempa[idx], templ[idy]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002662#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002663 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002664 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002665#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002666 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002667 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002668#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002669 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002670 scan_order->scan, scan_order->neighbors,
2671 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002672 skip = (p->eobs[block] == 0);
2673 can_skip &= skip;
2674 tempa[idx] = !skip;
2675 templ[idy] = !skip;
2676#if CONFIG_EXT_TX
2677 if (tx_size == TX_8X4) {
2678 tempa[idx + 1] = tempa[idx];
2679 } else if (tx_size == TX_4X8) {
2680 templ[idy + 1] = templ[idy];
2681 }
2682#endif // CONFIG_EXT_TX
2683
Yaowu Xuc27fc142016-08-22 16:08:15 -07002684 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2685 goto next_highbd;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002686 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2687 dst_stride, p->eobs[block], xd->bd, DCT_DCT,
2688 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002689 } else {
2690 int64_t dist;
2691 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002692 TX_TYPE tx_type =
2693 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2694 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002695 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002696 combine_entropy_contexts(tempa[idx], templ[idy]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002697#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002698 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002699 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002700#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002701 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002702 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002703#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002704 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
2705 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002706 scan_order->scan, scan_order->neighbors,
2707 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002708 skip = (p->eobs[block] == 0);
2709 can_skip &= skip;
2710 tempa[idx] = !skip;
2711 templ[idy] = !skip;
2712#if CONFIG_EXT_TX
2713 if (tx_size == TX_8X4) {
2714 tempa[idx + 1] = tempa[idx];
2715 } else if (tx_size == TX_4X8) {
2716 templ[idy + 1] = templ[idy];
2717 }
2718#endif // CONFIG_EXT_TX
2719 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2720 dst_stride, p->eobs[block], xd->bd, tx_type,
2721 0);
2722 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002723 dist = (int64_t)tmp << 4;
2724 distortion += dist;
2725 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2726 goto next_highbd;
2727 }
2728 }
2729 }
2730
2731 rate += ratey;
2732 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2733
2734 if (this_rd < best_rd) {
2735 *bestrate = rate;
2736 *bestratey = ratey;
2737 *bestdistortion = distortion;
2738 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002739 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002740 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002741 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2742 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
2743 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002744 memcpy(best_dst16 + idy * 8,
2745 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002746 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747 }
2748 }
2749 next_highbd : {}
2750 }
2751
2752 if (best_rd >= rd_thresh) return best_rd;
2753
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002754 if (y_skip) *y_skip &= best_can_skip;
2755
Urvang Joshifeb925f2016-12-05 10:37:29 -08002756 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002758 best_dst16 + idy * 8,
2759 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760 }
2761
2762 return best_rd;
2763 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002764#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002765
Yushin Cho77bba8d2016-11-04 16:36:56 -07002766#if CONFIG_PVQ
2767 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2768#endif
2769
Yaowu Xuc27fc142016-08-22 16:08:15 -07002770 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2771 int64_t this_rd;
2772 int ratey = 0;
2773 int64_t distortion = 0;
2774 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002775 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002776
Urvang Joshifeb925f2016-12-05 10:37:29 -08002777 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2778 (1 << mode))) {
2779 continue;
2780 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002781
2782 // Only do the oblique modes if the best so far is
2783 // one of the neighboring directional modes
2784 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2785 if (conditional_skipintra(mode, *best_mode)) continue;
2786 }
2787
Urvang Joshifeb925f2016-12-05 10:37:29 -08002788 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2789 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790
Urvang Joshifeb925f2016-12-05 10:37:29 -08002791 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2792 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2793 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2794 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002795 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2796 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002797#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002798 int16_t *const src_diff = av1_raster_block_offset_int16(
2799 BLOCK_8X8, block_raster_idx, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002800#else
Urvang Joshifeb925f2016-12-05 10:37:29 -08002801 int i, j;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002802#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002803 int skip;
2804 assert(block < 4);
2805 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2806 idx == 0 && idy == 0));
2807 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2808 block == 0 || block == 2));
2809 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002810 av1_predict_intra_block(xd, pd->width, pd->height,
2811 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2812 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002813#if CONFIG_CB4X4
2814 2 * (col + idx), 2 * (row + idy),
2815#else
2816 col + idx, row + idy,
2817#endif
2818 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002819#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002820 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2821 dst, dst_stride);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002822#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002823
Urvang Joshifeb925f2016-12-05 10:37:29 -08002824 if (is_lossless) {
2825 TX_TYPE tx_type =
2826 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2827 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002828 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002829 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002830#if CONFIG_CB4X4
2831 block = 4 * block;
2832#endif
Yushin Cho900243b2017-01-03 11:02:38 -08002833#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002834#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002835 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002836 tx_size, coeff_ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002837#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002838 av1_xform_quant(cm, x, 0, block,
2839#if CONFIG_CB4X4
2840 2 * (row + idy), 2 * (col + idx),
2841#else
2842 row + idy, col + idx,
2843#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002844 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002846 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002847 scan_order->scan, scan_order->neighbors,
2848 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002849 skip = (p->eobs[block] == 0);
2850 can_skip &= skip;
2851 tempa[idx] = !skip;
2852 templ[idy] = !skip;
2853#if CONFIG_EXT_TX
2854 if (tx_size == TX_8X4) {
2855 tempa[idx + 1] = tempa[idx];
2856 } else if (tx_size == TX_4X8) {
2857 templ[idy + 1] = templ[idy];
2858 }
2859#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002860#else
Yushin Cho900243b2017-01-03 11:02:38 -08002861 (void)scan_order;
2862
2863 av1_xform_quant(cm, x, 0, block,
2864#if CONFIG_CB4X4
2865 2 * (row + idy), 2 * (col + idx),
2866#else
2867 row + idy, col + idx,
2868#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002869 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yushin Cho900243b2017-01-03 11:02:38 -08002870
2871 ratey += x->rate;
2872 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002873 tempa[idx] = !skip;
2874 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08002875 can_skip &= skip;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002876#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2878 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002879#if CONFIG_PVQ
2880 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002881 for (j = 0; j < tx_height; j++)
2882 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002883#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002884 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
2885 p->eobs[block], DCT_DCT, 1);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002886#if CONFIG_PVQ
2887 }
2888#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002889 } else {
2890 int64_t dist;
2891 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002892 TX_TYPE tx_type =
2893 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2894 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002895 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002896 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002897#if CONFIG_CB4X4
2898 block = 4 * block;
2899#endif
Yushin Cho900243b2017-01-03 11:02:38 -08002900#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002901#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002902 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002903 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002904#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002905 av1_xform_quant(cm, x, 0, block,
2906#if CONFIG_CB4X4
2907 2 * (row + idy), 2 * (col + idx),
2908#else
2909 row + idy, col + idx,
2910#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002911 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002912#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002913 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
2914 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002915 scan_order->scan, scan_order->neighbors,
2916 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002917 skip = (p->eobs[block] == 0);
2918 can_skip &= skip;
2919 tempa[idx] = !skip;
2920 templ[idy] = !skip;
2921#if CONFIG_EXT_TX
2922 if (tx_size == TX_8X4) {
2923 tempa[idx + 1] = tempa[idx];
2924 } else if (tx_size == TX_4X8) {
2925 templ[idy + 1] = templ[idy];
2926 }
2927#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002928#else
Yushin Cho900243b2017-01-03 11:02:38 -08002929 (void)scan_order;
2930
2931 av1_xform_quant(cm, x, 0, block,
2932#if CONFIG_CB4X4
2933 2 * (row + idy), 2 * (col + idx),
2934#else
2935 row + idy, col + idx,
2936#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002937 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yushin Cho900243b2017-01-03 11:02:38 -08002938 ratey += x->rate;
2939 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002940 tempa[idx] = !skip;
2941 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08002942 can_skip &= skip;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002943#endif
Yushin Chob27a17f2016-12-23 14:33:02 -08002944#if CONFIG_PVQ
2945 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002946 for (j = 0; j < tx_height; j++)
2947 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Yushin Chob27a17f2016-12-23 14:33:02 -08002948#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002949 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
2950 p->eobs[block], tx_type, 0);
Yushin Chob27a17f2016-12-23 14:33:02 -08002951#if CONFIG_PVQ
2952 }
2953#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002954 // No need for av1_block_error2_c because the ssz is unused
Urvang Joshifeb925f2016-12-05 10:37:29 -08002955 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002956 dist = (int64_t)tmp << 4;
2957 distortion += dist;
2958 // To use the pixel domain distortion, the step below needs to be
2959 // put behind the inv txfm. Compared to calculating the distortion
2960 // in the frequency domain, the overhead of encoding effort is low.
2961 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2962 goto next;
2963 }
2964 }
2965 }
2966
2967 rate += ratey;
2968 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2969
2970 if (this_rd < best_rd) {
2971 *bestrate = rate;
2972 *bestratey = ratey;
2973 *bestdistortion = distortion;
2974 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002975 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002977 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2978 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07002979#if CONFIG_PVQ
2980 od_encode_checkpoint(&x->daala_enc, &post_buf);
2981#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002982 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002983 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002984 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002985 }
2986 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07002987#if CONFIG_PVQ
2988 od_encode_rollback(&x->daala_enc, &pre_buf);
2989#endif
2990 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07002991
2992 if (best_rd >= rd_thresh) return best_rd;
2993
Yushin Cho77bba8d2016-11-04 16:36:56 -07002994#if CONFIG_PVQ
2995 od_encode_rollback(&x->daala_enc, &post_buf);
2996#endif
2997
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002998 if (y_skip) *y_skip &= best_can_skip;
2999
Urvang Joshifeb925f2016-12-05 10:37:29 -08003000 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003002 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003003
3004 return best_rd;
3005}
3006
Urvang Joshi52648442016-10-13 17:27:51 -07003007static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3008 MACROBLOCK *mb, int *rate,
3009 int *rate_y, int64_t *distortion,
3010 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003011 const MACROBLOCKD *const xd = &mb->e_mbd;
3012 MODE_INFO *const mic = xd->mi[0];
3013 const MODE_INFO *above_mi = xd->above_mi;
3014 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003015 MB_MODE_INFO *const mbmi = &mic->mbmi;
3016 const BLOCK_SIZE bsize = mbmi->sb_type;
3017 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3018 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003019 int idx, idy;
3020 int cost = 0;
3021 int64_t total_distortion = 0;
3022 int tot_rate_y = 0;
3023 int64_t total_rd = 0;
3024 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003025 const int is_lossless = xd->lossless[mbmi->segment_id];
3026#if CONFIG_EXT_TX && CONFIG_RECT_TX
3027 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3028#else
3029 const TX_SIZE tx_size = TX_4X4;
3030#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003031
3032#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003033#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003034 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003035#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003037#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003038 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003039#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003040
3041 // TODO(any): Add search of the tx_type to improve rd performance at the
3042 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003043 mbmi->tx_type = DCT_DCT;
3044 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003045
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003046 if (y_skip) *y_skip = 1;
3047
Urvang Joshifeb925f2016-12-05 10:37:29 -08003048 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3049 // 8x8 coding block.
3050 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3051 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003052 PREDICTION_MODE best_mode = DC_PRED;
3053 int r = INT_MAX, ry = INT_MAX;
3054 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003055 int j;
3056 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003057 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003058 const PREDICTION_MODE A =
3059 av1_above_block_mode(mic, above_mi, pred_block_idx);
3060 const PREDICTION_MODE L =
3061 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003062
3063 bmode_costs = cpi->y_mode_costs[A][L];
3064 }
3065
Urvang Joshifeb925f2016-12-05 10:37:29 -08003066 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003067 cpi, mb, idy, idx, &best_mode, bmode_costs,
3068 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003069 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003070#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003071 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Yushin Cho7a428ba2017-01-12 16:28:49 -08003072#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073 total_rd += this_rd;
3074 cost += r;
3075 total_distortion += d;
3076 tot_rate_y += ry;
3077
Urvang Joshifeb925f2016-12-05 10:37:29 -08003078 mic->bmi[pred_block_idx].as_mode = best_mode;
3079 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3080 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3081 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3082 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003083
3084 if (total_rd >= best_rd) return INT64_MAX;
3085 }
3086 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003087 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003088
Yushin Cho7a428ba2017-01-12 16:28:49 -08003089#if CONFIG_DAALA_DIST
3090 {
3091 const struct macroblock_plane *p = &mb->plane[0];
3092 const struct macroblockd_plane *pd = &xd->plane[0];
3093 const int src_stride = p->src.stride;
3094 const int dst_stride = pd->dst.stride;
3095 uint8_t *src = p->src.buf;
3096 uint8_t *dst = pd->dst.buf;
3097 int use_activity_masking = 0;
3098 int qm = OD_HVS_QM;
3099
3100#if CONFIG_PVQ
3101 use_activity_masking = mb->daala_enc.use_activity_masking;
3102#endif
3103 // Daala-defined distortion computed for the block of 8x8 pixels
3104 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, TX_8X8,
3105 qm, use_activity_masking, mb->qindex)
3106 << 4;
3107 }
3108#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003109 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003110 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003111 int rate_tx_type = 0;
3112#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003113 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3114 1) {
3115 const int eset =
3116 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003117 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3118 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003119 }
3120#else
clang-format67948d32016-09-07 22:40:40 -07003121 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003122 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3123 [intra_mode_to_tx_type_context[mbmi->mode]]
3124 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003125#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003126 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003127 cost += rate_tx_type;
3128 tot_rate_y += rate_tx_type;
3129 }
3130
3131 *rate = cost;
3132 *rate_y = tot_rate_y;
3133 *distortion = total_distortion;
3134
3135 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3136}
3137
hui su5db97432016-10-14 16:10:14 -07003138#if CONFIG_FILTER_INTRA
3139// Return 1 if an filter intra mode is selected; return 0 otherwise.
3140static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3141 int *rate, int *rate_tokenonly,
3142 int64_t *distortion, int *skippable,
3143 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003144 int64_t *best_rd, int64_t *best_model_rd,
3145 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146 MACROBLOCKD *const xd = &x->e_mbd;
3147 MODE_INFO *const mic = xd->mi[0];
3148 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003149 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003150 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003151 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003152 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003153 TX_TYPE best_tx_type;
3154
hui su5db97432016-10-14 16:10:14 -07003155 av1_zero(filter_intra_mode_info);
3156 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003158#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003159 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003160#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161
3162 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003163 int this_rate;
3164 int64_t this_rd, this_model_rd;
3165 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003167 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003168 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3169 if (*best_model_rd != INT64_MAX &&
3170 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3171 continue;
3172 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003173 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3174 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003175 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003176 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003178 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003179
3180 if (this_rd < *best_rd) {
3181 *best_rd = this_rd;
3182 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003183 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003184 best_tx_type = mic->mbmi.tx_type;
3185 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003186 *rate_tokenonly = tokenonly_rd_stats.rate;
3187 *distortion = tokenonly_rd_stats.dist;
3188 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003189 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003190 }
3191 }
3192
hui su5db97432016-10-14 16:10:14 -07003193 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003194 mbmi->mode = DC_PRED;
3195 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003196 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3197 filter_intra_mode_info.use_filter_intra_mode[0];
3198 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3199 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003200 mbmi->tx_type = best_tx_type;
3201 return 1;
3202 } else {
3203 return 0;
3204 }
3205}
hui su5db97432016-10-14 16:10:14 -07003206#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003207
hui su5db97432016-10-14 16:10:14 -07003208#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003209// Run RD calculation with given luma intra prediction angle., and return
3210// the RD cost. Update the best mode info. if the RD cost is the best so far.
3211static int64_t calc_rd_given_intra_angle(
3212 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3213 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3214 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3215 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003216#if CONFIG_INTRA_INTERP
3217 INTRA_FILTER *best_filter,
3218#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003219 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003220 int this_rate;
3221 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003222 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003223 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003224
hui su45dc5972016-12-08 17:42:50 -08003225 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003226 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3227 if (*best_model_rd != INT64_MAX &&
3228 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3229 return INT64_MAX;
3230 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003231 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3232 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3233
3234 this_rate = tokenonly_rd_stats.rate + mode_cost +
3235 write_uniform_cost(2 * max_angle_delta + 1,
3236 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003237 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003238
3239 if (this_rd < *best_rd) {
3240 *best_rd = this_rd;
3241 *best_angle_delta = mbmi->angle_delta[0];
3242 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003243#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003244 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003245#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003246 *best_tx_type = mbmi->tx_type;
3247 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003248 rd_stats->rate = tokenonly_rd_stats.rate;
3249 rd_stats->dist = tokenonly_rd_stats.dist;
3250 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003251 }
hui su45dc5972016-12-08 17:42:50 -08003252 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253}
3254
hui su45dc5972016-12-08 17:42:50 -08003255// With given luma directional intra prediction mode, pick the best angle delta
3256// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003257static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003258 int *rate, RD_STATS *rd_stats,
3259 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003260 int64_t best_rd,
3261 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262 MACROBLOCKD *const xd = &x->e_mbd;
3263 MODE_INFO *const mic = xd->mi[0];
3264 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su45dc5972016-12-08 17:42:50 -08003265 int i, angle_delta, best_angle_delta = 0;
3266 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
3267 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003268#if CONFIG_INTRA_INTERP
3269 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003270 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003272#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003273 int64_t this_rd, best_rd_in, rd_cost[16];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003274 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3275 TX_TYPE best_tx_type = mbmi->tx_type;
3276
hui su45dc5972016-12-08 17:42:50 -08003277 for (i = 0; i < 2 * (max_angle_delta + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278
hui su45dc5972016-12-08 17:42:50 -08003279 for (angle_delta = 0; angle_delta <= max_angle_delta; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003280#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003281 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3282 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3283 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003284#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003285 for (i = 0; i < 2; ++i) {
3286 best_rd_in = (best_rd == INT64_MAX)
3287 ? INT64_MAX
3288 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3289 this_rd = calc_rd_given_intra_angle(
3290 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003291#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003292 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003293#else
hui su45dc5972016-12-08 17:42:50 -08003294 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003295#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003296 best_rd_in, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3297 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003298#if CONFIG_INTRA_INTERP
3299 &best_filter,
3300#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003301 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003302 rd_cost[2 * angle_delta + i] = this_rd;
3303 if (first_try && this_rd == INT64_MAX) return best_rd;
3304 first_try = 0;
3305 if (angle_delta == 0) {
3306 rd_cost[1] = this_rd;
3307 break;
3308 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309 }
hui su45dc5972016-12-08 17:42:50 -08003310#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003311 }
hui su45dc5972016-12-08 17:42:50 -08003312#endif // CONFIG_INTRA_INTERP
3313 }
3314
3315 assert(best_rd != INT64_MAX);
3316 for (angle_delta = 1; angle_delta <= max_angle_delta; angle_delta += 2) {
3317 int64_t rd_thresh;
3318#if CONFIG_INTRA_INTERP
3319 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3320 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3321 mic->mbmi.intra_filter = filter;
3322#endif // CONFIG_INTRA_INTERP
3323 for (i = 0; i < 2; ++i) {
3324 int skip_search = 0;
3325 rd_thresh = best_rd + (best_rd >> 5);
3326 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3327 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3328 skip_search = 1;
3329 if (!skip_search) {
3330 this_rd = calc_rd_given_intra_angle(
3331 cpi, x, bsize,
3332#if CONFIG_INTRA_INTERP
3333 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3334#else
3335 mode_cost,
3336#endif // CONFIG_INTRA_INTERP
3337 best_rd, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3338 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3339#if CONFIG_INTRA_INTERP
3340 &best_filter,
3341#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003342 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003343 }
3344 }
3345#if CONFIG_INTRA_INTERP
3346 }
3347#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003348 }
3349
hui sueda3d762016-12-06 16:58:23 -08003350#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003351 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
3352 p_angle = mode_to_angle_map[mbmi->mode] +
3353 best_angle_delta * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003354 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003355 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3356 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003357 this_rd = calc_rd_given_intra_angle(
3358 cpi, x, bsize,
3359 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3360 best_rd, best_angle_delta, max_angle_delta, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003362 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003363 }
3364 }
3365 }
hui sueda3d762016-12-06 16:58:23 -08003366#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003367
3368 mbmi->tx_size = best_tx_size;
3369 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003370#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003371 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003372#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003373 mbmi->tx_type = best_tx_type;
3374 return best_rd;
3375}
3376
3377// Indices are sign, integer, and fractional part of the gradient value
3378static const uint8_t gradient_to_angle_bin[2][7][16] = {
3379 {
3380 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3381 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3382 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3383 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3384 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3385 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3386 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3387 },
3388 {
3389 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3390 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3391 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3392 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3393 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3394 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3395 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3396 },
3397};
3398
3399static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3400 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
3401};
3402
3403static void angle_estimation(const uint8_t *src, int src_stride, int rows,
3404 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003405 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003406 uint64_t hist[DIRECTIONAL_MODES];
3407 uint64_t hist_sum = 0;
3408
3409 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3410 src += src_stride;
3411 for (r = 1; r < rows; ++r) {
3412 for (c = 1; c < cols; ++c) {
3413 dx = src[c] - src[c - 1];
3414 dy = src[c] - src[c - src_stride];
3415 temp = dx * dx + dy * dy;
3416 if (dy == 0) {
3417 index = 2;
3418 } else {
3419 sn = (dx > 0) ^ (dy > 0);
3420 dx = abs(dx);
3421 dy = abs(dy);
3422 remd = dx % dy;
3423 quot = dx / dy;
3424 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003425 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003426 }
3427 hist[index] += temp;
3428 }
3429 src += src_stride;
3430 }
3431
3432 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3433 for (i = 0; i < INTRA_MODES; ++i) {
3434 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003435 const uint8_t angle_bin = mode_to_angle_bin[i];
3436 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003437 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003438 if (angle_bin > 0) {
3439 score += hist[angle_bin - 1];
3440 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003441 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003442 if (angle_bin < DIRECTIONAL_MODES - 1) {
3443 score += hist[angle_bin + 1];
3444 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003445 }
3446 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3447 directional_mode_skip_mask[i] = 1;
3448 }
3449 }
3450}
3451
Yaowu Xuf883b422016-08-30 14:01:10 -07003452#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003453static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
3454 int rows, int cols,
3455 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003456 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003457 uint64_t hist[DIRECTIONAL_MODES];
3458 uint64_t hist_sum = 0;
3459 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
3460
3461 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3462 src += src_stride;
3463 for (r = 1; r < rows; ++r) {
3464 for (c = 1; c < cols; ++c) {
3465 dx = src[c] - src[c - 1];
3466 dy = src[c] - src[c - src_stride];
3467 temp = dx * dx + dy * dy;
3468 if (dy == 0) {
3469 index = 2;
3470 } else {
3471 sn = (dx > 0) ^ (dy > 0);
3472 dx = abs(dx);
3473 dy = abs(dy);
3474 remd = dx % dy;
3475 quot = dx / dy;
3476 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003477 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003478 }
3479 hist[index] += temp;
3480 }
3481 src += src_stride;
3482 }
3483
3484 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3485 for (i = 0; i < INTRA_MODES; ++i) {
3486 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003487 const uint8_t angle_bin = mode_to_angle_bin[i];
3488 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003489 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003490 if (angle_bin > 0) {
3491 score += hist[angle_bin - 1];
3492 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003493 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003494 if (angle_bin < DIRECTIONAL_MODES - 1) {
3495 score += hist[angle_bin + 1];
3496 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003497 }
3498 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3499 directional_mode_skip_mask[i] = 1;
3500 }
3501 }
3502}
Yaowu Xuf883b422016-08-30 14:01:10 -07003503#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003504#endif // CONFIG_EXT_INTRA
3505
3506// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003507static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3508 int *rate, int *rate_tokenonly,
3509 int64_t *distortion, int *skippable,
3510 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003511 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003512 MACROBLOCKD *const xd = &x->e_mbd;
3513 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003514 MB_MODE_INFO *const mbmi = &mic->mbmi;
3515 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003516 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003517#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003518 const int rows = block_size_high[bsize];
3519 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003520#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003521 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003522#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003523 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003524 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003525 const int src_stride = x->plane[0].src.stride;
3526 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003527#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003528#if CONFIG_FILTER_INTRA
3529 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003530 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3531#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003532 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003533#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003534 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003535 uint8_t *best_palette_color_map =
3536 cpi->common.allow_screen_content_tools
3537 ? x->palette_buffer->best_palette_color_map
3538 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003539 int palette_y_mode_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003540#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003541 const MODE_INFO *above_mi = xd->above_mi;
3542 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003543 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3544 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003546#if CONFIG_PVQ
3547 od_rollback_buffer pre_buf, post_buf;
3548
3549 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3550 od_encode_checkpoint(&x->daala_enc, &post_buf);
3551#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003552 bmode_costs = cpi->y_mode_costs[A][L];
3553
3554#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003555 mbmi->angle_delta[0] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 memset(directional_mode_skip_mask, 0,
3557 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07003558#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003559 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3560 highbd_angle_estimation(src, src_stride, rows, cols,
3561 directional_mode_skip_mask);
3562 else
3563#endif
3564 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
3565#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003566#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003567 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003568#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003569#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 pmi->palette_size[0] = 0;
3571 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003572 palette_y_mode_ctx +=
3573 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003574 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003575 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003576#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003577
3578 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3579 x->use_default_intra_tx_type = 1;
3580 else
3581 x->use_default_intra_tx_type = 0;
3582
3583 /* Y Search for intra prediction mode */
3584 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003585 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003586 int this_rate, this_rate_tokenonly, s;
3587 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003588 if (mode_idx == FINAL_MODE_SEARCH) {
3589 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003590 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003591 x->use_default_intra_tx_type = 0;
3592 } else {
hui sude0c70a2017-01-09 17:12:17 -08003593 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003595#if CONFIG_PVQ
3596 od_encode_rollback(&x->daala_enc, &pre_buf);
3597#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003598#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003599 mbmi->angle_delta[0] = 0;
3600#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003601 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003602 if (best_model_rd != INT64_MAX &&
3603 this_model_rd > best_model_rd + (best_model_rd >> 1))
3604 continue;
3605 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3606#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003607 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3608 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003609 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003610 this_rd_stats.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -08003611 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats,
3612 bsize, bmode_costs[mbmi->mode], best_rd,
3613 &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003615 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003616 }
3617#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003618 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003619#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003620 this_rate_tokenonly = this_rd_stats.rate;
3621 this_distortion = this_rd_stats.dist;
3622 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003623
3624 if (this_rate_tokenonly == INT_MAX) continue;
3625
hui sude0c70a2017-01-09 17:12:17 -08003626 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003627
hui sude0c70a2017-01-09 17:12:17 -08003628 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 // super_block_yrd above includes the cost of the tx_size in the
3630 // tokenonly rate, but for intra blocks, tx_size is always coded
3631 // (prediction granularity), so we account for it in the full rate,
3632 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003633 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003634 }
Urvang Joshib100db72016-10-12 16:28:56 -07003635#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003636 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Urvang Joshi23a61112017-01-30 14:59:27 -08003637 this_rate +=
3638 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3639 [palette_y_mode_ctx],
3640 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003641#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003642#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003643 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003644 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3645#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003646#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003647 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003648 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -08003649#if CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003650 const int p_angle = mode_to_angle_map[mbmi->mode] +
3651 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003652 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003653 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003654 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003655#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003656 this_rate += write_uniform_cost(2 * max_angle_delta + 1,
3657 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658 }
3659#endif // CONFIG_EXT_INTRA
3660 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003661#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003662 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003663 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003664 }
hui su5db97432016-10-14 16:10:14 -07003665#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003666
3667 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003668 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003669 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003670#if CONFIG_FILTER_INTRA
3671 beat_best_rd = 1;
3672#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003673 *rate = this_rate;
3674 *rate_tokenonly = this_rate_tokenonly;
3675 *distortion = this_distortion;
3676 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003677#if CONFIG_PVQ
3678 od_encode_checkpoint(&x->daala_enc, &post_buf);
3679#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003680 }
3681 }
3682
Yushin Cho77bba8d2016-11-04 16:36:56 -07003683#if CONFIG_PVQ
3684 od_encode_rollback(&x->daala_enc, &post_buf);
3685#endif
3686
Urvang Joshib100db72016-10-12 16:28:56 -07003687#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003688 if (cpi->common.allow_screen_content_tools) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003689 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3690 bmode_costs[DC_PRED], &best_mbmi,
3691 best_palette_color_map, &best_rd, &best_model_rd,
3692 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003693 }
Urvang Joshib100db72016-10-12 16:28:56 -07003694#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003695
hui su5db97432016-10-14 16:10:14 -07003696#if CONFIG_FILTER_INTRA
3697 if (beat_best_rd) {
3698 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3699 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003700 &best_rd, &best_model_rd,
3701 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003702 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003703 }
3704 }
hui su5db97432016-10-14 16:10:14 -07003705#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706
hui sude0c70a2017-01-09 17:12:17 -08003707 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003708 return best_rd;
3709}
3710
Yue Chena1e48dc2016-08-29 17:29:33 -07003711// Return value 0: early termination triggered, no valid rd cost available;
3712// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003713static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3714 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3715 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003716 MACROBLOCKD *const xd = &x->e_mbd;
3717 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3718 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3719 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003720 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003721 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003722
3723 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003724
Jingning Han31b6a4f2017-02-23 11:05:53 -08003725#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003726 if (x->skip_chroma_rd) return is_cost_valid;
3727 bsize = AOMMAX(BLOCK_8X8, bsize);
3728#endif
3729
Yushin Cho77bba8d2016-11-04 16:36:56 -07003730#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003731 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003732 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3733 av1_subtract_plane(x, bsize, plane);
3734 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003735#endif
Yue Chena1e48dc2016-08-29 17:29:33 -07003736
Yushin Cho09de28b2016-06-21 14:51:23 -07003737 if (is_cost_valid) {
3738 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003739 RD_STATS pn_rd_stats;
3740 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3741 uv_tx_size, cpi->sf.use_fast_coef_costing);
3742 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003743 is_cost_valid = 0;
3744 break;
3745 }
Angie Chiang284d7772016-11-08 11:06:45 -08003746 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3747 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003748 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003749 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003750 is_cost_valid = 0;
3751 break;
3752 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003753 }
3754 }
3755
3756 if (!is_cost_valid) {
3757 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003758 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003759 }
3760
3761 return is_cost_valid;
3762}
3763
Yaowu Xuc27fc142016-08-22 16:08:15 -07003764#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003765void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3766 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003767 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003768 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003769 MACROBLOCKD *xd = &x->e_mbd;
3770 const struct macroblock_plane *const p = &x->plane[plane];
3771 struct macroblockd_plane *const pd = &xd->plane[plane];
3772 int64_t tmp;
3773 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003774 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003775 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003776 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003777 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003778 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003779 int bh = block_size_high[txm_bsize];
3780 int bw = block_size_wide[txm_bsize];
3781 int txb_h = tx_size_high_unit[tx_size];
3782 int txb_w = tx_size_wide_unit[tx_size];
3783
Yaowu Xuc27fc142016-08-22 16:08:15 -07003784 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003785 uint8_t *src =
3786 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3787 uint8_t *dst =
3788 &pd->dst
3789 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuf883b422016-08-30 14:01:10 -07003790#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003791 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3792 uint8_t *rec_buffer;
3793#else
3794 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003795#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003796 int max_blocks_high = block_size_high[plane_bsize];
3797 int max_blocks_wide = block_size_wide[plane_bsize];
3798 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003799 const int16_t *diff =
3800 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003801 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003802
3803 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804
3805 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003806 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003807 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003808 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3809
3810 max_blocks_high >>= tx_size_wide_log2[0];
3811 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003812
3813#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003814 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
3815 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003816#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003817 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003818 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819#endif // CONFIG_NEW_QUANT
3820
Yushin Cho721868c2016-11-14 16:04:33 +09003821 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003822 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003823
3824// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003825#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003826 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3827 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003828 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003829 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003830 } else {
3831 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003832 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003833 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003834 }
3835#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003836 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003837 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003838#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003839
Jingning Han9fdc4222016-10-27 21:32:19 -07003840 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003841 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003842 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3843 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003845 for (idy = 0; idy < blocks_height; ++idy) {
3846 for (idx = 0; idx < blocks_width; ++idx) {
3847 const int16_t *d =
3848 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003849 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003850 }
3851 }
3852 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003853 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003854 }
3855
Yaowu Xuf883b422016-08-30 14:01:10 -07003856#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3858 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003859#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003860 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003861
3862 if (p->eobs[block] > 0) {
3863 INV_TXFM_PARAM inv_txfm_param;
3864 inv_txfm_param.tx_type = tx_type;
3865 inv_txfm_param.tx_size = tx_size;
3866 inv_txfm_param.eob = p->eobs[block];
3867 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003868// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003869#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003870 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3871 inv_txfm_param.bd = xd->bd;
3872 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3873 } else {
3874 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3875 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003876#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003877 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003878#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879
Jingning Han4b47c932016-11-03 09:20:08 -07003880 if (txb_w + blk_col > max_blocks_wide ||
3881 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003882 int idx, idy;
3883 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003884 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3885 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003887 for (idy = 0; idy < blocks_height; ++idy) {
3888 for (idx = 0; idx < blocks_width; ++idx) {
3889 uint8_t *const s =
3890 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3891 uint8_t *const r =
3892 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003893 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 tmp += this_dist;
3895 }
3896 }
3897 } else {
3898 uint32_t this_dist;
3899 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3900 &this_dist);
3901 tmp = this_dist;
3902 }
3903 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003904 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003905 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3906 scan_order->scan, scan_order->neighbors, 0);
3907 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003908 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003909
Angie Chiangd81fdb42016-11-03 12:20:58 -07003910#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003911 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3912 txb_coeff_cost);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003913#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003914}
3915
Yaowu Xuf883b422016-08-30 14:01:10 -07003916static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003917 int blk_col, int plane, int block, int block32,
3918 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003919 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3920 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003921 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003922 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003923 MACROBLOCKD *const xd = &x->e_mbd;
3924 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3925 struct macroblock_plane *const p = &x->plane[plane];
3926 struct macroblockd_plane *const pd = &xd->plane[plane];
3927 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3928 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003929 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003930 [MAX_MIB_SIZE] =
3931 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003932 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3933 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003934 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003935 int64_t this_rd = INT64_MAX;
3936 ENTROPY_CONTEXT *pta = ta + blk_col;
3937 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003938 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003939 int ctx =
3940 txfm_partition_context(tx_above + (blk_col >> 1),
3941 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003943 int tmp_eob = 0;
3944 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003945 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003946 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947
Jingning Han63cbf342016-11-09 15:37:48 -08003948 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003949
Jingning Hand3fada82016-11-22 10:46:55 -08003950 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951
3952 if (ref_best_rd < 0) {
3953 *is_cost_valid = 0;
3954 return;
3955 }
3956
Jingning Hance059e82016-10-31 16:27:28 -07003957 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003958
Angie Chiangc0feea82016-11-03 15:36:18 -07003959 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960
3961 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3962
Jingning Han1c019f92016-11-21 12:53:32 -08003963 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
3964 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965
3966 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3967 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003968
3969 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3970 rd_stats_stack[block32].rate != INT_MAX) {
3971 *rd_stats = rd_stats_stack[block32];
3972 p->eobs[block] = !rd_stats->skip;
3973 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3974 } else {
3975 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
3976 plane_bsize, coeff_ctx, rd_stats);
3977 if (tx_size == TX_32X32) {
3978 rd_stats_stack[block32] = *rd_stats;
3979 }
3980 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003981
Angie Chiangb5dda482016-11-02 16:19:58 -07003982 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
3983 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
3984 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003985 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08003986#if CONFIG_RD_DEBUG
3987 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3988 zero_blk_rate - rd_stats->rate);
3989#endif
Angie Chiangb5dda482016-11-02 16:19:58 -07003990 rd_stats->rate = zero_blk_rate;
3991 rd_stats->dist = rd_stats->sse;
3992 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
3994 p->eobs[block] = 0;
3995 } else {
3996 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07003997 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003998 }
3999
Jingning Han571189c2016-10-24 10:38:43 -07004000 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004001 rd_stats->rate +=
4002 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4003 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004004 tmp_eob = p->eobs[block];
4005 }
4006
Jingning Han571189c2016-10-24 10:38:43 -07004007 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004008 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4009 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004010 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004011 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004012 int this_cost_valid = 1;
4013 int64_t tmp_rd = 0;
4014
Angie Chiangd7246172016-11-03 11:49:15 -07004015 sum_rd_stats.rate =
4016 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004017
4018 assert(tx_size < TX_SIZES_ALL);
4019
Yaowu Xuc27fc142016-08-22 16:08:15 -07004020 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004021 int offsetr = blk_row + (i >> 1) * bsl;
4022 int offsetc = blk_col + (i & 0x01) * bsl;
4023
4024 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4025
Jingning Han63cbf342016-11-09 15:37:48 -08004026 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004027 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004028 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4029 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004030
Angie Chiangc0feea82016-11-03 15:36:18 -07004031 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004032
Angie Chiangd7246172016-11-03 11:49:15 -07004033 tmp_rd =
4034 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004035 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004036 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004037 }
4038 if (this_cost_valid) sum_rd = tmp_rd;
4039 }
4040
4041 if (this_rd < sum_rd) {
4042 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004043 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4044 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004046 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004047 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004048 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4049 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004050 inter_tx_size[idy][idx] = tx_size;
4051 mbmi->tx_size = tx_size;
4052 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004053 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004055 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004056 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4057 }
4058}
4059
Angie Chiangb5dda482016-11-02 16:19:58 -07004060static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4061 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004062 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004063 MACROBLOCKD *const xd = &x->e_mbd;
4064 int is_cost_valid = 1;
4065 int64_t this_rd = 0;
4066
4067 if (ref_best_rd < 0) is_cost_valid = 0;
4068
Angie Chiangc0feea82016-11-03 15:36:18 -07004069 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004070
4071 if (is_cost_valid) {
4072 const struct macroblockd_plane *const pd = &xd->plane[0];
4073 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004074 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4075 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004076 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004077 const int bh = tx_size_high_unit[max_tx_size];
4078 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004079 int idx, idy;
4080 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004081 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004082 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004083 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4084 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4085 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4086 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4087
Angie Chiangb5dda482016-11-02 16:19:58 -07004088 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004089 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090
Jingning Han9ca05b72017-01-03 14:41:36 -08004091 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092 memcpy(tx_above, xd->above_txfm_context,
4093 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4094 memcpy(tx_left, xd->left_txfm_context,
4095 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4096
4097 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004098 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004099 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004100 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004101 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004102 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004103 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004104 this_rd += AOMMIN(
4105 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4106 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004107 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004108 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004109 }
4110 }
4111 }
4112
Angie Chiangb5dda482016-11-02 16:19:58 -07004113 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4114 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004115 if (this_rd > ref_best_rd) is_cost_valid = 0;
4116
4117 if (!is_cost_valid) {
4118 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004119 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120 }
4121}
4122
Yaowu Xuf883b422016-08-30 14:01:10 -07004123static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004124 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004125 int64_t ref_best_rd, TX_TYPE tx_type,
4126 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004127 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004128 MACROBLOCKD *const xd = &x->e_mbd;
4129 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004130 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004131 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4132 int s0 = av1_cost_bit(skip_prob, 0);
4133 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004134 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004135 int row, col;
4136 const int max_blocks_high = max_block_high(xd, bsize, 0);
4137 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138
4139 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004140 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004141 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142
Angie Chiangb5dda482016-11-02 16:19:58 -07004143 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144
Jingning Hane67b38a2016-11-04 10:30:00 -07004145 for (row = 0; row < max_blocks_high / 2; ++row)
4146 for (col = 0; col < max_blocks_wide / 2; ++col)
4147 mbmi->min_tx_size = AOMMIN(
4148 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4149
Yaowu Xuc27fc142016-08-22 16:08:15 -07004150#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004151 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4152 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004153 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004154 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4155 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 if (is_inter) {
4157 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004158 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004159 cpi->inter_tx_type_costs[ext_tx_set]
4160 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004161 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004162 } else {
4163 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004164 rd_stats->rate +=
4165 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4166 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004167 }
4168 }
4169#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004170 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4171 rd_stats->rate +=
4172 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173#endif // CONFIG_EXT_TX
4174
Angie Chiangb5dda482016-11-02 16:19:58 -07004175 if (rd_stats->skip)
4176 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004178 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004179
Angie Chiangb5dda482016-11-02 16:19:58 -07004180 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4181 !(rd_stats->skip))
4182 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004183
4184 return rd;
4185}
4186
Angie Chiangb5dda482016-11-02 16:19:58 -07004187static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4188 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004190 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4192 MACROBLOCKD *const xd = &x->e_mbd;
4193 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4194 int64_t rd = INT64_MAX;
4195 int64_t best_rd = INT64_MAX;
4196 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4197 const int is_inter = is_inter_block(mbmi);
4198 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004199 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004200 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004201 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
4202 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004203 int idx, idy;
4204 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004205 const int count32 =
4206 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004207#if CONFIG_EXT_PARTITION
4208 RD_STATS rd_stats_stack[16];
4209#else
Jingning Han63cbf342016-11-09 15:37:48 -08004210 RD_STATS rd_stats_stack[4];
Jingning Han89d648b2016-11-22 11:22:08 -08004211#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004212#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004213 const int ext_tx_set =
4214 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215#endif // CONFIG_EXT_TX
4216
4217 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4218#if CONFIG_EXT_TX
4219 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4220#else
4221 prune = prune_tx_types(cpi, bsize, x, xd, 0);
4222#endif
4223
Angie Chiangc0feea82016-11-03 15:36:18 -07004224 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225
Jingning Han89d648b2016-11-22 11:22:08 -08004226 for (idx = 0; idx < count32; ++idx)
4227 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004228
Yaowu Xuc27fc142016-08-22 16:08:15 -07004229 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004230 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004231 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004232#if CONFIG_EXT_TX
4233 if (is_inter) {
4234 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4235 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4236 if (!do_tx_type_search(tx_type, prune)) continue;
4237 }
4238 } else {
4239 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4240 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4241 }
4242 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4243 }
4244#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4246 !do_tx_type_search(tx_type, prune))
4247 continue;
4248#endif // CONFIG_EXT_TX
4249 if (is_inter && x->use_default_inter_tx_type &&
4250 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4251 continue;
4252
Jingning Hane67b38a2016-11-04 10:30:00 -07004253 if (xd->lossless[mbmi->segment_id])
4254 if (tx_type != DCT_DCT) continue;
4255
Angie Chiangb5dda482016-11-02 16:19:58 -07004256 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004257 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004258
4259 if (rd < best_rd) {
4260 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004261 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004262 best_tx_type = mbmi->tx_type;
4263 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004264 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004265 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4266 for (idy = 0; idy < xd->n8_h; ++idy)
4267 for (idx = 0; idx < xd->n8_w; ++idx)
4268 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4269 }
4270 }
4271
4272 mbmi->tx_type = best_tx_type;
4273 for (idy = 0; idy < xd->n8_h; ++idy)
4274 for (idx = 0; idx < xd->n8_w; ++idx)
4275 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4276 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004277 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004278 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4279}
4280
Yaowu Xuf883b422016-08-30 14:01:10 -07004281static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 int blk_col, int plane, int block, TX_SIZE tx_size,
4283 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004284 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004285 MACROBLOCKD *const xd = &x->e_mbd;
4286 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4287 struct macroblock_plane *const p = &x->plane[plane];
4288 struct macroblockd_plane *const pd = &xd->plane[plane];
4289 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4290 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4291 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4292 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004293 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4294 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004295
Jingning Hand3fada82016-11-22 10:46:55 -08004296 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004297
Yaowu Xuc27fc142016-08-22 16:08:15 -07004298 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4299
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004300 plane_tx_size =
4301 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4302 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004303
4304 if (tx_size == plane_tx_size) {
4305 int coeff_ctx, i;
4306 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4307 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07004308 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07004309 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07004310 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004311
Jingning Han58224042016-10-27 16:35:32 -07004312 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004313 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004314 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004315 tl[i] = !(p->eobs[block] == 0);
4316 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004317 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4318 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004319 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004320 int i;
4321
4322 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323
4324 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004325 int offsetr = blk_row + (i >> 1) * bsl;
4326 int offsetc = blk_col + (i & 0x01) * bsl;
4327
4328 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4329
4330 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4331 above_ctx, left_ctx, rd_stats);
4332 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004333 }
4334 }
4335}
4336
4337// Return value 0: early termination triggered, no valid rd cost available;
4338// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004339static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4340 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4341 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004342 MACROBLOCKD *const xd = &x->e_mbd;
4343 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4344 int plane;
4345 int is_cost_valid = 1;
4346 int64_t this_rd;
4347
4348 if (ref_best_rd < 0) is_cost_valid = 0;
4349
Angie Chiangc0feea82016-11-03 15:36:18 -07004350 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004351
Jingning Han31b6a4f2017-02-23 11:05:53 -08004352#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004353 if (x->skip_chroma_rd) return is_cost_valid;
4354 bsize = AOMMAX(BLOCK_8X8, bsize);
4355#endif
4356
Yue Chena1e48dc2016-08-29 17:29:33 -07004357#if CONFIG_EXT_TX && CONFIG_RECT_TX
4358 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004359 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004360 }
4361#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4362
Yaowu Xuc27fc142016-08-22 16:08:15 -07004363 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004365 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004366 }
4367
Yaowu Xuc27fc142016-08-22 16:08:15 -07004368 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4369 const struct macroblockd_plane *const pd = &xd->plane[plane];
4370 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004371 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4372 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004373 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004374 const int bh = tx_size_high_unit[max_tx_size];
4375 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004376 int idx, idy;
4377 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004378 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4380 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004381 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004382 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004383
Jingning Han9ca05b72017-01-03 14:41:36 -08004384 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385
4386 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004387 for (idx = 0; idx < mi_width; idx += bw) {
4388 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004389 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390 block += step;
4391 }
4392 }
4393
Angie Chiangb5dda482016-11-02 16:19:58 -07004394 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004395 is_cost_valid = 0;
4396 break;
4397 }
4398
Angie Chiang628d7c92016-11-03 16:24:56 -07004399 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004400
Angie Chiangb5dda482016-11-02 16:19:58 -07004401 this_rd =
4402 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4403 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404
4405 if (this_rd > ref_best_rd) {
4406 is_cost_valid = 0;
4407 break;
4408 }
4409 }
4410
4411 if (!is_cost_valid) {
4412 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004413 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004414 }
4415
4416 return is_cost_valid;
4417}
4418#endif // CONFIG_VAR_TX
4419
Urvang Joshib100db72016-10-12 16:28:56 -07004420#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004421static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4422 int dc_mode_cost,
4423 uint8_t *best_palette_color_map,
4424 MB_MODE_INFO *const best_mbmi,
4425 int64_t *best_rd, int *rate,
4426 int *rate_tokenonly, int64_t *distortion,
4427 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004428 MACROBLOCKD *const xd = &x->e_mbd;
4429 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui sude0c70a2017-01-09 17:12:17 -08004430 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004431 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004432 int this_rate;
4433 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434 int colors_u, colors_v, colors;
4435 const int src_stride = x->plane[1].src.stride;
4436 const uint8_t *const src_u = x->plane[1].src.buf;
4437 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004438 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004439 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004440 int plane_block_width, plane_block_height, rows, cols;
4441 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4442 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004443 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4444
hui su83c26632017-01-24 17:19:06 -08004445 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004446#if CONFIG_FILTER_INTRA
4447 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4448#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004449
Yaowu Xuf883b422016-08-30 14:01:10 -07004450#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004451 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004452 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4453 cpi->common.bit_depth);
4454 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4455 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004456 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004457#endif // CONFIG_AOM_HIGHBITDEPTH
4458 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4459 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
4460#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004461 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004462#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463
4464 colors = colors_u > colors_v ? colors_u : colors_v;
4465 if (colors > 1 && colors <= 64) {
4466 int r, c, n, i, j;
4467 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004468 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004469 float lb_u, ub_u, val_u;
4470 float lb_v, ub_v, val_v;
4471 float *const data = x->palette_buffer->kmeans_data_buf;
4472 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004473
Yaowu Xuf883b422016-08-30 14:01:10 -07004474#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004475 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4476 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4477 if (cpi->common.use_highbitdepth) {
4478 lb_u = src_u16[0];
4479 ub_u = src_u16[0];
4480 lb_v = src_v16[0];
4481 ub_v = src_v16[0];
4482 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004483#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004484 lb_u = src_u[0];
4485 ub_u = src_u[0];
4486 lb_v = src_v[0];
4487 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07004488#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004489 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004490#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004491
Yaowu Xuc27fc142016-08-22 16:08:15 -07004492 for (r = 0; r < rows; ++r) {
4493 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004494#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004495 if (cpi->common.use_highbitdepth) {
4496 val_u = src_u16[r * src_stride + c];
4497 val_v = src_v16[r * src_stride + c];
4498 data[(r * cols + c) * 2] = val_u;
4499 data[(r * cols + c) * 2 + 1] = val_v;
4500 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004501#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004502 val_u = src_u[r * src_stride + c];
4503 val_v = src_v[r * src_stride + c];
4504 data[(r * cols + c) * 2] = val_u;
4505 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07004506#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004507 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004508#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509 if (val_u < lb_u)
4510 lb_u = val_u;
4511 else if (val_u > ub_u)
4512 ub_u = val_u;
4513 if (val_v < lb_v)
4514 lb_v = val_v;
4515 else if (val_v > ub_v)
4516 ub_v = val_v;
4517 }
4518 }
4519
4520 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4521 --n) {
4522 for (i = 0; i < n; ++i) {
4523 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4524 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4525 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004526 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004527 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4528 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004529 pmi->palette_size[1] = n;
4530 for (i = 1; i < 3; ++i) {
4531 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004532#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533 if (cpi->common.use_highbitdepth)
4534 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4535 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4536 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004537#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004538 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4539 clip_pixel((int)centroids[j * 2 + i - 1]);
4540 }
4541 }
4542
Angie Chiang284d7772016-11-08 11:06:45 -08004543 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4544 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004545 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004546 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07004547 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08004548 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004549 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004550 av1_cost_bit(
4551 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004552
4553 for (i = 0; i < rows; ++i) {
4554 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004555 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004556 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004557 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004558 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004559 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4560 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004561 }
4562 }
4563
Angie Chiang284d7772016-11-08 11:06:45 -08004564 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004565 if (this_rd < *best_rd) {
4566 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004567 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004568 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004569 plane_block_width * plane_block_height *
4570 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004571 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004572 *distortion = tokenonly_rd_stats.dist;
4573 *rate_tokenonly = tokenonly_rd_stats.rate;
4574 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575 }
4576 }
4577 }
hui su83c26632017-01-24 17:19:06 -08004578 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004579 memcpy(color_map, best_palette_color_map,
4580 rows * cols * sizeof(best_palette_color_map[0]));
4581 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004582}
Urvang Joshib100db72016-10-12 16:28:56 -07004583#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004584
hui su5db97432016-10-14 16:10:14 -07004585#if CONFIG_FILTER_INTRA
4586// Return 1 if an filter intra mode is selected; return 0 otherwise.
4587static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4588 int *rate, int *rate_tokenonly,
4589 int64_t *distortion, int *skippable,
4590 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004591 MACROBLOCKD *const xd = &x->e_mbd;
4592 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004593 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004594 int this_rate;
4595 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004596 FILTER_INTRA_MODE mode;
4597 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004598 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599
hui su5db97432016-10-14 16:10:14 -07004600 av1_zero(filter_intra_mode_info);
4601 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004602 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004603#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004604 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004605#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004606
4607 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004608 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004609 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610 continue;
4611
Angie Chiang284d7772016-11-08 11:06:45 -08004612 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004613 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004614 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4615 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004616 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004617 if (this_rd < *best_rd) {
4618 *best_rd = this_rd;
4619 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004620 *rate_tokenonly = tokenonly_rd_stats.rate;
4621 *distortion = tokenonly_rd_stats.dist;
4622 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004623 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4624 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004625 }
4626 }
4627
hui su5db97432016-10-14 16:10:14 -07004628 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004629 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004630 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4631 filter_intra_mode_info.use_filter_intra_mode[1];
4632 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4633 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004634 return 1;
4635 } else {
4636 return 0;
4637 }
4638}
hui su5db97432016-10-14 16:10:14 -07004639#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004640
hui su5db97432016-10-14 16:10:14 -07004641#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004642// Run RD calculation with given chroma intra prediction angle., and return
4643// the RD cost. Update the best mode info. if the RD cost is the best so far.
4644static int64_t pick_intra_angle_routine_sbuv(
4645 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4646 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4647 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004648 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004649 int this_rate;
4650 int64_t this_rd;
4651 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004652
hui su45dc5972016-12-08 17:42:50 -08004653 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4654 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004655 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4656 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004657 if (this_rd < *best_rd) {
4658 *best_rd = this_rd;
4659 *best_angle_delta = mbmi->angle_delta[1];
4660 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004661 rd_stats->rate = tokenonly_rd_stats.rate;
4662 rd_stats->dist = tokenonly_rd_stats.dist;
4663 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004664 }
hui su45dc5972016-12-08 17:42:50 -08004665 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004666}
4667
hui su45dc5972016-12-08 17:42:50 -08004668// With given chroma directional intra prediction mode, pick the best angle
4669// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004670static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004671 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004672 int64_t best_rd, int *rate,
4673 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004674 MACROBLOCKD *const xd = &x->e_mbd;
4675 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su45dc5972016-12-08 17:42:50 -08004676 int i, angle_delta, best_angle_delta = 0;
4677 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA_UV + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004678
hui su45dc5972016-12-08 17:42:50 -08004679 rd_stats->rate = INT_MAX;
4680 rd_stats->skip = 0;
4681 rd_stats->dist = INT64_MAX;
4682 for (i = 0; i < 2 * (MAX_ANGLE_DELTA_UV + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004683
hui su45dc5972016-12-08 17:42:50 -08004684 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4685 for (i = 0; i < 2; ++i) {
4686 best_rd_in = (best_rd == INT64_MAX)
4687 ? INT64_MAX
4688 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4689 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4690 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4691 best_rd_in, rate, rd_stats,
4692 &best_angle_delta, &best_rd);
4693 rd_cost[2 * angle_delta + i] = this_rd;
4694 if (angle_delta == 0) {
4695 if (this_rd == INT64_MAX) return 0;
4696 rd_cost[1] = this_rd;
4697 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 }
4699 }
hui su45dc5972016-12-08 17:42:50 -08004700 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004701
hui su45dc5972016-12-08 17:42:50 -08004702 assert(best_rd != INT64_MAX);
4703 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4704 int64_t rd_thresh;
4705 for (i = 0; i < 2; ++i) {
4706 int skip_search = 0;
4707 rd_thresh = best_rd + (best_rd >> 5);
4708 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4709 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4710 skip_search = 1;
4711 if (!skip_search) {
4712 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4713 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4714 best_rd, rate, rd_stats,
4715 &best_angle_delta, &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004716 }
4717 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004718 }
4719
4720 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004721 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004722}
4723#endif // CONFIG_EXT_INTRA
4724
Urvang Joshi52648442016-10-13 17:27:51 -07004725static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4726 int *rate, int *rate_tokenonly,
4727 int64_t *distortion, int *skippable,
4728 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004729 MACROBLOCKD *xd = &x->e_mbd;
4730 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su83c26632017-01-24 17:19:06 -08004731 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004733 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004734 int this_rate;
4735 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004736#if CONFIG_PVQ
4737 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004738 od_encode_checkpoint(&x->daala_enc, &buf);
4739#endif
Urvang Joshib100db72016-10-12 16:28:56 -07004740#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004741 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004742 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004743#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004744
hui su83c26632017-01-24 17:19:06 -08004745#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004746 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4747#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004748#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004749 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004750#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004751 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004752#if CONFIG_EXT_INTRA
4753 const int is_directional_mode =
4754 av1_is_directional_mode(mode, mbmi->sb_type);
4755#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004756 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4757 (1 << mode)))
4758 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004759
4760 mbmi->uv_mode = mode;
4761#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004763 if (is_directional_mode) {
hui su83c26632017-01-24 17:19:06 -08004764 const int rate_overhead =
4765 cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4766 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004767 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4768 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004769 continue;
4770 } else {
hui su83c26632017-01-24 17:19:06 -08004771#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004772 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004773#if CONFIG_PVQ
4774 od_encode_rollback(&x->daala_enc, &buf);
4775#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004776 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004777 }
hui su83c26632017-01-24 17:19:06 -08004778#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004779 }
hui su83c26632017-01-24 17:19:06 -08004780#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004781 this_rate =
4782 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004783
4784#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004785 if (is_directional_mode) {
4786 this_rate +=
4787 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
4788 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
4789 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004790#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004791#if CONFIG_FILTER_INTRA
4792 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4793 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4794#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004795#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004796 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4797 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004798 this_rate += av1_cost_bit(
4799 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004800#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004801
Yushin Cho77bba8d2016-11-04 16:36:56 -07004802#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004803 od_encode_rollback(&x->daala_enc, &buf);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004804#endif
Yushin Cho5c207292017-02-16 15:01:33 -08004805 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004806
4807 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004808 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004809 best_rd = this_rd;
4810 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004811 *rate_tokenonly = tokenonly_rd_stats.rate;
4812 *distortion = tokenonly_rd_stats.dist;
4813 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004814 }
4815 }
4816
Urvang Joshib100db72016-10-12 16:28:56 -07004817#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004818 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4819 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004820 rd_pick_palette_intra_sbuv(cpi, x,
4821 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4822 best_palette_color_map, &best_mbmi, &best_rd,
4823 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 }
Urvang Joshib100db72016-10-12 16:28:56 -07004825#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004826
hui su5db97432016-10-14 16:10:14 -07004827#if CONFIG_FILTER_INTRA
4828 if (mbmi->sb_type >= BLOCK_8X8) {
4829 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004830 skippable, bsize, &best_rd))
4831 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004832 }
hui su5db97432016-10-14 16:10:14 -07004833#endif // CONFIG_FILTER_INTRA
4834
hui su83c26632017-01-24 17:19:06 -08004835 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004836 // Make sure we actually chose a mode
4837 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004838 return best_rd;
4839}
4840
Urvang Joshi52648442016-10-13 17:27:51 -07004841static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4843 TX_SIZE max_tx_size, int *rate_uv,
4844 int *rate_uv_tokenonly, int64_t *dist_uv,
4845 int *skip_uv, PREDICTION_MODE *mode_uv) {
4846 // Use an estimated rd for uv_intra based on DC_PRED if the
4847 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004848 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004849#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004850#if CONFIG_CHROMA_2X2
4851 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4852 bsize, max_tx_size);
4853#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004854 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4855 if (x->skip_chroma_rd) {
4856 *rate_uv = 0;
4857 *rate_uv_tokenonly = 0;
4858 *dist_uv = 0;
4859 *skip_uv = 1;
4860 *mode_uv = DC_PRED;
4861 return;
4862 }
Jingning Han3f167252016-06-07 16:11:42 -07004863 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4864 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004865#endif // CONFIG_CHROMA_2X2
4866#else
4867 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4868 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4869#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004870 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4871}
4872
Urvang Joshi52648442016-10-13 17:27:51 -07004873static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004874#if CONFIG_REF_MV && CONFIG_EXT_INTER
4875 int is_compound,
4876#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4877 int16_t mode_context) {
4878#if CONFIG_REF_MV
4879 int mode_cost = 0;
4880#if CONFIG_EXT_INTER
4881 int16_t mode_ctx =
4882 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4883#else
4884 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4885#endif // CONFIG_EXT_INTER
4886 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4887
4888 assert(is_inter_mode(mode));
4889
4890#if CONFIG_EXT_INTER
4891 if (is_compound) {
clang-format55ce9e02017-02-15 22:27:12 -08004892 return cpi
4893 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004894 } else {
4895 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4896#else
4897 if (mode == NEWMV) {
4898#endif // CONFIG_EXT_INTER
4899 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4900#if CONFIG_EXT_INTER
4901 if (!is_compound)
4902 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4903#endif // CONFIG_EXT_INTER
4904 return mode_cost;
4905 } else {
4906 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4907 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4908
4909 if (is_all_zero_mv) return mode_cost;
4910
4911 if (mode == ZEROMV) {
4912 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4913 return mode_cost;
4914 } else {
4915 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4916 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4917
4918 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4919 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4920 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4921
4922 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4923 return mode_cost;
4924 }
4925 }
4926#if CONFIG_EXT_INTER
4927 }
4928#endif // CONFIG_EXT_INTER
4929#else
4930 assert(is_inter_mode(mode));
4931#if CONFIG_EXT_INTER
4932 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004933 return cpi
4934 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004935 } else {
4936#endif // CONFIG_EXT_INTER
4937 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4938#if CONFIG_EXT_INTER
4939 }
4940#endif // CONFIG_EXT_INTER
4941#endif
4942}
4943
Sarah Parker6fdc8532016-11-16 17:47:13 -08004944#if CONFIG_EXT_INTER
4945static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4946 COMPOUND_TYPE comp_type) {
4947 switch (comp_type) {
4948 case COMPOUND_AVERAGE: return 0;
4949 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Sarah Parker2f6ce752016-12-08 15:26:46 -08004950#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08004951 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08004952#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08004953 default: assert(0); return 0;
4954 }
4955}
4956#endif // CONFIG_EXT_INTER
4957
Sarah Parkere5299862016-08-16 14:57:37 -07004958#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004959static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08004960 static const int gm_amortization_blks[TRANS_TYPES] = {
4961 4, 6, 8, 10, 10, 10, 12
4962 };
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004963 static const int gm_params_cost[TRANS_TYPES] = {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08004964 GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
4965 GM_AFFINE_BITS, GM_HORTRAPEZOID_BITS, GM_VERTRAPEZOID_BITS,
4966 GM_HOMOGRAPHY_BITS,
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004967 };
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004968 const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004969 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
Debargha Mukherjee705544c2016-11-22 08:55:49 -08004970 if (cpi->global_motion_used[ref][0] >= gm_amortization_blks[gm->wmtype]) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004971 return 0;
4972 } else {
4973 const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
4974 cpi->gmtype_cost[gm->wmtype];
4975 return cost / gm_amortization_blks[gm->wmtype];
4976 }
Sarah Parkere5299862016-08-16 14:57:37 -07004977}
Sarah Parkere5299862016-08-16 14:57:37 -07004978#endif // CONFIG_GLOBAL_MOTION
4979
clang-format55ce9e02017-02-15 22:27:12 -08004980static int set_and_cost_bmi_mvs(
4981 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
4982 PREDICTION_MODE mode, int_mv this_mv[2],
4983 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
4984 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004985#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08004986 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004987#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00004988 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
4989 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004990 MODE_INFO *const mic = xd->mi[0];
4991 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4992 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4993 int thismvcost = 0;
4994 int idx, idy;
4995 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4996 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4997 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004998 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00004999 (void)mi_row;
5000 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005001
5002 switch (mode) {
5003 case NEWMV:
5004#if CONFIG_EXT_INTER
5005 case NEWFROMNEARMV:
5006#endif // CONFIG_EXT_INTER
5007 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5008#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005009 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005010 lower_mv_precision(&this_mv[0].as_mv, 0);
5011#endif // CONFIG_EXT_INTER
5012
5013#if CONFIG_REF_MV
5014 for (idx = 0; idx < 1 + is_compound; ++idx) {
5015 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005016 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005017 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005018 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5019 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 }
5021 (void)mvjcost;
5022 (void)mvcost;
5023#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005024 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5025 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005026#if !CONFIG_EXT_INTER
5027 if (is_compound) {
5028 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005029 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5030 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005031 }
5032#endif // !CONFIG_EXT_INTER
5033#endif
5034 break;
5035 case NEARMV:
5036 case NEARESTMV:
5037 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5038 if (is_compound)
5039 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5040 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005041 case ZEROMV: {
5042 int ref;
5043 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005044#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005045 this_mv[ref].as_int =
5046 gm_get_motion_vector(
5047 &cpi->common.global_motion[mbmi->ref_frame[ref]],
David Barker45390c12017-02-20 14:44:40 +00005048 cpi->common.allow_high_precision_mv,
5049 mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005050 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005051 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[ref]);
5052#else
5053 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005054#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005055 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005056 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005057 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005058#if CONFIG_EXT_INTER
5059 case NEW_NEWMV:
5060 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5061 compound_seg_newmvs[1].as_int == INVALID_MV) {
5062 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5063 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5064 } else {
5065 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5066 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5067 }
Alex Converse6317c882016-09-29 14:21:37 -07005068 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005069 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005070 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005071 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005072 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5073 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
5074 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5075 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005076 break;
5077 case NEW_NEARMV:
5078 case NEW_NEARESTMV:
5079 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005080 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005082 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5083 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005084 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5085 break;
5086 case NEAR_NEWMV:
5087 case NEAREST_NEWMV:
5088 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5089 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005090 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005091 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005092 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5093 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005094 break;
5095 case NEAREST_NEARMV:
5096 case NEAR_NEARESTMV:
5097 case NEAREST_NEARESTMV:
5098 case NEAR_NEARMV:
5099 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5100 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5101 break;
5102 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005103#if CONFIG_GLOBAL_MOTION
5104 this_mv[0].as_int =
5105 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005106 cpi->common.allow_high_precision_mv,
5107 mi_col * MI_SIZE + MI_SIZE / 2,
5108 mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005109 .as_int;
5110 this_mv[1].as_int =
5111 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005112 cpi->common.allow_high_precision_mv,
5113 mi_col * MI_SIZE + MI_SIZE / 2,
5114 mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005115 .as_int;
5116 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]) +
5117 GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
5118#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005119 this_mv[0].as_int = 0;
5120 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005121#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005122 break;
5123#endif // CONFIG_EXT_INTER
5124 default: break;
5125 }
5126
5127 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5128 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5129
5130 mic->bmi[i].as_mode = mode;
5131
5132#if CONFIG_REF_MV
5133 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005134 mic->bmi[i].pred_mv[0].as_int =
5135 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5136 if (is_compound)
5137 mic->bmi[i].pred_mv[1].as_int =
5138 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005139 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005140 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5141 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005142 }
5143#endif
5144
5145 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5146 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5147 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5148
5149#if CONFIG_REF_MV
5150#if CONFIG_EXT_INTER
5151 if (is_compound)
5152 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5153 else
5154#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005155 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5156 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005157#else // CONFIG_REF_MV
5158 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
5159#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005160#if CONFIG_REF_MV && CONFIG_EXT_INTER
5161 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
5162#else
5163 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
5164#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5165}
5166
Yushin Choab44fd12017-01-09 16:06:53 -08005167static int64_t encode_inter_mb_segment_sub8x8(
5168 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5169 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5170 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005171 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005172 MACROBLOCKD *xd = &x->e_mbd;
5173 struct macroblockd_plane *const pd = &xd->plane[0];
5174 struct macroblock_plane *const p = &x->plane[0];
5175 MODE_INFO *const mi = xd->mi[0];
5176 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005177 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5178 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005179 const int width = block_size_wide[plane_bsize];
5180 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005181 int idx, idy;
5182 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005183 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005184 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005185 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005186 int64_t thisdistortion = 0, thissse = 0;
5187 int thisrate = 0;
5188 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005189 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005190 const int num_4x4_w = tx_size_wide_unit[tx_size];
5191 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005192#if !CONFIG_PVQ
5193 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5194#else
5195 (void)cpi;
5196 (void)ta;
5197 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005198 (void)tx_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005199#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005200
5201#if CONFIG_EXT_TX && CONFIG_RECT_TX
5202 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5203 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5204 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5205#else
5206 assert(tx_size == TX_4X4);
5207#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005208
Yaowu Xuc27fc142016-08-22 16:08:15 -07005209 assert(tx_type == DCT_DCT);
5210
Yaowu Xuf883b422016-08-30 14:01:10 -07005211 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212
Yaowu Xuf883b422016-08-30 14:01:10 -07005213#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005214 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005215 aom_highbd_subtract_block(
5216 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5217 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005218 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005219 aom_subtract_block(height, width,
5220 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005221 8, src, p->src.stride, dst, pd->dst.stride);
5222 }
5223#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005224 aom_subtract_block(height, width,
5225 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005226 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07005227#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005228
Jingning Hanbafee8d2016-12-02 10:25:03 -08005229 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5230 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005233 const int k = i + (idy * 2 + idx);
5234 const int block = av1_raster_order_to_block_index(tx_size, k);
5235 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5236 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005237 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Yushin Cho38395482017-01-03 13:10:41 -08005238#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005240 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5241 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005242#else
Angie Chiangff6d8902016-10-21 11:02:09 -07005243 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005244 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005245#endif // CONFIG_NEW_QUANT
5246 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07005247 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07005248#else
Yushin Cho38395482017-01-03 13:10:41 -08005249 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5250 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yushin Cho77bba8d2016-11-04 16:36:56 -07005251#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005252 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
5253 &dist, &ssz);
5254 thisdistortion += dist;
5255 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005256#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005257 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07005258 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005259 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005260 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5261 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005262#else
5263 thisrate += x->rate;
5264 *(ta + (k & 1)) = !x->pvq_skip[0];
5265 *(tl + (k >> 1)) = !x->pvq_skip[0];
5266#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267#if CONFIG_EXT_TX
5268 if (tx_size == TX_8X4) {
5269 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5270 }
5271 if (tx_size == TX_4X8) {
5272 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5273 }
5274#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005275 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5276 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005277 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005278 if (rd >= best_yrd) return INT64_MAX;
5279 }
5280 }
5281
5282 *distortion = thisdistortion;
5283 *labelyrate = thisrate;
5284 *sse = thissse;
5285
5286 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5287}
5288
5289typedef struct {
5290 int eobs;
5291 int brate;
5292 int byrate;
5293 int64_t bdist;
5294 int64_t bsse;
5295 int64_t brdcost;
5296 int_mv mvs[2];
5297#if CONFIG_REF_MV
5298 int_mv pred_mv[2];
5299#endif
5300#if CONFIG_EXT_INTER
5301 int_mv ref_mv[2];
5302#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005303
5304#if CONFIG_CB4X4
5305 ENTROPY_CONTEXT ta[4];
5306 ENTROPY_CONTEXT tl[4];
5307#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 ENTROPY_CONTEXT ta[2];
5309 ENTROPY_CONTEXT tl[2];
Jingning Han276c2942016-12-05 12:37:02 -08005310#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005311} SEG_RDSTAT;
5312
5313typedef struct {
5314 int_mv *ref_mv[2];
5315 int_mv mvp;
5316
5317 int64_t segment_rd;
5318 int r;
5319 int64_t d;
5320 int64_t sse;
5321 int segment_yrate;
5322 PREDICTION_MODE modes[4];
5323#if CONFIG_EXT_INTER
5324 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5325#else
5326 SEG_RDSTAT rdstat[4][INTER_MODES];
5327#endif // CONFIG_EXT_INTER
5328 int mvthresh;
5329} BEST_SEG_INFO;
5330
5331static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
5332 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
5333 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
5334}
5335
5336static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5337 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5338 struct macroblock_plane *const p = &x->plane[0];
5339 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5340
5341 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005342 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005343 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5344 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005345 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005346 if (has_second_ref(mbmi))
5347 pd->pre[1].buf =
5348 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005349 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005350}
5351
5352static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5353 struct buf_2d orig_pre[2]) {
5354 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5355 x->plane[0].src = orig_src;
5356 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5357 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5358}
5359
5360// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5361// TODO(aconverse): Find out if this is still productive then clean up or remove
5362static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005363 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364#if CONFIG_REF_MV && CONFIG_EXT_INTER
5365 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
5366#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5367 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005368 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5369 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005370 int_mv zeromv[2];
5371 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5372 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005373 (void)mi_row;
5374 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005375 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5376#if CONFIG_GLOBAL_MOTION
5377 if (this_mode == ZEROMV
5378#if CONFIG_EXT_INTER
5379 || this_mode == ZERO_ZEROMV
5380#endif // CONFIG_EXT_INTER
5381 )
5382 zeromv[cur_frm].as_int =
5383 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
David Barker45390c12017-02-20 14:44:40 +00005384 cpi->common.allow_high_precision_mv,
5385 mi_col * MI_SIZE + MI_SIZE / 2,
5386 mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005387 .as_int;
5388 else
5389#endif // CONFIG_GLOBAL_MOTION
5390 zeromv[cur_frm].as_int = 0;
5391 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005392#if !CONFIG_EXT_INTER
5393 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
5394#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005395 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005396 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005397 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005398 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399#if CONFIG_REF_MV
5400 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005401 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005402#else
5403 int16_t rfc = mode_context[ref_frames[0]];
5404#endif
5405#if CONFIG_REF_MV && CONFIG_EXT_INTER
5406 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
5407 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
5408 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
5409#else
5410 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5411 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5412 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
5413#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5414
5415#if !CONFIG_REF_MV
5416 (void)bsize;
5417 (void)block;
5418#endif
5419
5420 if (this_mode == NEARMV) {
5421 if (c1 > c3) return 0;
5422 } else if (this_mode == NEARESTMV) {
5423 if (c2 > c3) return 0;
5424 } else {
5425 assert(this_mode == ZEROMV);
5426 if (ref_frames[1] <= INTRA_FRAME) {
5427 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5428 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5429 return 0;
5430 } else {
5431 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5432 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5433 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5434 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5435 return 0;
5436 }
5437 }
5438 }
5439#if CONFIG_EXT_INTER
5440 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
5441 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
5442 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005443 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5444 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005445#if CONFIG_REF_MV
5446 int16_t rfc = compound_mode_context[ref_frames[0]];
5447 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
5448 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
5449 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
5450 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
5451 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
5452#else
5453 int16_t rfc = mode_context[ref_frames[0]];
5454 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
5455 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5456 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
5457 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
5458 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
5459#endif
5460
5461 if (this_mode == NEAREST_NEARMV) {
5462 if (c1 > c3) return 0;
5463 } else if (this_mode == NEAREST_NEARESTMV) {
5464 if (c2 > c3) return 0;
5465 } else if (this_mode == NEAR_NEARESTMV) {
5466 if (c4 > c3) return 0;
5467 } else if (this_mode == NEAR_NEARMV) {
5468 if (c5 > c3) return 0;
5469 } else {
5470 assert(this_mode == ZERO_ZEROMV);
5471 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5472 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
5473 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
5474 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
5475 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
5476 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
5477 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
5478 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
5479 return 0;
5480 }
5481 }
5482#endif // CONFIG_EXT_INTER
5483 return 1;
5484}
5485
Urvang Joshi52648442016-10-13 17:27:51 -07005486static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5487 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5488 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005489#if CONFIG_EXT_INTER
5490 int_mv *ref_mv_sub8x8[2],
5491#endif
5492 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
5493 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005494 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005495 const int pw = block_size_wide[bsize];
5496 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005497 MACROBLOCKD *xd = &x->e_mbd;
5498 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5499 const int refs[2] = { mbmi->ref_frame[0],
5500 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
5501 int_mv ref_mv[2];
5502 int ite, ref;
5503#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005504 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005505 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5506 mbmi->interp_filter[3],
5507 };
5508#else
James Zern7b9407a2016-05-18 23:48:05 -07005509 const InterpFilter interp_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005510#endif
5511 struct scale_factors sf;
5512
5513 // Do joint motion search in compound mode to get more accurate mv.
5514 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5515 int last_besterr[2] = { INT_MAX, INT_MAX };
5516 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07005517 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
5518 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005519 };
5520
5521// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005522#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005523 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5524 uint8_t *second_pred;
5525#else
5526 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005527#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005528
Jingning Han61418bb2017-01-23 17:12:48 -08005529#if CONFIG_EXT_INTER && CONFIG_CB4X4
5530 (void)ref_mv_sub8x8;
5531#endif
5532
Yaowu Xuc27fc142016-08-22 16:08:15 -07005533 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005534#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005535 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5536 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5537 else
5538#endif // CONFIG_EXT_INTER
5539 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5540
5541 if (scaled_ref_frame[ref]) {
5542 int i;
5543 // Swap out the reference frame for a version that's been scaled to
5544 // match the resolution of the current frame, allowing the existing
5545 // motion search code to be used without additional modifications.
5546 for (i = 0; i < MAX_MB_PLANE; i++)
5547 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005548 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5549 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550 }
5551
5552 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
5553 }
5554
5555// Since we have scaled the reference frames to match the size of the current
5556// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07005557#if CONFIG_AOM_HIGHBITDEPTH
5558 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5559 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005560#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005561 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5562 cm->height);
5563#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005564
5565 // Allow joint search multiple times iteratively for each reference frame
5566 // and break out of the search loop if it couldn't find a better mv.
5567 for (ite = 0; ite < 4; ite++) {
5568 struct buf_2d ref_yv12[2];
5569 int bestsme = INT_MAX;
5570 int sadpb = x->sadperbit16;
5571 MV *const best_mv = &x->best_mv.as_mv;
5572 int search_range = 3;
5573
5574 int tmp_col_min = x->mv_col_min;
5575 int tmp_col_max = x->mv_col_max;
5576 int tmp_row_min = x->mv_row_min;
5577 int tmp_row_max = x->mv_row_max;
5578 int id = ite % 2; // Even iterations search in the first reference frame,
5579 // odd iterations search in the second. The predictor
5580 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005581 const int plane = 0;
5582 ConvolveParams conv_params = get_conv_params(0, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583
5584 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005585 ref_yv12[0] = xd->plane[plane].pre[0];
5586 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587
5588#if CONFIG_DUAL_FILTER
5589 // reload the filter types
5590 interp_filter[0] =
5591 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5592 interp_filter[1] =
5593 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
5594#endif
5595
5596// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005597#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005598 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5599 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005600 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005601 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5602 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
5603 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd->bd);
5604 } else {
5605 second_pred = (uint8_t *)second_pred_alloc_16;
Angie Chiang9f45bc42017-01-13 16:27:54 -08005606 av1_build_inter_predictor(
5607 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5608 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
5609 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610 }
5611#else
Angie Chiang9f45bc42017-01-13 16:27:54 -08005612 av1_build_inter_predictor(
5613 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5614 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
5615 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07005616#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617
5618 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005619 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005620 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621
5622 // Use the mv result from the single mode as mv predictor.
5623 *best_mv = frame_mv[refs[id]].as_mv;
5624
5625 best_mv->col >>= 3;
5626 best_mv->row >>= 3;
5627
5628#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005629 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630#endif
5631
5632 // Small-range full-pixel motion search.
5633 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005634 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5635 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005637 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5638 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005639
5640 x->mv_col_min = tmp_col_min;
5641 x->mv_col_max = tmp_col_max;
5642 x->mv_row_min = tmp_row_min;
5643 x->mv_row_max = tmp_row_max;
5644
5645 if (bestsme < INT_MAX) {
5646 int dis; /* TODO: use dis in distortion calculation later. */
5647 unsigned int sse;
5648 if (cpi->sf.use_upsampled_references) {
5649 // Use up-sampled reference frames.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005650 struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 struct buf_2d backup_pred = pd->pre[0];
5652 const YV12_BUFFER_CONFIG *upsampled_ref =
5653 get_upsampled_ref(cpi, refs[id]);
5654
5655 // Set pred for Y plane
5656 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5657 upsampled_ref->y_crop_width,
5658 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5659 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5660 pd->subsampling_y);
5661
Jingning Han271bb2c2016-12-14 12:34:46 -08005662// If bsize < BLOCK_8X8, adjust pred pointer for this block
5663#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664 if (bsize < BLOCK_8X8)
5665 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005666 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5667 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005668 << 3];
Jingning Han271bb2c2016-12-14 12:34:46 -08005669#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005670
5671 bestsme = cpi->find_fractional_mv_step(
5672 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5673 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5674 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5675 &dis, &sse, second_pred, pw, ph, 1);
5676
5677 // Restore the reference frames.
5678 pd->pre[0] = backup_pred;
5679 } else {
5680 (void)block;
5681 bestsme = cpi->find_fractional_mv_step(
5682 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5683 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5684 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5685 &dis, &sse, second_pred, pw, ph, 0);
5686 }
5687 }
5688
5689 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005690 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005691
5692 if (bestsme < last_besterr[id]) {
5693 frame_mv[refs[id]].as_mv = *best_mv;
5694 last_besterr[id] = bestsme;
5695 } else {
5696 break;
5697 }
5698 }
5699
5700 *rate_mv = 0;
5701
5702 for (ref = 0; ref < 2; ++ref) {
5703 if (scaled_ref_frame[ref]) {
5704 // Restore the prediction frame pointers to their unscaled versions.
5705 int i;
5706 for (i = 0; i < MAX_MB_PLANE; i++)
5707 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5708 }
5709#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005710 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005711#endif
Jingning Han61418bb2017-01-23 17:12:48 -08005712#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713 if (bsize >= BLOCK_8X8)
5714#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005715 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5716 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5717 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005718#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005719 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005720 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5721 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5722 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005723#endif // CONFIG_EXT_INTER
5724 }
5725}
5726
Yushin Cho482016d2017-01-06 14:06:13 -08005727static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005728 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005729 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5730 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5731 int mvthresh,
5732#if CONFIG_EXT_INTER
5733 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5734 int_mv compound_seg_newmvs[4][2],
5735#else
5736 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5737#endif // CONFIG_EXT_INTER
5738 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5739 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5740#if CONFIG_REF_MV
5741 int_mv tmp_ref_mv[2];
5742#endif
5743 MACROBLOCKD *xd = &x->e_mbd;
5744 MODE_INFO *mi = xd->mi[0];
5745 MB_MODE_INFO *mbmi = &mi->mbmi;
5746 int mode_idx;
5747 int k, br = 0, idx, idy;
5748 int64_t bd = 0, block_sse = 0;
5749 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005750 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005751 struct macroblock_plane *const p = &x->plane[0];
5752 struct macroblockd_plane *const pd = &xd->plane[0];
5753 const int label_count = 4;
5754 int64_t this_segment_rd = 0;
5755 int label_mv_thresh;
5756 int segmentyrate = 0;
5757 const BLOCK_SIZE bsize = mbmi->sb_type;
5758 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5759 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005760#if CONFIG_CB4X4
5761 ENTROPY_CONTEXT t_above[4], t_left[4];
5762#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005763 ENTROPY_CONTEXT t_above[2], t_left[2];
Jingning Han276c2942016-12-05 12:37:02 -08005764#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005765 int subpelmv = 1, have_ref = 0;
5766 const int has_second_rf = has_second_ref(mbmi);
5767 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5768 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005769#if CONFIG_PVQ
5770 od_rollback_buffer pre_buf;
5771
5772 od_encode_checkpoint(&x->daala_enc, &pre_buf);
5773#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005774#if CONFIG_EXT_TX && CONFIG_RECT_TX
5775 mbmi->tx_size =
5776 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5777#else
5778 mbmi->tx_size = TX_4X4;
5779#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5780
Yaowu Xuf883b422016-08-30 14:01:10 -07005781 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005782
5783 bsi->segment_rd = best_rd;
5784 bsi->ref_mv[0] = best_ref_mv;
5785 bsi->ref_mv[1] = second_best_ref_mv;
5786 bsi->mvp.as_int = best_ref_mv->as_int;
5787 bsi->mvthresh = mvthresh;
5788
5789 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5790
5791#if CONFIG_REFMV
5792 for (idx = 0; idx < 4; ++idx) {
5793 for (k = NEARESTMV; k <= NEWMV; ++k) {
5794 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5795 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5796
5797 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5798 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5799 }
5800 }
5801#endif
5802
5803 memcpy(t_above, pd->above_context, sizeof(t_above));
5804 memcpy(t_left, pd->left_context, sizeof(t_left));
5805
5806 // 64 makes this threshold really big effectively
5807 // making it so that we very rarely check mvs on
5808 // segments. setting this to 1 would make mv thresh
5809 // roughly equal to what it is for macroblocks
5810 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5811
5812 // Segmentation method overheads
5813 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5814 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5815 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5816 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5817 int_mv mode_mv[MB_MODE_COUNT][2];
5818 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5819 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005820 int64_t new_best_rd = INT64_MAX;
5821 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005822 int ref;
5823#if CONFIG_REF_MV
5824 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5825 uint8_t ref_mv_count[2];
5826#endif
5827#if CONFIG_EXT_INTER
5828 int mv_idx;
5829 int_mv ref_mvs_sub8x8[2][2];
5830#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005831#if CONFIG_PVQ
5832 od_rollback_buffer idx_buf, post_buf;
5833 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5834 od_encode_checkpoint(&x->daala_enc, &post_buf);
5835#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836
5837 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5838 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5839#if CONFIG_EXT_INTER
5840 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Urvang Joshi454280d2016-10-14 16:51:44 -07005841 av1_update_mv_context(xd, mi, frame, mv_ref_list, index, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005842 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005844#if CONFIG_GLOBAL_MOTION
5845 frame_mv[ZEROMV][frame].as_int =
David Barker45390c12017-02-20 14:44:40 +00005846 gm_get_motion_vector(
5847 &cm->global_motion[frame], cm->allow_high_precision_mv,
5848 mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +00005849 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005850#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005851 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005852#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005853 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005854#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005855 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005856#endif
5857#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005858 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005859#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005860 &frame_mv[NEARESTMV][frame],
5861 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005862
5863#if CONFIG_REF_MV
5864 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5865 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5866 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5867 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
5868#endif
5869
5870#if CONFIG_EXT_INTER
5871 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5872 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005873 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5874 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005875
5876 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005877#if CONFIG_GLOBAL_MOTION
5878 frame_mv[ZERO_ZEROMV][frame].as_int =
5879 gm_get_motion_vector(&cm->global_motion[frame],
David Barker45390c12017-02-20 14:44:40 +00005880 cm->allow_high_precision_mv,
5881 mi_col * MI_SIZE + MI_SIZE / 2,
5882 mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005883 .as_int;
5884#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005885 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005886#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005887 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5888 frame_mv[NEARESTMV][frame].as_int;
5889
5890 if (ref == 0) {
5891 frame_mv[NEAREST_NEARMV][frame].as_int =
5892 frame_mv[NEARESTMV][frame].as_int;
5893 frame_mv[NEAR_NEARESTMV][frame].as_int =
5894 frame_mv[NEARMV][frame].as_int;
5895 frame_mv[NEAREST_NEWMV][frame].as_int =
5896 frame_mv[NEARESTMV][frame].as_int;
5897 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5898 frame_mv[NEAR_NEARMV][frame].as_int =
5899 frame_mv[NEARMV][frame].as_int;
5900 } else if (ref == 1) {
5901 frame_mv[NEAREST_NEARMV][frame].as_int =
5902 frame_mv[NEARMV][frame].as_int;
5903 frame_mv[NEAR_NEARESTMV][frame].as_int =
5904 frame_mv[NEARESTMV][frame].as_int;
5905 frame_mv[NEW_NEARESTMV][frame].as_int =
5906 frame_mv[NEARESTMV][frame].as_int;
5907 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5908 frame_mv[NEAR_NEARMV][frame].as_int =
5909 frame_mv[NEARMV][frame].as_int;
5910 }
5911 }
5912#endif // CONFIG_EXT_INTER
5913 }
5914
5915// search for the best motion vector on this segment
5916#if CONFIG_EXT_INTER
5917 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5918 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5919 ++this_mode)
5920#else
5921 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5922#endif // CONFIG_EXT_INTER
5923 {
5924 const struct buf_2d orig_src = x->plane[0].src;
5925 struct buf_2d orig_pre[2];
5926 // This flag controls if the motion estimation will kick off. When it
5927 // is set to a non-zero value, the encoder will force motion estimation.
5928 int run_mv_search = 0;
5929
5930 mode_idx = INTER_OFFSET(this_mode);
5931#if CONFIG_EXT_INTER
5932 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5933
5934 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5935 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5936#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005937 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005938 if (!(inter_mode_mask & (1 << this_mode))) continue;
5939
5940#if CONFIG_REF_MV
5941 run_mv_search = 2;
5942#if !CONFIG_EXT_INTER
5943 if (filter_idx > 0 && this_mode == NEWMV) {
5944 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005945 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005946
5947 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005948 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005949 ref_rdstat->mvs[0].as_int &&
5950 ref_rdstat->mvs[0].as_int != INVALID_MV)
5951 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5952 --run_mv_search;
5953
Urvang Joshi454280d2016-10-14 16:51:44 -07005954 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005955 ref_rdstat->mvs[1].as_int &&
5956 ref_rdstat->mvs[1].as_int != INVALID_MV)
5957 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5958 --run_mv_search;
5959 } else {
5960 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5961 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5962 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005963 seg_mvs[index][mbmi->ref_frame[0]].as_int =
5964 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965 }
5966 }
5967
5968 if (run_mv_search != 0 && filter_idx > 1) {
5969 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005970 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971 run_mv_search = 2;
5972
5973 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005974 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005975 ref_rdstat->mvs[0].as_int &&
5976 ref_rdstat->mvs[0].as_int != INVALID_MV)
5977 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5978 --run_mv_search;
5979
Urvang Joshi454280d2016-10-14 16:51:44 -07005980 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005981 ref_rdstat->mvs[1].as_int &&
5982 ref_rdstat->mvs[1].as_int != INVALID_MV)
5983 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5984 --run_mv_search;
5985 } else {
5986 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5987 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5988 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07005989 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005990 ref_rdstat->mvs[0].as_int;
5991 }
5992 }
5993 }
5994 }
5995#endif // CONFIG_EXT_INTER
5996#endif // CONFIG_REF_MV
5997
Sarah Parkere5299862016-08-16 14:57:37 -07005998#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005999 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07006000 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00006001 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07006002#endif // CONFIG_GLOBAL_MOTION
6003
6004 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006005#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006006 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006007#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006008 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00006009 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07006010 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006011
6012 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07006013 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
6014 sizeof(bsi->rdstat[index][mode_idx].ta));
6015 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
6016 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006017#if CONFIG_PVQ
6018 od_encode_rollback(&x->daala_enc, &idx_buf);
6019#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006020
6021 // motion search for newmv (single predictor case only)
6022 if (!has_second_rf &&
6023#if CONFIG_EXT_INTER
6024 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07006025 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006026#else
6027 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006028 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07006029 run_mv_search)
6030#endif // CONFIG_EXT_INTER
6031 ) {
6032 int step_param = 0;
6033 int bestsme = INT_MAX;
6034 int sadpb = x->sadperbit4;
6035 MV mvp_full;
6036 int max_mv;
6037 int cost_list[5];
6038 int tmp_col_min = x->mv_col_min;
6039 int tmp_col_max = x->mv_col_max;
6040 int tmp_row_min = x->mv_row_min;
6041 int tmp_row_max = x->mv_row_max;
6042
6043 /* Is the best so far sufficiently good that we cant justify doing
6044 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07006045 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006046
6047 if (cpi->oxcf.mode != BEST) {
6048#if CONFIG_EXT_INTER
6049 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
6050#else
6051// use previous block's result as next block's MV predictor.
6052#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006053 if (index > 0) {
6054 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
6055 if (index == 2)
6056 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057 }
6058#endif
6059#endif // CONFIG_EXT_INTER
6060 }
Urvang Joshi454280d2016-10-14 16:51:44 -07006061 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
6062 : AOMMAX(abs(bsi->mvp.as_mv.row),
6063 abs(bsi->mvp.as_mv.col)) >>
6064 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006065
6066 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6067 // Take wtd average of the step_params based on the last frame's
6068 // max mv magnitude and the best ref mvs of the current block for
6069 // the given reference.
6070 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006071 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006072 } else {
6073 step_param = cpi->mv_step_param;
6074 }
6075
6076#if CONFIG_REF_MV
6077 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
6078 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
6079#else
6080 mvp_full.row = bsi->mvp.as_mv.row >> 3;
6081 mvp_full.col = bsi->mvp.as_mv.col >> 3;
6082#endif
6083
6084 if (cpi->sf.adaptive_motion_search) {
6085 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
6086 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07006087 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006088 }
6089
6090 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07006091 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006092
Yaowu Xuf883b422016-08-30 14:01:10 -07006093 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094
6095 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6096
6097#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006098 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006099#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07006100 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006101 cpi, x, bsize, &mvp_full, step_param, sadpb,
6102 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6103 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6104
6105 x->mv_col_min = tmp_col_min;
6106 x->mv_col_max = tmp_col_max;
6107 x->mv_row_min = tmp_row_min;
6108 x->mv_row_max = tmp_row_max;
6109
6110 if (bestsme < INT_MAX) {
6111 int distortion;
6112 if (cpi->sf.use_upsampled_references) {
6113 int best_mv_var;
6114 const int try_second =
6115 x->second_best_mv.as_int != INVALID_MV &&
6116 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006117 const int pw = block_size_wide[bsize];
6118 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006119 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006120 struct buf_2d backup_pred = pd->pre[0];
6121 const YV12_BUFFER_CONFIG *upsampled_ref =
6122 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6123
6124 // Set pred for Y plane
6125 setup_pred_plane(
6126 &pd->pre[0], upsampled_ref->y_buffer,
6127 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6128 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6129 pd->subsampling_x, pd->subsampling_y);
6130
6131 // adjust pred pointer for this block
6132 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006133 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006134 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006135 << 3];
6136
6137 best_mv_var = cpi->find_fractional_mv_step(
6138 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6139 x->errorperbit, &cpi->fn_ptr[bsize],
6140 cpi->sf.mv.subpel_force_stop,
6141 cpi->sf.mv.subpel_iters_per_step,
6142 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6143 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
6144 1);
6145
6146 if (try_second) {
6147 int this_var;
6148 MV best_mv = x->best_mv.as_mv;
6149 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07006150 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6151 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6152 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6153 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006154
6155 x->best_mv = x->second_best_mv;
6156 if (x->best_mv.as_mv.row * 8 <= maxr &&
6157 x->best_mv.as_mv.row * 8 >= minr &&
6158 x->best_mv.as_mv.col * 8 <= maxc &&
6159 x->best_mv.as_mv.col * 8 >= minc) {
6160 this_var = cpi->find_fractional_mv_step(
6161 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6162 x->errorperbit, &cpi->fn_ptr[bsize],
6163 cpi->sf.mv.subpel_force_stop,
6164 cpi->sf.mv.subpel_iters_per_step,
6165 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6166 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
6167 NULL, pw, ph, 1);
6168 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6169 x->best_mv.as_mv = best_mv;
6170 }
6171 }
6172
6173 // Restore the reference frames.
6174 pd->pre[0] = backup_pred;
6175 } else {
6176 cpi->find_fractional_mv_step(
6177 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6178 x->errorperbit, &cpi->fn_ptr[bsize],
6179 cpi->sf.mv.subpel_force_stop,
6180 cpi->sf.mv.subpel_iters_per_step,
6181 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6182 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
6183 }
6184
6185// save motion search result for use in compound prediction
6186#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006187 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006188#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006189 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190#endif // CONFIG_EXT_INTER
6191 }
6192
6193 if (cpi->sf.adaptive_motion_search)
6194 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6195
6196#if CONFIG_EXT_INTER
6197 mode_mv[this_mode][0] = x->best_mv;
6198#else
6199 mode_mv[NEWMV][0] = x->best_mv;
6200#endif // CONFIG_EXT_INTER
6201
6202 // restore src pointers
6203 mi_buf_restore(x, orig_src, orig_pre);
6204 }
6205
6206 if (has_second_rf) {
6207#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006208 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6209 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006210#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006211 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6212 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006213#endif // CONFIG_EXT_INTER
6214 continue;
6215 }
6216
6217#if CONFIG_DUAL_FILTER
6218 (void)run_mv_search;
6219#endif
6220
6221 if (has_second_rf &&
6222#if CONFIG_EXT_INTER
6223 this_mode == NEW_NEWMV &&
6224#else
6225 this_mode == NEWMV &&
6226#endif // CONFIG_EXT_INTER
6227#if CONFIG_DUAL_FILTER
6228 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6229#else
6230 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
6231#endif
6232 {
6233 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006234 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006235 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6236 int rate_mv;
6237 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6238 mi_col,
6239#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006240 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006241#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006242 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006243#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006244 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006245#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006246 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006247 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006248 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006249 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6250#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006251 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006252 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006253 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006254 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6255#endif // CONFIG_EXT_INTER
6256 }
6257 // restore src pointers
6258 mi_buf_restore(x, orig_src, orig_pre);
6259 }
6260
Urvang Joshi454280d2016-10-14 16:51:44 -07006261 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6262 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006263#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006264 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006265#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006266 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006267#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006268 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006269
6270 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006271 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006272 mode_mv[this_mode][ref].as_int;
6273 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006274 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006275 mode_mv[this_mode][ref].as_int;
6276 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006277 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006278 mode_mv[this_mode][ref].as_int;
6279#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006280 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6281 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006282 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006283 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6284 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006285 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006286 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6287 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006288#endif
6289#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006290 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006291 bsi->ref_mv[ref]->as_int;
6292 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006293 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006294 bsi->ref_mv[ref]->as_int;
6295 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006296 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006297 bsi->ref_mv[ref]->as_int;
6298#endif // CONFIG_EXT_INTER
6299 }
6300
6301 // Trap vectors that reach beyond the UMV borders
6302 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
6303 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
6304 continue;
6305
6306 if (filter_idx > 0) {
6307 BEST_SEG_INFO *ref_bsi = bsi_buf;
6308 subpelmv = 0;
6309 have_ref = 1;
6310
6311 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6312 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6313#if CONFIG_EXT_INTER
6314 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006315 have_ref &=
6316 ((mode_mv[this_mode][ref].as_int ==
6317 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6318 (bsi->ref_mv[ref]->as_int ==
6319 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006320 else
6321#endif // CONFIG_EXT_INTER
6322 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006323 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324 }
6325
Urvang Joshi454280d2016-10-14 16:51:44 -07006326 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006327
6328 if (filter_idx > 1 && !subpelmv && !have_ref) {
6329 ref_bsi = bsi_buf + 1;
6330 have_ref = 1;
6331 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6332#if CONFIG_EXT_INTER
6333 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006334 have_ref &=
6335 ((mode_mv[this_mode][ref].as_int ==
6336 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6337 (bsi->ref_mv[ref]->as_int ==
6338 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006339 else
6340#endif // CONFIG_EXT_INTER
6341 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006342 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006343
Urvang Joshi454280d2016-10-14 16:51:44 -07006344 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006345 }
6346
6347 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006348 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006349#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006350 bsi->rdstat[index][mode_idx].byrate =
6351 ref_bsi->rdstat[index][mode_idx].byrate;
6352 bsi->rdstat[index][mode_idx].bdist =
6353 ref_bsi->rdstat[index][mode_idx].bdist;
6354 bsi->rdstat[index][mode_idx].bsse =
6355 ref_bsi->rdstat[index][mode_idx].bsse;
6356 bsi->rdstat[index][mode_idx].brate +=
6357 ref_bsi->rdstat[index][mode_idx].byrate;
6358 bsi->rdstat[index][mode_idx].eobs =
6359 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006360
Urvang Joshi454280d2016-10-14 16:51:44 -07006361 bsi->rdstat[index][mode_idx].brdcost =
6362 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6363 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364
Urvang Joshi454280d2016-10-14 16:51:44 -07006365 memcpy(bsi->rdstat[index][mode_idx].ta,
6366 ref_bsi->rdstat[index][mode_idx].ta,
6367 sizeof(bsi->rdstat[index][mode_idx].ta));
6368 memcpy(bsi->rdstat[index][mode_idx].tl,
6369 ref_bsi->rdstat[index][mode_idx].tl,
6370 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006371#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006372 memcpy(&bsi->rdstat[index][mode_idx],
6373 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006374#endif
6375 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006376 bsi->rdstat[index + 1][mode_idx].eobs =
6377 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006378 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006379 bsi->rdstat[index + 2][mode_idx].eobs =
6380 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006381
Urvang Joshi454280d2016-10-14 16:51:44 -07006382 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383#if CONFIG_REF_MV
6384 // If the NEWMV mode is using the same motion vector as the
6385 // NEARESTMV mode, skip the rest rate-distortion calculations
6386 // and use the inferred motion vector modes.
6387 if (this_mode == NEWMV) {
6388 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006389 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006391 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006392 bsi->ref_mv[1]->as_int)
6393 continue;
6394 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006395 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006396 bsi->ref_mv[0]->as_int)
6397 continue;
6398 }
6399 }
6400#endif
6401 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006402 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006403#if CONFIG_PVQ
6404 od_encode_checkpoint(&x->daala_enc, &post_buf);
6405#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006406 }
6407 continue;
6408 }
6409 }
6410
Yushin Choab44fd12017-01-09 16:06:53 -08006411 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006412 cpi, x, bsi->segment_rd - this_segment_rd, index,
6413 &bsi->rdstat[index][mode_idx].byrate,
6414 &bsi->rdstat[index][mode_idx].bdist,
6415 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6416 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006417
Urvang Joshi454280d2016-10-14 16:51:44 -07006418 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6419 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6420 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6421 bsi->rdstat[index][mode_idx].brate +=
6422 bsi->rdstat[index][mode_idx].byrate;
6423 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006424 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006425 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006426 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006427 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006428 }
6429
Urvang Joshi454280d2016-10-14 16:51:44 -07006430 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431#if CONFIG_REF_MV
6432 // If the NEWMV mode is using the same motion vector as the
6433 // NEARESTMV mode, skip the rest rate-distortion calculations
6434 // and use the inferred motion vector modes.
6435 if (this_mode == NEWMV) {
6436 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006437 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006438 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006439 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006440 bsi->ref_mv[1]->as_int)
6441 continue;
6442 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006443 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006444 bsi->ref_mv[0]->as_int)
6445 continue;
6446 }
6447 }
6448#endif
6449 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006450 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006451
6452#if CONFIG_PVQ
6453 od_encode_checkpoint(&x->daala_enc, &post_buf);
6454#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006455 }
6456 } /*for each 4x4 mode*/
6457
Urvang Joshi454280d2016-10-14 16:51:44 -07006458 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006459 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006460 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006461#if CONFIG_EXT_INTER
6462 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6463#else
6464 for (midx = 0; midx < INTER_MODES; ++midx)
6465#endif // CONFIG_EXT_INTER
6466 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6467 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006468#if CONFIG_PVQ
6469 od_encode_rollback(&x->daala_enc, &pre_buf);
6470#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006471 return INT64_MAX;
6472 }
6473
6474 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006475 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6476 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006477#if CONFIG_PVQ
6478 od_encode_rollback(&x->daala_enc, &post_buf);
6479#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006480
6481#if CONFIG_EXT_INTER
6482 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006483 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006484 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006485 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006486#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006487 set_and_cost_bmi_mvs(
6488 cpi, x, xd, index, mode_selected, mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006489#if CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006490 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006491#else
David Barker45390c12017-02-20 14:44:40 +00006492 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006493#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006494 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006495
Urvang Joshi454280d2016-10-14 16:51:44 -07006496 br += bsi->rdstat[index][mode_idx].brate;
6497 bd += bsi->rdstat[index][mode_idx].bdist;
6498 block_sse += bsi->rdstat[index][mode_idx].bsse;
6499 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6500 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006501
6502 if (this_segment_rd > bsi->segment_rd) {
6503 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006504 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006505#if CONFIG_EXT_INTER
6506 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6507#else
6508 for (midx = 0; midx < INTER_MODES; ++midx)
6509#endif // CONFIG_EXT_INTER
6510 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6511 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006512#if CONFIG_PVQ
6513 od_encode_rollback(&x->daala_enc, &pre_buf);
6514#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006515 return INT64_MAX;
6516 }
6517 }
6518 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006519#if CONFIG_PVQ
6520 od_encode_rollback(&x->daala_enc, &pre_buf);
6521#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006522
6523 bsi->r = br;
6524 bsi->d = bd;
6525 bsi->segment_yrate = segmentyrate;
6526 bsi->segment_rd = this_segment_rd;
6527 bsi->sse = block_sse;
6528
6529 // update the coding decisions
6530 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6531
Yushin Cho7a428ba2017-01-12 16:28:49 -08006532#if CONFIG_DAALA_DIST
6533 {
6534 const int src_stride = p->src.stride;
6535 const int dst_stride = pd->dst.stride;
6536 uint8_t *src = p->src.buf;
6537 uint8_t pred[8 * 8];
6538 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
6539 int use_activity_masking = 0;
6540 int qm = OD_HVS_QM;
6541#if CONFIG_PVQ
6542 use_activity_masking = x->daala_enc.use_activity_masking;
6543#endif
6544
6545 for (idy = 0; idy < 2; idy += num_4x4_blocks_high)
6546 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6547 int i = idy * 2 + idx;
6548 int j, m;
6549 uint8_t *dst_init = &pd->dst.buf[(idy * dst_stride + idx) * 4];
6550
6551 av1_build_inter_predictor_sub8x8(xd, 0, i, idy, idx, mi_row, mi_col);
6552 // Save predicted pixels for use later.
6553 for (j = 0; j < num_4x4_blocks_high * 4; j++)
6554 for (m = 0; m < num_4x4_blocks_wide * 4; m++)
6555 pred[(idy * 4 + j) * 8 + idx * 4 + m] =
6556 dst_init[j * dst_stride + m];
6557
6558 // Do xform and quant to get decoded pixels.
6559 {
6560 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6561 const int txb_height = max_block_high(xd, plane_bsize, 0);
6562 int idx_, idy_;
6563
6564 for (idy_ = 0; idy_ < txb_height; idy_++) {
6565 for (idx_ = 0; idx_ < txb_width; idx_++) {
6566 int block;
6567 int coeff_ctx = 0;
6568 const tran_low_t *dqcoeff;
6569 uint16_t eob;
6570 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6571 INV_TXFM_PARAM inv_txfm_param;
6572 uint8_t *dst = dst_init + (idy_ * dst_stride + idx_) * 4;
6573
6574 block = i + (idy_ * 2 + idx_);
6575
6576 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6577 eob = p->eobs[block];
6578
6579 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
6580 BLOCK_8X8, TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
6581
6582 inv_txfm_param.tx_type =
6583 get_tx_type(plane_type, xd, block, TX_4X4);
6584 inv_txfm_param.tx_size = TX_4X4;
6585 inv_txfm_param.eob = eob;
6586 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
6587
6588#if CONFIG_PVQ
6589 {
6590 int i2, j2;
6591
6592 for (j2 = 0; j2 < 4; j2++)
6593 for (i2 = 0; i2 < 4; i2++) dst[j2 * dst_stride + i2] = 0;
6594 }
6595#endif
6596 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
6597 }
6598 }
6599 }
6600 }
6601
6602 // Daala-defined distortion computed for 1) predicted pixels and
6603 // 2) decoded pixels of the block of 8x8 pixels
6604 bsi->sse = av1_daala_dist(src, src_stride, pred, 8, TX_8X8, qm,
6605 use_activity_masking, x->qindex)
6606 << 4;
6607
6608 bsi->d = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, TX_8X8,
6609 qm, use_activity_masking, x->qindex)
6610 << 4;
6611 }
6612#endif // CONFIG_DAALA_DIST
6613
Yaowu Xuc27fc142016-08-22 16:08:15 -07006614 if (bsi->segment_rd > best_rd) return INT64_MAX;
6615 /* set it to the best */
6616 for (idx = 0; idx < 4; idx++) {
6617 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6618 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6619 if (has_second_ref(mbmi))
6620 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
6621#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006622 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006623 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006624 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006625#endif
6626#if CONFIG_EXT_INTER
6627 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6628 if (has_second_rf)
6629 mi->bmi[idx].ref_mv[1].as_int =
6630 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6631#endif // CONFIG_EXT_INTER
6632 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6633 mi->bmi[idx].as_mode = bsi->modes[idx];
6634 }
6635
6636 /*
6637 * used to set mbmi->mv.as_int
6638 */
6639 *returntotrate = bsi->r;
6640 *returndistortion = bsi->d;
6641 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006642 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006643 *psse = bsi->sse;
6644 mbmi->mode = bsi->modes[3];
6645
6646 return bsi->segment_rd;
6647}
6648
Yaowu Xuf883b422016-08-30 14:01:10 -07006649static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650 const MACROBLOCKD *xd, int segment_id,
6651 unsigned int *ref_costs_single,
6652 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006653 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006654 int seg_ref_active =
6655 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6656 if (seg_ref_active) {
6657 memset(ref_costs_single, 0,
6658 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6659 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6660 *comp_mode_p = 128;
6661 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006662 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6663 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006664
6665 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006666 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006667 *comp_mode_p = comp_inter_p;
6668 } else {
6669 *comp_mode_p = 128;
6670 }
6671
Yaowu Xuf883b422016-08-30 14:01:10 -07006672 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006673
6674 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006675 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6676 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006677#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006678 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6679 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6680 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006681#endif // CONFIG_EXT_REFS
6682
Yaowu Xuf883b422016-08-30 14:01:10 -07006683 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684
6685 ref_costs_single[LAST_FRAME] =
6686#if CONFIG_EXT_REFS
6687 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6688 ref_costs_single[BWDREF_FRAME] =
6689#endif // CONFIG_EXT_REFS
6690 ref_costs_single[GOLDEN_FRAME] =
6691 ref_costs_single[ALTREF_FRAME] = base_cost;
6692
6693#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006694 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6695 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6696 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6697 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6698 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6699 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006700
Yaowu Xuf883b422016-08-30 14:01:10 -07006701 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6702 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6703 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6704 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006705
Yaowu Xuf883b422016-08-30 14:01:10 -07006706 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6707 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006708
Yaowu Xuf883b422016-08-30 14:01:10 -07006709 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6710 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006711
Yaowu Xuf883b422016-08-30 14:01:10 -07006712 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6713 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006714#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006715 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6716 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6717 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006718
Yaowu Xuf883b422016-08-30 14:01:10 -07006719 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6720 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006721#endif // CONFIG_EXT_REFS
6722 } else {
6723 ref_costs_single[LAST_FRAME] = 512;
6724#if CONFIG_EXT_REFS
6725 ref_costs_single[LAST2_FRAME] = 512;
6726 ref_costs_single[LAST3_FRAME] = 512;
6727 ref_costs_single[BWDREF_FRAME] = 512;
6728#endif // CONFIG_EXT_REFS
6729 ref_costs_single[GOLDEN_FRAME] = 512;
6730 ref_costs_single[ALTREF_FRAME] = 512;
6731 }
6732
6733 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006734 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006735#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006736 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6737 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6738 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006739#endif // CONFIG_EXT_REFS
6740
Yaowu Xuf883b422016-08-30 14:01:10 -07006741 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006742
6743 ref_costs_comp[LAST_FRAME] =
6744#if CONFIG_EXT_REFS
6745 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6746#endif // CONFIG_EXT_REFS
6747 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6748
6749#if CONFIG_EXT_REFS
6750 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6751#endif // CONFIG_EXT_REFS
6752
6753#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006754 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6755 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6756 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6757 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758
Yaowu Xuf883b422016-08-30 14:01:10 -07006759 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6760 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006761
Yaowu Xuf883b422016-08-30 14:01:10 -07006762 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6763 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006764
6765 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6766 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006767 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6768 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006769#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006770 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6771 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006772#endif // CONFIG_EXT_REFS
6773 } else {
6774 ref_costs_comp[LAST_FRAME] = 512;
6775#if CONFIG_EXT_REFS
6776 ref_costs_comp[LAST2_FRAME] = 512;
6777 ref_costs_comp[LAST3_FRAME] = 512;
6778 ref_costs_comp[BWDREF_FRAME] = 512;
6779 ref_costs_comp[ALTREF_FRAME] = 512;
6780#endif // CONFIG_EXT_REFS
6781 ref_costs_comp[GOLDEN_FRAME] = 512;
6782 }
6783 }
6784}
6785
6786static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6787 int mode_index,
6788 int64_t comp_pred_diff[REFERENCE_MODES],
6789 int skippable) {
6790 MACROBLOCKD *const xd = &x->e_mbd;
6791
6792 // Take a snapshot of the coding context so it can be
6793 // restored if we decide to encode this way
6794 ctx->skip = x->skip;
6795 ctx->skippable = skippable;
6796 ctx->best_mode_index = mode_index;
6797 ctx->mic = *xd->mi[0];
6798 ctx->mbmi_ext = *x->mbmi_ext;
6799 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6800 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6801 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6802}
6803
clang-format55ce9e02017-02-15 22:27:12 -08006804static void setup_buffer_inter(
6805 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6806 BLOCK_SIZE block_size, int mi_row, int mi_col,
6807 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6808 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6809 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006810 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006811 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6812 MACROBLOCKD *const xd = &x->e_mbd;
6813 MODE_INFO *const mi = xd->mi[0];
6814 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6815 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6816 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6817
6818 assert(yv12 != NULL);
6819
6820 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6821 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006822 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006823
6824 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006825 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006826 cm, xd, mi, ref_frame,
6827#if CONFIG_REF_MV
6828 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6829#if CONFIG_EXT_INTER
6830 mbmi_ext->compound_mode_context,
6831#endif // CONFIG_EXT_INTER
6832#endif
6833 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6834
6835 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006836 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6837 &frame_nearest_mv[ref_frame],
6838 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006839
Jingning Han271bb2c2016-12-14 12:34:46 -08006840// Further refinement that is encode side only to test the top few candidates
6841// in full and choose the best as the centre point for subsequent searches.
6842// The current implementation doesn't support scaling.
6843#if CONFIG_CB4X4
6844 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6845 block_size);
6846#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006847 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6848 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6849 block_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08006850#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006851}
6852
Urvang Joshi52648442016-10-13 17:27:51 -07006853static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6854 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006855#if CONFIG_EXT_INTER
6856 int ref_idx, int mv_idx,
6857#endif // CONFIG_EXT_INTER
6858 int *rate_mv) {
6859 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006860 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006861 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6862 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6863 int bestsme = INT_MAX;
6864 int step_param;
6865 int sadpb = x->sadperbit16;
6866 MV mvp_full;
6867#if CONFIG_EXT_INTER
6868 int ref = mbmi->ref_frame[ref_idx];
6869 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6870#else
6871 int ref = mbmi->ref_frame[0];
6872 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6873 int ref_idx = 0;
6874#endif // CONFIG_EXT_INTER
6875
6876 int tmp_col_min = x->mv_col_min;
6877 int tmp_col_max = x->mv_col_max;
6878 int tmp_row_min = x->mv_row_min;
6879 int tmp_row_max = x->mv_row_max;
6880 int cost_list[5];
6881
6882 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006883 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006884
6885 MV pred_mv[3];
6886 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6887 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6888 pred_mv[2] = x->pred_mv[ref];
6889
Yaowu Xuc27fc142016-08-22 16:08:15 -07006890 if (scaled_ref_frame) {
6891 int i;
6892 // Swap out the reference frame for a version that's been scaled to
6893 // match the resolution of the current frame, allowing the existing
6894 // motion search code to be used without additional modifications.
6895 for (i = 0; i < MAX_MB_PLANE; i++)
6896 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6897
Yaowu Xuf883b422016-08-30 14:01:10 -07006898 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006899 }
6900
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006901 av1_set_mv_search_range(x, &ref_mv);
6902
6903#if CONFIG_REF_MV
6904 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6905#endif
6906
Yaowu Xuc27fc142016-08-22 16:08:15 -07006907 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006908 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006909 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6910 // Take wtd average of the step_params based on the last frame's
6911 // max mv magnitude and that based on the best ref mvs of the current
6912 // block for the given reference.
6913 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006914 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006915 2;
6916 } else {
6917 step_param = cpi->mv_step_param;
6918 }
6919
6920 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6921 int boffset =
6922 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006923 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6924 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006925 }
6926
6927 if (cpi->sf.adaptive_motion_search) {
6928 int bwl = b_width_log2_lookup[bsize];
6929 int bhl = b_height_log2_lookup[bsize];
6930 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6931
6932 if (tlevel < 5) step_param += 2;
6933
6934 // prev_mv_sad is not setup for dynamically scaled frames.
6935 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6936 int i;
6937 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6938 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6939 x->pred_mv[ref].row = 0;
6940 x->pred_mv[ref].col = 0;
6941 x->best_mv.as_int = INVALID_MV;
6942
6943 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006944 int j;
6945 for (j = 0; j < MAX_MB_PLANE; ++j)
6946 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006947 }
6948 return;
6949 }
6950 }
6951 }
6952 }
6953
Yaowu Xuf883b422016-08-30 14:01:10 -07006954 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006955
Yue Chene9638cc2016-10-10 12:37:54 -07006956#if CONFIG_MOTION_VAR
6957 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6958 mvp_full = mbmi->mv[0].as_mv;
6959 else
6960#endif // CONFIG_MOTION_VAR
6961 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006962
6963 mvp_full.col >>= 3;
6964 mvp_full.row >>= 3;
6965
6966 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6967
Yue Chene9638cc2016-10-10 12:37:54 -07006968#if CONFIG_MOTION_VAR
6969 switch (mbmi->motion_mode) {
6970 case SIMPLE_TRANSLATION:
6971#endif // CONFIG_MOTION_VAR
6972 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6973 sadpb, cond_cost_list(cpi, cost_list),
6974 &ref_mv, INT_MAX, 1);
6975#if CONFIG_MOTION_VAR
6976 break;
6977 case OBMC_CAUSAL:
6978 bestsme = av1_obmc_full_pixel_diamond(
6979 cpi, x, &mvp_full, step_param, sadpb,
6980 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6981 &(x->best_mv.as_mv), 0);
6982 break;
6983 default: assert("Invalid motion mode!\n");
6984 }
6985#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006986
6987 x->mv_col_min = tmp_col_min;
6988 x->mv_col_max = tmp_col_max;
6989 x->mv_row_min = tmp_row_min;
6990 x->mv_row_max = tmp_row_max;
6991
6992 if (bestsme < INT_MAX) {
6993 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006994#if CONFIG_MOTION_VAR
6995 switch (mbmi->motion_mode) {
6996 case SIMPLE_TRANSLATION:
6997#endif // CONFIG_MOTION_VAR
6998 if (cpi->sf.use_upsampled_references) {
6999 int best_mv_var;
7000 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
7001 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007002 const int pw = block_size_wide[bsize];
7003 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07007004 // Use up-sampled reference frames.
7005 struct macroblockd_plane *const pd = &xd->plane[0];
7006 struct buf_2d backup_pred = pd->pre[ref_idx];
7007 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007008
Yue Chene9638cc2016-10-10 12:37:54 -07007009 // Set pred for Y plane
7010 setup_pred_plane(
7011 &pd->pre[ref_idx], upsampled_ref->y_buffer,
7012 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
7013 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
7014 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007015
Yue Chene9638cc2016-10-10 12:37:54 -07007016 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007017 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7018 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7019 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7020 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
7021 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007022
Yue Chene9638cc2016-10-10 12:37:54 -07007023 if (try_second) {
7024 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
7025 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
7026 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
7027 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
7028 int this_var;
7029 MV best_mv = x->best_mv.as_mv;
7030
7031 x->best_mv = x->second_best_mv;
7032 if (x->best_mv.as_mv.row * 8 <= maxr &&
7033 x->best_mv.as_mv.row * 8 >= minr &&
7034 x->best_mv.as_mv.col * 8 <= maxc &&
7035 x->best_mv.as_mv.col * 8 >= minc) {
7036 this_var = cpi->find_fractional_mv_step(
7037 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7038 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7039 cpi->sf.mv.subpel_iters_per_step,
7040 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
7041 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
7042 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
7043 x->best_mv.as_mv = best_mv;
7044 }
7045 }
7046
7047 // Restore the reference frames.
7048 pd->pre[ref_idx] = backup_pred;
7049 } else {
7050 cpi->find_fractional_mv_step(
7051 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7052 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7053 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7054 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
7055 0);
7056 }
7057#if CONFIG_MOTION_VAR
7058 break;
7059 case OBMC_CAUSAL:
7060 av1_find_best_obmc_sub_pixel_tree_up(
7061 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
7062 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7063 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7064 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
7065 cpi->sf.use_upsampled_references);
7066 break;
7067 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07007068 }
Yue Chene9638cc2016-10-10 12:37:54 -07007069#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007070 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007071 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
7072 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007073
Yue Chene9638cc2016-10-10 12:37:54 -07007074#if CONFIG_MOTION_VAR
7075 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
7076#else
7077 if (cpi->sf.adaptive_motion_search)
7078#endif // CONFIG_MOTION_VAR
7079 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007080
7081 if (scaled_ref_frame) {
7082 int i;
7083 for (i = 0; i < MAX_MB_PLANE; i++)
7084 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7085 }
7086}
7087
David Barkerac37fa32016-12-02 12:30:21 +00007088static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007089 int i;
7090 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007091 xd->plane[i].dst.buf = dst.plane[i];
7092 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007093 }
7094}
7095
Yaowu Xuc27fc142016-08-22 16:08:15 -07007096#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07007097static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007098 const uint8_t *mask, int mask_stride,
7099 BLOCK_SIZE bsize, int mi_row, int mi_col,
7100 int_mv *tmp_mv, int *rate_mv, int ref_idx,
7101 int mv_idx) {
7102 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007103 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007104 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7105 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7106 int bestsme = INT_MAX;
7107 int step_param;
7108 int sadpb = x->sadperbit16;
7109 MV mvp_full;
7110 int ref = mbmi->ref_frame[ref_idx];
7111 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
7112
7113 int tmp_col_min = x->mv_col_min;
7114 int tmp_col_max = x->mv_col_max;
7115 int tmp_row_min = x->mv_row_min;
7116 int tmp_row_max = x->mv_row_max;
7117
7118 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007119 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007120 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007121
7122 MV pred_mv[3];
7123 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7124 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7125 pred_mv[2] = x->pred_mv[ref];
7126
7127#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007128 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007129#endif
7130
7131 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007132 // Swap out the reference frame for a version that's been scaled to
7133 // match the resolution of the current frame, allowing the existing
7134 // motion search code to be used without additional modifications.
7135 for (i = 0; i < MAX_MB_PLANE; i++)
7136 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7137
Yaowu Xuf883b422016-08-30 14:01:10 -07007138 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007139 }
7140
Yaowu Xuf883b422016-08-30 14:01:10 -07007141 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007142
7143 // Work out the size of the first step in the mv step search.
7144 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7145 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7146 // Take wtd average of the step_params based on the last frame's
7147 // max mv magnitude and that based on the best ref mvs of the current
7148 // block for the given reference.
7149 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007150 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007151 2;
7152 } else {
7153 step_param = cpi->mv_step_param;
7154 }
7155
7156 // TODO(debargha): is show_frame needed here?
7157 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7158 int boffset =
7159 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007160 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7161 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007162 }
7163
7164 if (cpi->sf.adaptive_motion_search) {
7165 int bwl = b_width_log2_lookup[bsize];
7166 int bhl = b_height_log2_lookup[bsize];
7167 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7168
7169 if (tlevel < 5) step_param += 2;
7170
7171 // prev_mv_sad is not setup for dynamically scaled frames.
7172 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007173 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7174 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7175 x->pred_mv[ref].row = 0;
7176 x->pred_mv[ref].col = 0;
7177 tmp_mv->as_int = INVALID_MV;
7178
7179 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007180 int j;
7181 for (j = 0; j < MAX_MB_PLANE; ++j)
7182 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007183 }
7184 return;
7185 }
7186 }
7187 }
7188 }
7189
7190 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7191
7192 mvp_full.col >>= 3;
7193 mvp_full.row >>= 3;
7194
Yaowu Xuf883b422016-08-30 14:01:10 -07007195 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007196 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7197 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7198 &tmp_mv->as_mv, ref_idx);
7199
7200 x->mv_col_min = tmp_col_min;
7201 x->mv_col_max = tmp_col_max;
7202 x->mv_row_min = tmp_row_min;
7203 x->mv_row_max = tmp_row_max;
7204
7205 if (bestsme < INT_MAX) {
7206 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007207 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007208 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7209 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7210 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7211 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7212 cpi->sf.use_upsampled_references);
7213 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007214 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7215 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007216
7217 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7218 x->pred_mv[ref] = tmp_mv->as_mv;
7219
7220 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007221 for (i = 0; i < MAX_MB_PLANE; i++)
7222 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7223 }
7224}
7225
Sarah Parker6fdc8532016-11-16 17:47:13 -08007226static void do_masked_motion_search_indexed(
7227 const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007228 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
7229 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int mv_idx[2],
7230 int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007231 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7232 MACROBLOCKD *xd = &x->e_mbd;
7233 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7234 BLOCK_SIZE sb_type = mbmi->sb_type;
7235 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007236 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007237
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007238 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007239
7240 if (which == 0 || which == 2)
7241 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7242 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
7243
7244 if (which == 1 || which == 2) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007245// get the negative mask
7246#if CONFIG_COMPOUND_SEGMENT
7247 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7248 const int h = block_size_high[bsize];
7249 mask = av1_get_compound_type_mask_inverse(
7250 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7251#else
7252 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
7253#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007254 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7255 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
7256 }
7257}
7258#endif // CONFIG_EXT_INTER
7259
7260// In some situations we want to discount tha pparent cost of a new motion
7261// vector. Where there is a subtle motion field and especially where there is
7262// low spatial complexity then it can be hard to cover the cost of a new motion
7263// vector in a single block, even if that motion vector reduces distortion.
7264// However, once established that vector may be usable through the nearest and
7265// near mv modes to reduce distortion in subsequent blocks and also improve
7266// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007267static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007268 int_mv this_mv,
7269 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7270 int ref_frame) {
7271 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7272 (this_mv.as_int != 0) &&
7273 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7274 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7275 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7276 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7277}
7278
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007279#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7280#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007281
7282// TODO(jingning): this mv clamping function should be block size dependent.
7283static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7284 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7285 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7286 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7287 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7288}
7289
7290#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007291static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007292 const BLOCK_SIZE bsize, const uint8_t *pred0,
7293 int stride0, const uint8_t *pred1, int stride1) {
7294 const struct macroblock_plane *const p = &x->plane[0];
7295 const uint8_t *src = p->src.buf;
7296 int src_stride = p->src.stride;
7297 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007298 const int bw = block_size_wide[bsize];
7299 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007300 uint32_t esq[2][4], var;
7301 int64_t tl, br;
7302
Yaowu Xuf883b422016-08-30 14:01:10 -07007303#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007304 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7305 pred0 = CONVERT_TO_BYTEPTR(pred0);
7306 pred1 = CONVERT_TO_BYTEPTR(pred1);
7307 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007308#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007309
7310 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7311 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7312 stride0, &esq[0][1]);
7313 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7314 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7315 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7316 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7317 &esq[0][3]);
7318 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7319 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7320 stride1, &esq[1][1]);
7321 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7322 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7323 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7324 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7325 &esq[1][3]);
7326 (void)var;
7327
7328 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7329 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7330 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7331 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7332 return (tl + br > 0);
7333}
7334#endif // CONFIG_EXT_INTER
7335
7336#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007337static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007338 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007339 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007340 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7341 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007342 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007343 const MACROBLOCKD *xd = &x->e_mbd;
7344 int bsl = mi_width_log2_lookup[bsize];
7345 int pred_filter_search =
7346 cpi->sf.cb_pred_filter_search
7347 ? (((mi_row + mi_col) >> bsl) +
7348 get_chessboard_index(cm->current_video_frame)) &
7349 0x1
7350 : 0;
7351 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7352 const int is_comp_pred = has_second_ref(mbmi);
7353 const int this_mode = mbmi->mode;
7354 int refs[2] = { mbmi->ref_frame[0],
7355 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007356 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007357 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007358 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7359 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7360
7361#if CONFIG_EXT_INTER
7362 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
7363 this_mode != NEW_NEWMV) ||
7364 (af == lf))
7365#else
7366 if ((this_mode != NEWMV) || (af == lf))
7367#endif // CONFIG_EXT_INTER
7368 best_filter = af;
7369 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007370 if (is_comp_pred) {
7371 if (cpi->sf.adaptive_mode_search) {
7372#if CONFIG_EXT_INTER
7373 switch (this_mode) {
7374 case NEAREST_NEARESTMV:
7375 if (single_filter[NEARESTMV][refs[0]] ==
7376 single_filter[NEARESTMV][refs[1]])
7377 best_filter = single_filter[NEARESTMV][refs[0]];
7378 break;
7379 case NEAREST_NEARMV:
7380 if (single_filter[NEARESTMV][refs[0]] ==
7381 single_filter[NEARMV][refs[1]])
7382 best_filter = single_filter[NEARESTMV][refs[0]];
7383 break;
7384 case NEAR_NEARESTMV:
7385 if (single_filter[NEARMV][refs[0]] ==
7386 single_filter[NEARESTMV][refs[1]])
7387 best_filter = single_filter[NEARMV][refs[0]];
7388 break;
7389 case NEAR_NEARMV:
7390 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7391 best_filter = single_filter[NEARMV][refs[0]];
7392 break;
7393 case ZERO_ZEROMV:
7394 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7395 best_filter = single_filter[ZEROMV][refs[0]];
7396 break;
7397 case NEW_NEWMV:
7398 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7399 best_filter = single_filter[NEWMV][refs[0]];
7400 break;
7401 case NEAREST_NEWMV:
7402 if (single_filter[NEARESTMV][refs[0]] ==
7403 single_filter[NEWMV][refs[1]])
7404 best_filter = single_filter[NEARESTMV][refs[0]];
7405 break;
7406 case NEAR_NEWMV:
7407 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7408 best_filter = single_filter[NEARMV][refs[0]];
7409 break;
7410 case NEW_NEARESTMV:
7411 if (single_filter[NEWMV][refs[0]] ==
7412 single_filter[NEARESTMV][refs[1]])
7413 best_filter = single_filter[NEWMV][refs[0]];
7414 break;
7415 case NEW_NEARMV:
7416 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7417 best_filter = single_filter[NEWMV][refs[0]];
7418 break;
7419 default:
7420 if (single_filter[this_mode][refs[0]] ==
7421 single_filter[this_mode][refs[1]])
7422 best_filter = single_filter[this_mode][refs[0]];
7423 break;
7424 }
7425#else
7426 if (single_filter[this_mode][refs[0]] ==
7427 single_filter[this_mode][refs[1]])
7428 best_filter = single_filter[this_mode][refs[0]];
7429#endif // CONFIG_EXT_INTER
7430 }
7431 }
Angie Chiang75c22092016-10-25 12:19:16 -07007432 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7433 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007434 }
7435 return best_filter;
7436}
7437#endif
7438
7439#if CONFIG_EXT_INTER
7440// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07007441static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007442 const BLOCK_SIZE bsize, const uint8_t *const p0,
7443 const uint8_t *const p1, int *const best_wedge_sign,
7444 int *const best_wedge_index) {
7445 const MACROBLOCKD *const xd = &x->e_mbd;
7446 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007447 const int bw = block_size_wide[bsize];
7448 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007449 const int N = bw * bh;
7450 int rate;
7451 int64_t dist;
7452 int64_t rd, best_rd = INT64_MAX;
7453 int wedge_index;
7454 int wedge_sign;
7455 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7456 const uint8_t *mask;
7457 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007458#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007459 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7460 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7461#else
7462 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007463#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007464
7465 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7466 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7467 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7468 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7469
7470 int64_t sign_limit;
7471
Yaowu Xuf883b422016-08-30 14:01:10 -07007472#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007473 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007474 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007475 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007476 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007477 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007478 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007479 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7480 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007481#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007483 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7484 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7485 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007486 }
7487
Yaowu Xuf883b422016-08-30 14:01:10 -07007488 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7489 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007490 (1 << WEDGE_WEIGHT_BITS) / 2;
7491
Jingning Han61418bb2017-01-23 17:12:48 -08007492 if (N < 64)
7493 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7494 else
7495 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007496
7497 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007498 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007499
7500 // TODO(jingning): Make sse2 functions support N = 16 case
7501 if (N < 64)
7502 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7503 else
7504 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007505
Yaowu Xuf883b422016-08-30 14:01:10 -07007506 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007507 if (N < 64)
7508 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7509 else
7510 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007511 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7512
7513 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7514 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7515
7516 if (rd < best_rd) {
7517 *best_wedge_index = wedge_index;
7518 *best_wedge_sign = wedge_sign;
7519 best_rd = rd;
7520 }
7521 }
7522
7523 return best_rd;
7524}
7525
7526// Choose the best wedge index the specified sign
7527static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007528 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007529 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7530 const int wedge_sign, int *const best_wedge_index) {
7531 const MACROBLOCKD *const xd = &x->e_mbd;
7532 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007533 const int bw = block_size_wide[bsize];
7534 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007535 const int N = bw * bh;
7536 int rate;
7537 int64_t dist;
7538 int64_t rd, best_rd = INT64_MAX;
7539 int wedge_index;
7540 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7541 const uint8_t *mask;
7542 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007543#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007544 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7545 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7546#else
7547 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007548#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007549
7550 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7551 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7552
Yaowu Xuf883b422016-08-30 14:01:10 -07007553#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007554 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007555 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007556 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007557 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007558 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7559 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007560#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007561 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007562 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7563 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007564 }
7565
7566 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007567 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007568 if (N < 64)
7569 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7570 else
7571 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007572 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7573
7574 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7575 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7576
7577 if (rd < best_rd) {
7578 *best_wedge_index = wedge_index;
7579 best_rd = rd;
7580 }
7581 }
7582
7583 return best_rd;
7584}
7585
Yaowu Xuf883b422016-08-30 14:01:10 -07007586static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007587 const MACROBLOCK *const x,
7588 const BLOCK_SIZE bsize,
7589 const uint8_t *const p0,
7590 const uint8_t *const p1) {
7591 const MACROBLOCKD *const xd = &x->e_mbd;
7592 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007593 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007594
7595 int64_t rd;
7596 int wedge_index = -1;
7597 int wedge_sign = 0;
7598
Sarah Parker42d96102017-01-31 21:05:27 -08007599 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007600
7601 if (cpi->sf.fast_wedge_sign_estimate) {
7602 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7603 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7604 } else {
7605 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7606 }
7607
Sarah Parker6fdc8532016-11-16 17:47:13 -08007608 mbmi->interinter_compound_data.wedge_sign = wedge_sign;
7609 mbmi->interinter_compound_data.wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007610 return rd;
7611}
7612
Sarah Parker569edda2016-12-14 14:57:38 -08007613#if CONFIG_COMPOUND_SEGMENT
7614static int64_t pick_interinter_seg_mask(const AV1_COMP *const cpi,
7615 const MACROBLOCK *const x,
7616 const BLOCK_SIZE bsize,
7617 const uint8_t *const p0,
7618 const uint8_t *const p1) {
7619 const MACROBLOCKD *const xd = &x->e_mbd;
7620 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7621 const struct buf_2d *const src = &x->plane[0].src;
7622 const int bw = block_size_wide[bsize];
7623 const int bh = block_size_high[bsize];
7624 const int N = bw * bh;
7625 int rate;
7626 uint64_t sse;
7627 int64_t dist;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007628 int rd0;
7629 SEG_MASK_TYPE cur_mask_type;
7630 int64_t best_rd = INT64_MAX;
7631 SEG_MASK_TYPE best_mask_type = 0;
Sarah Parker569edda2016-12-14 14:57:38 -08007632#if CONFIG_AOM_HIGHBITDEPTH
7633 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7634 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7635#else
7636 const int bd_round = 0;
7637#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker409c0bb2017-01-04 11:29:07 -08007638 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Sarah Parker569edda2016-12-14 14:57:38 -08007639 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7640 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7641 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7642
7643#if CONFIG_AOM_HIGHBITDEPTH
7644 if (hbd) {
7645 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7646 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7647 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7648 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7649 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7650 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7651 } else // NOLINT
7652#endif // CONFIG_AOM_HIGHBITDEPTH
7653 {
7654 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7655 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7656 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7657 }
7658
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007659 // try each mask type and its inverse
7660 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007661// build mask and inverse
7662#if CONFIG_AOM_HIGHBITDEPTH
7663 if (hbd)
7664 build_compound_seg_mask_highbd(
7665 comp_data->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7666 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7667 else
7668#endif // CONFIG_AOM_HIGHBITDEPTH
7669 build_compound_seg_mask(comp_data->seg_mask, cur_mask_type, p0, bw, p1,
7670 bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007671
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007672 // compute rd for mask
7673 sse = av1_wedge_sse_from_residuals(r1, d10, comp_data->seg_mask, N);
7674 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007675
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007676 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7677 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007678
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007679 if (rd0 < best_rd) {
7680 best_mask_type = cur_mask_type;
7681 best_rd = rd0;
7682 }
7683 }
Sarah Parker569edda2016-12-14 14:57:38 -08007684
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007685 // make final mask
7686 comp_data->mask_type = best_mask_type;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007687#if CONFIG_AOM_HIGHBITDEPTH
7688 if (hbd)
7689 build_compound_seg_mask_highbd(
7690 comp_data->seg_mask, comp_data->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7691 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7692 else
7693#endif // CONFIG_AOM_HIGHBITDEPTH
7694 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, p0, bw,
7695 p1, bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007696
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007697 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007698}
7699#endif // CONFIG_COMPOUND_SEGMENT
7700
Yaowu Xuf883b422016-08-30 14:01:10 -07007701static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007702 const MACROBLOCK *const x,
7703 const BLOCK_SIZE bsize,
7704 const uint8_t *const p0,
7705 const uint8_t *const p1) {
7706 const MACROBLOCKD *const xd = &x->e_mbd;
7707 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7708
7709 int64_t rd;
7710 int wedge_index = -1;
7711
7712 assert(is_interintra_wedge_used(bsize));
7713
7714 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7715
7716 mbmi->interintra_wedge_sign = 0;
7717 mbmi->interintra_wedge_index = wedge_index;
7718 return rd;
7719}
Sarah Parker6fdc8532016-11-16 17:47:13 -08007720
7721static int interinter_compound_motion_search(const AV1_COMP *const cpi,
7722 MACROBLOCK *x,
7723 const BLOCK_SIZE bsize,
7724 const int this_mode, int mi_row,
7725 int mi_col) {
7726 const MACROBLOCKD *const xd = &x->e_mbd;
7727 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7728 int_mv tmp_mv[2];
7729 int rate_mvs[2], tmp_rate_mv = 0;
7730 if (this_mode == NEW_NEWMV) {
7731 int mv_idxs[2] = { 0, 0 };
7732 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7733 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7734 mv_idxs, 2);
7735 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7736 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7737 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7738 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7739 int mv_idxs[2] = { 0, 0 };
7740 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7741 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7742 mv_idxs, 0);
7743 tmp_rate_mv = rate_mvs[0];
7744 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7745 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7746 int mv_idxs[2] = { 0, 0 };
7747 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7748 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7749 mv_idxs, 1);
7750 tmp_rate_mv = rate_mvs[1];
7751 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7752 }
7753 return tmp_rate_mv;
7754}
7755
Sarah Parker569edda2016-12-14 14:57:38 -08007756#if CONFIG_COMPOUND_SEGMENT
7757// TODO(sarahparker) this and build_and_cost_compound_wedge can probably
7758// be combined in a refactor
7759static int64_t build_and_cost_compound_seg(
7760 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7761 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7762 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7763 int *strides, int mi_row, int mi_col) {
7764 MACROBLOCKD *xd = &x->e_mbd;
7765 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7766 int rate_sum;
7767 int64_t dist_sum;
7768 int64_t best_rd_cur = INT64_MAX;
7769 int64_t rd = INT64_MAX;
7770 int tmp_skip_txfm_sb;
7771 int64_t tmp_skip_sse_sb;
7772
7773 best_rd_cur = pick_interinter_seg_mask(cpi, x, bsize, *preds0, *preds1);
7774 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7775
Sarah Parker2e604882017-01-17 17:31:25 -08007776 if (have_newmv_in_inter_mode(this_mode) &&
7777 use_masked_motion_search(COMPOUND_SEG)) {
Sarah Parker569edda2016-12-14 14:57:38 -08007778 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7779 mi_row, mi_col);
7780 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
7781 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7782 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7783 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7784 if (rd < best_rd_cur) {
7785 best_rd_cur = rd;
7786 } else {
7787 mbmi->mv[0].as_int = cur_mv[0].as_int;
7788 mbmi->mv[1].as_int = cur_mv[1].as_int;
7789 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007790 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7791#if CONFIG_SUPERTX
7792 0, 0,
7793#endif // CONFIG_SUPERTX
7794 preds0, strides, preds1,
7795 strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007796 }
7797 av1_subtract_plane(x, bsize, 0);
7798 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7799 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7800 if (rd != INT64_MAX)
7801 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7802 best_rd_cur = rd;
7803
7804 } else {
David Barker426a9972017-01-27 11:03:11 +00007805 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7806#if CONFIG_SUPERTX
7807 0, 0,
7808#endif // CONFIG_SUPERTX
7809 preds0, strides, preds1, strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007810 av1_subtract_plane(x, bsize, 0);
7811 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7812 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7813 if (rd != INT64_MAX)
7814 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7815 best_rd_cur = rd;
7816 }
7817 return best_rd_cur;
7818}
7819#endif // CONFIG_COMPOUND_SEGMENT
7820
Sarah Parker6fdc8532016-11-16 17:47:13 -08007821static int64_t build_and_cost_compound_wedge(
7822 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7823 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
David Barkerac37fa32016-12-02 12:30:21 +00007824 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7825 int *strides, int mi_row, int mi_col) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007826 MACROBLOCKD *xd = &x->e_mbd;
7827 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7828 int rate_sum;
7829 int64_t dist_sum;
7830 int64_t best_rd_cur = INT64_MAX;
7831 int64_t rd = INT64_MAX;
7832 int tmp_skip_txfm_sb;
7833 int64_t tmp_skip_sse_sb;
7834
7835 best_rd_cur = pick_interinter_wedge(cpi, x, bsize, *preds0, *preds1);
7836 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7837
Sarah Parker2e604882017-01-17 17:31:25 -08007838 if (have_newmv_in_inter_mode(this_mode) &&
7839 use_masked_motion_search(COMPOUND_WEDGE)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007840 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7841 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00007842 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007843 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7844 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7845 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007846 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007847 mbmi->mv[0].as_int = cur_mv[0].as_int;
7848 mbmi->mv[1].as_int = cur_mv[1].as_int;
7849 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007850 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7851#if CONFIG_SUPERTX
7852 0, 0,
7853#endif // CONFIG_SUPERTX
7854 preds0, strides, preds1,
7855 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007856 }
7857 av1_subtract_plane(x, bsize, 0);
7858 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7859 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7860 if (rd != INT64_MAX)
7861 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7862 best_rd_cur = rd;
7863
7864 } else {
David Barker426a9972017-01-27 11:03:11 +00007865 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7866#if CONFIG_SUPERTX
7867 0, 0,
7868#endif // CONFIG_SUPERTX
7869 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007870 av1_subtract_plane(x, bsize, 0);
7871 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7872 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7873 if (rd != INT64_MAX)
7874 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7875 best_rd_cur = rd;
7876 }
7877 return best_rd_cur;
7878}
Yaowu Xuc27fc142016-08-22 16:08:15 -07007879#endif // CONFIG_EXT_INTER
7880
7881static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08007882 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
7883 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007884 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
7885 int mi_col,
Yue Chencb60b182016-10-13 15:18:22 -07007886#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -07007887 uint8_t *above_pred_buf[3], int above_pred_stride[3],
7888 uint8_t *left_pred_buf[3], int left_pred_stride[3],
Yue Chencb60b182016-10-13 15:18:22 -07007889#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007890#if CONFIG_EXT_INTER
7891 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME],
7892 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME],
Sarah Parker6fdc8532016-11-16 17:47:13 -08007893 int *compmode_interintra_cost, int *compmode_interinter_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007894 int64_t (*const modelled_rd)[TOTAL_REFS_PER_FRAME],
7895#else
7896 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
7897#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07007898 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME],
Angie Chiang76159122016-11-09 12:13:22 -08007899 int (*single_skippable)[TOTAL_REFS_PER_FRAME], const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07007900 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007901 MACROBLOCKD *xd = &x->e_mbd;
7902 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7903 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7904 const int is_comp_pred = has_second_ref(mbmi);
7905 const int this_mode = mbmi->mode;
7906 int_mv *frame_mv = mode_mv[this_mode];
7907 int i;
7908 int refs[2] = { mbmi->ref_frame[0],
7909 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
7910 int_mv cur_mv[2];
7911 int rate_mv = 0;
7912#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07007913 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007914 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007915 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
7916 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
7917 const unsigned int *const interintra_mode_cost =
7918 cpi->interintra_mode_cost[size_group_lookup[bsize]];
7919 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7920#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07007921 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007922#endif
7923#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007924#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007925 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
7926#else
7927 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07007928#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007929 uint8_t *tmp_buf;
7930
Yue Chencb60b182016-10-13 15:18:22 -07007931#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007932 MOTION_MODE motion_mode, last_motion_mode_allowed;
Angie Chiang76159122016-11-09 12:13:22 -08007933 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7934 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007935#if CONFIG_VAR_TX
7936 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7937#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07007938 int64_t best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08007939 MB_MODE_INFO base_mbmi, best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007940#if CONFIG_EXT_INTER
7941 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007942 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007943#if CONFIG_MOTION_VAR
7944 int rate_mv_bmc;
7945#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007946#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007947#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07007948#if CONFIG_WARPED_MOTION
Debargha Mukherjeee6eb3b52017-02-26 08:50:56 -08007949 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
Yue Chen69f18e12016-09-08 14:48:15 -07007950#endif // CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07007951 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00007952 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007953 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007954
7955 int skip_txfm_sb = 0;
7956 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08007957 int16_t mode_ctx;
Angie Chiang76159122016-11-09 12:13:22 -08007958#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7959 av1_invalid_rd_stats(&best_rd_stats);
7960#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007961
7962#if CONFIG_EXT_INTER
7963 *compmode_interintra_cost = 0;
7964 mbmi->use_wedge_interintra = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007965 *compmode_interinter_cost = 0;
7966 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007967
7968 // is_comp_interintra_pred implies !is_comp_pred
7969 assert(!is_comp_interintra_pred || (!is_comp_pred));
7970 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
7971 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
7972#endif // CONFIG_EXT_INTER
7973
7974#if CONFIG_REF_MV
7975#if CONFIG_EXT_INTER
7976 if (is_comp_pred)
7977 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
7978 else
7979#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007980 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
7981 mbmi->ref_frame, bsize, -1);
Yaowu Xub0d0d002016-11-22 09:26:43 -08007982#else // CONFIG_REF_MV
7983 mode_ctx = mbmi_ext->mode_context[refs[0]];
7984#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07007985
Yaowu Xuf883b422016-08-30 14:01:10 -07007986#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007987 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7988 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7989 else
Yaowu Xuf883b422016-08-30 14:01:10 -07007990#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007991 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00007992 // Make sure that we didn't leave the plane destination buffers set
7993 // to tmp_buf at the end of the last iteration
7994 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007995
Yue Chen69f18e12016-09-08 14:48:15 -07007996#if CONFIG_WARPED_MOTION
7997 mbmi->num_proj_ref[0] = 0;
7998 mbmi->num_proj_ref[1] = 0;
7999#endif // CONFIG_WARPED_MOTION
8000
Yaowu Xuc27fc142016-08-22 16:08:15 -07008001 if (is_comp_pred) {
8002 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8003 frame_mv[refs[1]].as_int == INVALID_MV)
8004 return INT64_MAX;
8005 }
8006
Yue Chene9638cc2016-10-10 12:37:54 -07008007 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008008 if (have_newmv_in_inter_mode(this_mode)) {
8009 if (is_comp_pred) {
8010#if CONFIG_EXT_INTER
8011 for (i = 0; i < 2; ++i) {
8012 single_newmv[refs[i]].as_int = single_newmvs[mv_idx][refs[i]].as_int;
8013 }
8014
8015 if (this_mode == NEW_NEWMV) {
8016 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8017 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8018
8019 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
8020 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
8021 single_newmv, &rate_mv, 0);
8022 } else {
8023#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008024 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008025#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008026 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07008027 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008028 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008029#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008030 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008031#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008032 rate_mv += av1_mv_bit_cost(
Zoe Liu82c8c922016-11-01 14:52:34 -07008033 &frame_mv[refs[1]].as_mv, &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008034 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8035 }
8036 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
8037 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07008038 rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07008039 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008040 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008041 } else {
8042 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07008043 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07008044 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008045 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008046 }
8047#else
8048 // Initialize mv using single prediction mode result.
8049 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8050 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8051
8052 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
8053 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col,
8054 single_newmv, &rate_mv, 0);
8055 } else {
8056#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008057 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008058#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008059 rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07008060 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008061 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008062#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008063 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008064#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008065 rate_mv += av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
Zoe Liu82c8c922016-11-01 14:52:34 -07008066 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
Yaowu Xuf883b422016-08-30 14:01:10 -07008067 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008068 }
8069#endif // CONFIG_EXT_INTER
8070 } else {
8071#if CONFIG_EXT_INTER
8072 if (is_comp_interintra_pred) {
8073 x->best_mv = single_newmvs[mv_idx][refs[0]];
8074 rate_mv = single_newmvs_rate[mv_idx][refs[0]];
8075 } else {
8076 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx,
8077 &rate_mv);
8078 single_newmvs[mv_idx][refs[0]] = x->best_mv;
8079 single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
8080 }
8081#else
8082 single_motion_search(cpi, x, bsize, mi_row, mi_col, &rate_mv);
8083 single_newmv[refs[0]] = x->best_mv;
8084#endif // CONFIG_EXT_INTER
8085
8086 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
8087
8088 frame_mv[refs[0]] = x->best_mv;
8089 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
8090
8091 // Estimate the rate implications of a new mv but discount this
8092 // under certain circumstances where we want to help initiate a weak
8093 // motion field, where the distortion gain for a single block may not
8094 // be enough to overcome the cost of a new mv.
8095 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008096 rate_mv = AOMMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008097 }
8098 }
Angie Chiang76159122016-11-09 12:13:22 -08008099 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008100 }
8101
8102 for (i = 0; i < is_comp_pred + 1; ++i) {
8103 cur_mv[i] = frame_mv[refs[i]];
8104// Clip "next_nearest" so that it does not extend to far out of image
8105#if CONFIG_EXT_INTER
8106 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
8107#else
8108 if (this_mode != NEWMV)
8109#endif // CONFIG_EXT_INTER
8110 clamp_mv2(&cur_mv[i].as_mv, xd);
8111
8112 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8113 mbmi->mv[i].as_int = cur_mv[i].as_int;
8114 }
8115
8116#if CONFIG_REF_MV
8117#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008118 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008119#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008120 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008121#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008122 {
8123#if !CONFIG_EXT_INTER
8124 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
8125#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008126 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8127 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8128 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8129
8130 for (i = 0; i < 2; ++i) {
8131 clamp_mv2(&cur_mv[i].as_mv, xd);
8132 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8133 mbmi->mv[i].as_int = cur_mv[i].as_int;
8134 }
8135 }
8136 }
8137
8138#if CONFIG_EXT_INTER
8139 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8140 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
8141 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8142
8143 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8144 clamp_mv2(&cur_mv[0].as_mv, xd);
8145 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8146 mbmi->mv[0].as_int = cur_mv[0].as_int;
8147 }
8148
8149 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
8150 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8151
8152 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8153 clamp_mv2(&cur_mv[1].as_mv, xd);
8154 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8155 mbmi->mv[1].as_int = cur_mv[1].as_int;
8156 }
8157 }
8158
8159 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8160 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
8161 this_mode == NEAR_NEARMV) {
8162 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
8163
8164 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8165 clamp_mv2(&cur_mv[0].as_mv, xd);
8166 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8167 mbmi->mv[0].as_int = cur_mv[0].as_int;
8168 }
8169
8170 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
8171 this_mode == NEAR_NEARMV) {
8172 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
8173
8174 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8175 clamp_mv2(&cur_mv[1].as_mv, xd);
8176 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8177 mbmi->mv[1].as_int = cur_mv[1].as_int;
8178 }
8179 }
8180#else
8181 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008182 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008183 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8184 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8185 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8186 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8187
8188 for (i = 0; i < 2; ++i) {
8189 clamp_mv2(&cur_mv[i].as_mv, xd);
8190 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8191 mbmi->mv[i].as_int = cur_mv[i].as_int;
8192 }
8193 }
8194 }
8195#endif // CONFIG_EXT_INTER
8196#endif // CONFIG_REF_MV
8197
8198 // do first prediction into the destination buffer. Do the next
8199 // prediction into a temporary buffer. Then keep track of which one
8200 // of these currently holds the best predictor, and use the other
8201 // one for future predictions. In the end, copy from tmp_buf to
8202 // dst if necessary.
8203 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008204 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8205 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008206 }
8207 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008208 orig_dst.plane[i] = xd->plane[i].dst.buf;
8209 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008210 }
8211
8212 // We don't include the cost of the second reference here, because there
8213 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8214 // words if you present them in that order, the second one is always known
8215 // if the first is known.
8216 //
8217 // Under some circumstances we discount the cost of new mv mode to encourage
8218 // initiation of a motion field.
8219 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8220 refs[0])) {
8221#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008222 rd_stats->rate +=
8223 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
8224 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008225#else
Angie Chiang76159122016-11-09 12:13:22 -08008226 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8227 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008228#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8229 } else {
8230#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008231 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008232#else
Angie Chiang76159122016-11-09 12:13:22 -08008233 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008234#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8235 }
8236
Angie Chiang76159122016-11-09 12:13:22 -08008237 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008238#if CONFIG_EXT_INTER
8239 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8240#else
8241 mbmi->mode != NEARESTMV
8242#endif // CONFIG_EXT_INTER
8243 )
8244 return INT64_MAX;
8245
Angie Chiang1b5bd292017-02-21 16:33:24 -08008246 InterpFilter assign_filter = SWITCHABLE;
8247
Angie Chiang75c22092016-10-25 12:19:16 -07008248 if (cm->interp_filter == SWITCHABLE) {
Angie Chiang1b5bd292017-02-21 16:33:24 -08008249#if !CONFIG_DUAL_FILTER
Jingning Han203b1d32017-01-12 16:00:13 -08008250 assign_filter =
8251 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
Angie Chiang75c22092016-10-25 12:19:16 -07008252#endif
8253 } else {
8254 assign_filter = cm->interp_filter;
8255 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008256
Angie Chiang75c22092016-10-25 12:19:16 -07008257 { // Do interpolation filter search in the parentheses
8258 int tmp_rate;
8259 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008260#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07008261 mbmi->interp_filter[0] =
8262 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8263 mbmi->interp_filter[1] =
8264 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8265 mbmi->interp_filter[2] =
8266 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8267 mbmi->interp_filter[3] =
8268 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008269#else
Angie Chiang75c22092016-10-25 12:19:16 -07008270 mbmi->interp_filter =
8271 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008272#endif
Angie Chiang75c22092016-10-25 12:19:16 -07008273 rs = av1_get_switchable_rate(cpi, xd);
David Barkerac37fa32016-12-02 12:30:21 +00008274 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Angie Chiang75c22092016-10-25 12:19:16 -07008275 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8276 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8277 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008278
Angie Chiang75c22092016-10-25 12:19:16 -07008279 if (assign_filter == SWITCHABLE) {
8280 // do interp_filter search
8281 if (av1_is_interp_needed(xd)) {
Angie Chiang5678ad92016-11-21 09:38:40 -08008282#if CONFIG_DUAL_FILTER
8283 const int filter_set_size = DUAL_FILTER_SET_SIZE;
8284#else
8285 const int filter_set_size = SWITCHABLE_FILTERS;
8286#endif
Angie Chiang75c22092016-10-25 12:19:16 -07008287 int best_in_temp = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008288#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07008289 InterpFilter best_filter[4];
8290 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008291#else
Angie Chiang75c22092016-10-25 12:19:16 -07008292 InterpFilter best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008293#endif
David Barkerac37fa32016-12-02 12:30:21 +00008294 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07008295 // EIGHTTAP_REGULAR mode is calculated beforehand
Angie Chiang5678ad92016-11-21 09:38:40 -08008296 for (i = 1; i < filter_set_size; ++i) {
Angie Chiang75c22092016-10-25 12:19:16 -07008297 int tmp_skip_sb = 0;
8298 int64_t tmp_skip_sse = INT64_MAX;
8299 int tmp_rs;
Angie Chiang3655dcd2016-10-28 09:05:27 -07008300 int64_t tmp_rd;
Angie Chiang75c22092016-10-25 12:19:16 -07008301#if CONFIG_DUAL_FILTER
8302 mbmi->interp_filter[0] = filter_sets[i][0];
8303 mbmi->interp_filter[1] = filter_sets[i][1];
8304 mbmi->interp_filter[2] = filter_sets[i][0];
8305 mbmi->interp_filter[3] = filter_sets[i][1];
8306#else
8307 mbmi->interp_filter = i;
8308#endif
8309 tmp_rs = av1_get_switchable_rate(cpi, xd);
David Barkerac37fa32016-12-02 12:30:21 +00008310 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Angie Chiang75c22092016-10-25 12:19:16 -07008311 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8312 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
8313 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008314
Angie Chiang75c22092016-10-25 12:19:16 -07008315 if (tmp_rd < rd) {
8316 rd = tmp_rd;
8317 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008318#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07008319 av1_copy(best_filter, mbmi->interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008320#else
Angie Chiang75c22092016-10-25 12:19:16 -07008321 best_filter = mbmi->interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008322#endif
Angie Chiang75c22092016-10-25 12:19:16 -07008323 skip_txfm_sb = tmp_skip_sb;
8324 skip_sse_sb = tmp_skip_sse;
8325 best_in_temp = !best_in_temp;
8326 if (best_in_temp) {
David Barkerac37fa32016-12-02 12:30:21 +00008327 restore_dst_buf(xd, orig_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07008328 } else {
David Barkerac37fa32016-12-02 12:30:21 +00008329 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07008330 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008331 }
8332 }
Angie Chiang75c22092016-10-25 12:19:16 -07008333 if (best_in_temp) {
David Barkerac37fa32016-12-02 12:30:21 +00008334 restore_dst_buf(xd, tmp_dst);
Angie Chiang75c22092016-10-25 12:19:16 -07008335 } else {
David Barkerac37fa32016-12-02 12:30:21 +00008336 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008337 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008338#if CONFIG_DUAL_FILTER
Angie Chiang75c22092016-10-25 12:19:16 -07008339 av1_copy(mbmi->interp_filter, best_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008340#else
Angie Chiang75c22092016-10-25 12:19:16 -07008341 mbmi->interp_filter = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008342#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008343 } else {
Angie Chiange7e37202017-02-21 17:08:37 -08008344#if CONFIG_DUAL_FILTER
8345 int dir;
8346 for (dir = 0; dir < 4; ++dir)
8347 assert(mbmi->interp_filter[dir] == EIGHTTAP_REGULAR);
Angie Chiang75c22092016-10-25 12:19:16 -07008348#else
Angie Chiange7e37202017-02-21 17:08:37 -08008349 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
Angie Chiang75c22092016-10-25 12:19:16 -07008350#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008351 }
8352 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008353 }
8354
Yaowu Xuc27fc142016-08-22 16:08:15 -07008355#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008356#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008357 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008358 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008359 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008360#if CONFIG_MOTION_VAR
8361 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008362#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008363#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008364
Sarah Parker6fdc8532016-11-16 17:47:13 -08008365 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008366 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008367 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008368 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8369 INTERINTER_COMPOUND_DATA best_compound_data;
8370 int_mv best_mv[2];
8371 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008372 int tmp_skip_txfm_sb;
8373 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08008374 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008375 uint8_t pred0[2 * MAX_SB_SQUARE];
8376 uint8_t pred1[2 * MAX_SB_SQUARE];
8377 uint8_t *preds0[1] = { pred0 };
8378 uint8_t *preds1[1] = { pred1 };
8379 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008380 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008381 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008382 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008383
Sarah Parker6fdc8532016-11-16 17:47:13 -08008384 best_mv[0].as_int = cur_mv[0].as_int;
8385 best_mv[1].as_int = cur_mv[1].as_int;
8386 memset(&best_compound_data, 0, sizeof(INTERINTER_COMPOUND_DATA));
Sarah Parker6fddd182016-11-10 20:57:20 -08008387 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8388 av1_compound_type_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008389
Sarah Parker42d96102017-01-31 21:05:27 -08008390 if (masked_compound_used) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008391 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008392 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008393 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008394 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008395 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008396 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008397
Sarah Parker6fdc8532016-11-16 17:47:13 -08008398 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008399 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008400 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008401 best_rd_cur = INT64_MAX;
8402 mbmi->interinter_compound_data.type = cur_type;
8403 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
8404 bsize, mbmi->interinter_compound_data.type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008405 (masked_compound_used
8406 ? compound_type_cost[mbmi->interinter_compound_data.type]
8407 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008408
Sarah Parker6fdc8532016-11-16 17:47:13 -08008409 switch (cur_type) {
8410 case COMPOUND_AVERAGE:
David Barkerac37fa32016-12-02 12:30:21 +00008411 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008412 av1_subtract_plane(x, bsize, 0);
8413 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8414 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8415 INT64_MAX);
8416 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008417 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008418 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008419 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008420 break;
8421 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008422 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8423 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008424 best_rd_cur = build_and_cost_compound_wedge(
David Barkerac37fa32016-12-02 12:30:21 +00008425 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8426 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008427 }
8428 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008429#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008430 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008431 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8432 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker569edda2016-12-14 14:57:38 -08008433 best_rd_cur = build_and_cost_compound_seg(
8434 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8435 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008436 }
8437 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008438#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008439 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008440 }
Sarah Parker2e604882017-01-17 17:31:25 -08008441
8442 if (best_rd_cur < best_rd_compound) {
8443 best_rd_compound = best_rd_cur;
8444 memcpy(&best_compound_data, &mbmi->interinter_compound_data,
8445 sizeof(best_compound_data));
8446 if (have_newmv_in_inter_mode(this_mode)) {
8447 if (use_masked_motion_search(cur_type)) {
8448 best_tmp_rate_mv = tmp_rate_mv;
8449 best_mv[0].as_int = mbmi->mv[0].as_int;
8450 best_mv[1].as_int = mbmi->mv[1].as_int;
8451 } else {
8452 best_mv[0].as_int = cur_mv[0].as_int;
8453 best_mv[1].as_int = cur_mv[1].as_int;
8454 }
8455 }
8456 }
8457 // reset to original mvs for next iteration
8458 mbmi->mv[0].as_int = cur_mv[0].as_int;
8459 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008460 }
Sarah Parker6fdc8532016-11-16 17:47:13 -08008461 memcpy(&mbmi->interinter_compound_data, &best_compound_data,
8462 sizeof(INTERINTER_COMPOUND_DATA));
8463 if (have_newmv_in_inter_mode(this_mode)) {
8464 mbmi->mv[0].as_int = best_mv[0].as_int;
8465 mbmi->mv[1].as_int = best_mv[1].as_int;
8466 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8467 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2e604882017-01-17 17:31:25 -08008468 if (use_masked_motion_search(mbmi->interinter_compound_data.type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008469 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8470 rate_mv = best_tmp_rate_mv;
8471 }
8472 }
8473
8474 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008475 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008477 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008478
8479 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008480
Sarah Parker6fdc8532016-11-16 17:47:13 -08008481 *compmode_interinter_cost =
8482 compound_type_cost[mbmi->interinter_compound_data.type] +
8483 av1_cost_literal(get_interinter_compound_type_bits(
8484 bsize, mbmi->interinter_compound_data.type));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008485 }
8486
8487 if (is_comp_interintra_pred) {
8488 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8489 int64_t best_interintra_rd = INT64_MAX;
8490 int rmode, rate_sum;
8491 int64_t dist_sum;
8492 int j;
8493 int64_t best_interintra_rd_nowedge = INT64_MAX;
8494 int64_t best_interintra_rd_wedge = INT64_MAX;
8495 int rwedge;
8496 int_mv tmp_mv;
8497 int tmp_rate_mv = 0;
8498 int tmp_skip_txfm_sb;
8499 int64_t tmp_skip_sse_sb;
8500 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8501 uint8_t *intrapred;
8502
Yaowu Xuf883b422016-08-30 14:01:10 -07008503#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008504 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8505 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8506 else
Yaowu Xuf883b422016-08-30 14:01:10 -07008507#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008508 intrapred = intrapred_;
8509
Emil Keyder01770b32017-01-20 18:03:11 -05008510 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008511 for (j = 0; j < MAX_MB_PLANE; j++) {
8512 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8513 xd->plane[j].dst.stride = bw;
8514 }
David Barkerac37fa32016-12-02 12:30:21 +00008515 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
8516 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008517 mbmi->ref_frame[1] = INTRA_FRAME;
8518 mbmi->use_wedge_interintra = 0;
8519
8520 for (j = 0; j < INTERINTRA_MODES; ++j) {
8521 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8522 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008523 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8524 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008525 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008526 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8527 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8528 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
8529 if (rd < best_interintra_rd) {
8530 best_interintra_rd = rd;
8531 best_interintra_mode = mbmi->interintra_mode;
8532 }
8533 }
8534 mbmi->interintra_mode = best_interintra_mode;
8535 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008536 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8537 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008538 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8539 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008540 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8541 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8542 if (rd != INT64_MAX)
8543 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
8544 best_interintra_rd = rd;
8545
8546 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008547 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008548 return INT64_MAX;
8549 }
8550 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008551 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008552 if (rd != INT64_MAX)
8553 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
8554 dist_sum);
8555 best_interintra_rd_nowedge = rd;
8556
8557 // Disbale wedge search if source variance is small
8558 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8559 mbmi->use_wedge_interintra = 1;
8560
Yaowu Xuf883b422016-08-30 14:01:10 -07008561 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8562 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008563
8564 best_interintra_rd_wedge =
8565 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8566
8567 best_interintra_rd_wedge +=
8568 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
8569 // Refine motion vector.
8570 if (have_newmv_in_inter_mode(this_mode)) {
8571 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008572 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008573 mbmi->interintra_wedge_index, 1, bsize);
8574 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
8575 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
8576 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00008577 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008578 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8579 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8580 rd = RDCOST(x->rdmult, x->rddiv,
8581 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8582 if (rd < best_interintra_rd_wedge) {
8583 best_interintra_rd_wedge = rd;
8584 } else {
8585 tmp_mv.as_int = cur_mv[0].as_int;
8586 tmp_rate_mv = rate_mv;
8587 }
8588 } else {
8589 tmp_mv.as_int = cur_mv[0].as_int;
8590 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008591 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008592 }
8593 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008594 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008595 rd =
8596 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8597 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8598 if (rd != INT64_MAX)
8599 rd = RDCOST(x->rdmult, x->rddiv,
8600 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8601 best_interintra_rd_wedge = rd;
8602 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8603 mbmi->use_wedge_interintra = 1;
8604 best_interintra_rd = best_interintra_rd_wedge;
8605 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008606 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008607 rate_mv = tmp_rate_mv;
8608 } else {
8609 mbmi->use_wedge_interintra = 0;
8610 best_interintra_rd = best_interintra_rd_nowedge;
8611 mbmi->mv[0].as_int = cur_mv[0].as_int;
8612 }
8613 } else {
8614 mbmi->use_wedge_interintra = 0;
8615 best_interintra_rd = best_interintra_rd_nowedge;
8616 }
8617 }
8618
8619 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008620 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008621 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008622 *compmode_interintra_cost += interintra_mode_cost[mbmi->interintra_mode];
8623 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008624 *compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008625 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8626 if (mbmi->use_wedge_interintra) {
8627 *compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008628 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008629 }
8630 }
8631 } else if (is_interintra_allowed(mbmi)) {
8632 *compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008633 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008634 }
8635
Angie Chiang75c22092016-10-25 12:19:16 -07008636 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008637 int tmp_rate;
8638 int64_t tmp_dist;
David Barkerac37fa32016-12-02 12:30:21 +00008639 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008640 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8641 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8642 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
8643 }
Angie Chiang75c22092016-10-25 12:19:16 -07008644#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008645
8646#if CONFIG_DUAL_FILTER
8647 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
8648#else
8649 if (!is_comp_pred) single_filter[this_mode][refs[0]] = mbmi->interp_filter;
8650#endif
8651
8652#if CONFIG_EXT_INTER
8653 if (modelled_rd != NULL) {
8654 if (is_comp_pred) {
8655 const int mode0 = compound_ref0_mode(this_mode);
8656 const int mode1 = compound_ref1_mode(this_mode);
8657 int64_t mrd =
Yaowu Xuf883b422016-08-30 14:01:10 -07008658 AOMMIN(modelled_rd[mode0][refs[0]], modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008659 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008660 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008661 return INT64_MAX;
8662 }
8663 } else if (!is_comp_interintra_pred) {
8664 modelled_rd[this_mode][refs[0]] = rd;
8665 }
8666 }
8667#endif // CONFIG_EXT_INTER
8668
8669 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8670 // if current pred_error modeled rd is substantially more than the best
8671 // so far, do not bother doing full rd
8672 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008673 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008674 return INT64_MAX;
8675 }
8676 }
8677
Angie Chiang76159122016-11-09 12:13:22 -08008678 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008679#if CONFIG_WARPED_MOTION
8680 aom_clear_system_state();
8681 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
Debargha Mukherjee8b613212017-01-25 13:50:16 -08008682#if CONFIG_EXT_INTER
8683 best_bmc_mbmi.num_proj_ref[0] = mbmi->num_proj_ref[0];
8684#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008685#endif // CONFIG_WARPED_MOTION
8686#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008687 rate2_nocoeff = rd_stats->rate;
Yue Chen69f18e12016-09-08 14:48:15 -07008688 last_motion_mode_allowed = motion_mode_allowed(mbmi);
Yue Chend326f762016-11-29 12:11:32 -08008689 base_mbmi = *mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008690#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008691
Yue Chencb60b182016-10-13 15:18:22 -07008692#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008693 best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08008694 for (motion_mode = SIMPLE_TRANSLATION;
Yue Chen69f18e12016-09-08 14:48:15 -07008695 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8696 int64_t tmp_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08008697 int tmp_rate;
Yue Chen69f18e12016-09-08 14:48:15 -07008698 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008699#if CONFIG_EXT_INTER
Yue Chend326f762016-11-29 12:11:32 -08008700 int tmp_rate2 =
8701 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008702#else
8703 int tmp_rate2 = rate2_nocoeff;
8704#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008705
Yue Chend326f762016-11-29 12:11:32 -08008706 *mbmi = base_mbmi;
8707 mbmi->motion_mode = motion_mode;
Yue Chencb60b182016-10-13 15:18:22 -07008708#if CONFIG_MOTION_VAR
Yue Chencb60b182016-10-13 15:18:22 -07008709 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008710#if CONFIG_EXT_INTER
8711 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07008712 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008713#endif // CONFIG_EXT_INTER
8714 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008715 int tmp_rate_mv = 0;
8716
Yue Chene9638cc2016-10-10 12:37:54 -07008717 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008718#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07008719 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008720#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07008721 &tmp_rate_mv);
8722 mbmi->mv[0].as_int = x->best_mv.as_int;
8723 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8724 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008725 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008726 }
8727#if CONFIG_EXT_INTER
8728 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8729#else
8730 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8731#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008732#if CONFIG_DUAL_FILTER
8733 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
Yue Chend326f762016-11-29 12:11:32 -08008734 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008735 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
Yue Chend326f762016-11-29 12:11:32 -08008736 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
Angie Chiang1733f6b2017-01-05 09:52:20 -08008737#endif // CONFIG_DUAL_FILTER
David Barkerac37fa32016-12-02 12:30:21 +00008738 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008739#if CONFIG_EXT_INTER
8740 } else {
David Barkerac37fa32016-12-02 12:30:21 +00008741 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008742#endif // CONFIG_EXT_INTER
8743 }
Yue Chene9638cc2016-10-10 12:37:54 -07008744 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, above_pred_buf,
8745 above_pred_stride, left_pred_buf,
8746 left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008747 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8748 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8749 }
Yue Chencb60b182016-10-13 15:18:22 -07008750#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008751
8752#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07008753 if (mbmi->motion_mode == WARPED_CAUSAL) {
Yue Chen69f18e12016-09-08 14:48:15 -07008754#if CONFIG_EXT_INTER
8755 *mbmi = best_bmc_mbmi;
8756 mbmi->motion_mode = WARPED_CAUSAL;
8757#endif // CONFIG_EXT_INTER
8758 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8759#if CONFIG_DUAL_FILTER
8760 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8761 ? EIGHTTAP_REGULAR
8762 : cm->interp_filter;
8763 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8764 ? EIGHTTAP_REGULAR
8765 : cm->interp_filter;
8766#else
8767 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8768 : cm->interp_filter;
8769#endif // CONFIG_DUAL_FILTER
8770
8771 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
8772 &mbmi->wm_params[0]) == 0) {
8773 int plane;
8774#if CONFIG_AOM_HIGHBITDEPTH
8775 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
8776#endif // CONFIG_AOM_HIGHBITDEPTH
8777
8778 for (plane = 0; plane < 3; ++plane) {
8779 const struct macroblockd_plane *pd = &xd->plane[plane];
8780
8781 av1_warp_plane(&mbmi->wm_params[0],
8782#if CONFIG_AOM_HIGHBITDEPTH
8783 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
8784#endif // CONFIG_AOM_HIGHBITDEPTH
8785 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
8786 pd->pre[0].stride, pd->dst.buf,
8787 (mi_col * MI_SIZE) >> pd->subsampling_x,
8788 (mi_row * MI_SIZE) >> pd->subsampling_y,
Jingning Hanff6ee6a2016-12-07 09:55:21 -08008789 (xd->n8_w * MI_SIZE) >> pd->subsampling_x,
8790 (xd->n8_h * MI_SIZE) >> pd->subsampling_y,
8791 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
8792 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07008793 }
8794
8795 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8796 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8797 } else {
8798 continue;
8799 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008800 }
8801#endif // CONFIG_WARPED_MOTION
8802 x->skip = 0;
8803
Yue Chen8a78a2b2016-11-17 18:23:38 -08008804 rd_stats->dist = 0;
8805 rd_stats->sse = 0;
8806 rd_stats->skip = 1;
Angie Chiang76159122016-11-09 12:13:22 -08008807 rd_stats->rate = tmp_rate2;
Yue Chen69f18e12016-09-08 14:48:15 -07008808 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8809#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8810 if (last_motion_mode_allowed == WARPED_CAUSAL)
8811#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8812 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8813#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8814 else
8815 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8816#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8817 }
8818#if CONFIG_WARPED_MOTION
8819 if (mbmi->motion_mode == WARPED_CAUSAL) {
8820 rd_stats->rate -= rs;
8821 }
8822#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07008823#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008825 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07008826 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08008827
Yaowu Xu1e761992016-11-09 15:01:47 -08008828 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08008829 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008830#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08008831 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08008832 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008833 } else {
8834 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08008835 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008836 for (idy = 0; idy < xd->n8_h; ++idy)
8837 for (idx = 0; idx < xd->n8_w; ++idx)
8838 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08008839 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08008840 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8841 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008842#else
Yaowu Xu1e761992016-11-09 15:01:47 -08008843 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08008844 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008845/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07008846#endif // CONFIG_VAR_TX
8847
Angie Chiang76159122016-11-09 12:13:22 -08008848 if (rd_stats_y->rate == INT_MAX) {
8849 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07008850#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8851 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008852 continue;
8853 } else {
Yue Chencb60b182016-10-13 15:18:22 -07008854#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +00008855 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008856 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07008857#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008858 }
Yue Chencb60b182016-10-13 15:18:22 -07008859#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008860 }
8861
Angie Chiang76159122016-11-09 12:13:22 -08008862 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008863
Angie Chiang76159122016-11-09 12:13:22 -08008864 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8865 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08008866/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07008867#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07008868 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08008869 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08008870#else
8871 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08008872 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08008873#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07008874 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07008875#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008876 continue;
8877#else
David Barkerac37fa32016-12-02 12:30:21 +00008878 restore_dst_buf(xd, orig_dst);
Debargha Mukherjee0e119122016-11-04 12:10:23 -07008879 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07008880#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008881 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08008882 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08008883 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08008884#if CONFIG_RD_DEBUG
8885 // record transform block coefficient cost
8886 // TODO(angiebird): So far rd_debug tool only detects descrepancy of
8887 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8888 // here because we already collect the coefficient cost. Move this part to
8889 // other place when we need to compare non-coefficient cost.
8890 mbmi->rd_stats = *rd_stats;
8891#endif
Yue Chencb60b182016-10-13 15:18:22 -07008892#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008893 if (rd_stats->skip) {
8894 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8895 rd_stats_y->rate = 0;
8896 rd_stats_uv->rate = 0;
8897 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008898 mbmi->skip = 0;
8899 // here mbmi->skip temporarily plays a role as what this_skip2 does
8900 } else if (!xd->lossless[mbmi->segment_id] &&
8901 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08008902 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07008903 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08008904 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07008905 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08008906 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8907 rd_stats->sse))) {
8908 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8909 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8910 rd_stats->dist = rd_stats->sse;
8911 rd_stats_y->rate = 0;
8912 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008913 mbmi->skip = 1;
8914 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008915 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008916 mbmi->skip = 0;
8917 }
8918 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008919#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008920 } else {
8921 x->skip = 1;
8922 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07008923 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008924
8925// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07008926#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008927 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07008928#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008929 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008930
Angie Chiang76159122016-11-09 12:13:22 -08008931 rd_stats->dist = skip_sse_sb;
8932 rd_stats->sse = skip_sse_sb;
8933 rd_stats_y->rate = 0;
8934 rd_stats_uv->rate = 0;
8935 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008936 }
Yue Chen8a78a2b2016-11-17 18:23:38 -08008937#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8938 if (!is_comp_pred && mbmi->motion_mode == SIMPLE_TRANSLATION)
8939 single_skippable[this_mode][refs[0]] = rd_stats->skip;
8940#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen19e7aa82016-11-30 14:05:39 -08008941
Sarah Parkere5299862016-08-16 14:57:37 -07008942#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08008943 if (this_mode == ZEROMV
8944#if CONFIG_EXT_INTER
8945 || this_mode == ZERO_ZEROMV
8946#endif // CONFIG_EXT_INTER
8947 ) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08008948 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
Angie Chiang76159122016-11-09 12:13:22 -08008949 if (is_comp_pred)
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08008950 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
Yue Chen19e7aa82016-11-30 14:05:39 -08008951 if (is_nontrans_global_motion(xd)) {
8952 rd_stats->rate -= rs;
8953#if CONFIG_DUAL_FILTER
8954 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8955 ? EIGHTTAP_REGULAR
8956 : cm->interp_filter;
8957 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8958 ? EIGHTTAP_REGULAR
8959 : cm->interp_filter;
8960#else
8961 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8962 ? EIGHTTAP_REGULAR
8963 : cm->interp_filter;
8964#endif // CONFIG_DUAL_FILTER
8965 }
Sarah Parkere5299862016-08-16 14:57:37 -07008966 }
8967#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008968
Yue Chencb60b182016-10-13 15:18:22 -07008969#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008970 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07008971 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008972 best_mbmi = *mbmi;
8973 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08008974 best_rd_stats = *rd_stats;
8975 best_rd_stats_y = *rd_stats_y;
8976 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008977#if CONFIG_VAR_TX
8978 for (i = 0; i < MAX_MB_PLANE; ++i)
8979 memcpy(best_blk_skip[i], x->blk_skip[i],
8980 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8981#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07008982 best_xskip = x->skip;
8983 best_disable_skip = *disable_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008984 }
8985 }
8986
8987 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08008988 av1_invalid_rd_stats(rd_stats);
David Barkerac37fa32016-12-02 12:30:21 +00008989 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008990 return INT64_MAX;
8991 }
8992 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008993 *rd_stats = best_rd_stats;
8994 *rd_stats_y = best_rd_stats_y;
8995 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008996#if CONFIG_VAR_TX
8997 for (i = 0; i < MAX_MB_PLANE; ++i)
8998 memcpy(x->blk_skip[i], best_blk_skip[i],
8999 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9000#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009001 x->skip = best_xskip;
9002 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07009003#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009004
Yue Chen8a78a2b2016-11-17 18:23:38 -08009005#if !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Angie Chiang76159122016-11-09 12:13:22 -08009006 if (!is_comp_pred) single_skippable[this_mode][refs[0]] = rd_stats->skip;
Yue Chencb60b182016-10-13 15:18:22 -07009007#endif // !(CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009008
David Barkerac37fa32016-12-02 12:30:21 +00009009 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009010 return 0; // The rate-distortion cost will be re-calculated by caller.
9011}
9012
Urvang Joshi52648442016-10-13 17:27:51 -07009013void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
9014 RD_COST *rd_cost, BLOCK_SIZE bsize,
9015 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9016 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009017 MACROBLOCKD *const xd = &x->e_mbd;
9018 struct macroblockd_plane *const pd = xd->plane;
9019 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9020 int y_skip = 0, uv_skip = 0;
9021 int64_t dist_y = 0, dist_uv = 0;
9022 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009023 const int unify_bsize = CONFIG_CB4X4;
9024
Yaowu Xuc27fc142016-08-22 16:08:15 -07009025 ctx->skip = 0;
9026 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009027 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009028
Jingning Han271bb2c2016-12-14 12:34:46 -08009029 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009030 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9031 &y_skip, bsize, best_rd) >= best_rd) {
9032 rd_cost->rate = INT_MAX;
9033 return;
9034 }
9035 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009036 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07009037 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009038 rd_cost->rate = INT_MAX;
9039 return;
9040 }
9041 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009042 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9043 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009044
9045#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009046#if !CONFIG_CHROMA_2X2
Jingning Han8efdbc82017-02-19 14:40:03 -08009047 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Jingning Han31b6a4f2017-02-23 11:05:53 -08009048#endif
Jingning Han8efdbc82017-02-19 14:40:03 -08009049 if (!x->skip_chroma_rd)
9050 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9051 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009052#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009053 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009054 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009055#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009056
9057 if (y_skip && uv_skip) {
9058 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07009059 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009060 rd_cost->dist = dist_y + dist_uv;
9061 } else {
9062 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07009063 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009064 rd_cost->dist = dist_y + dist_uv;
9065 }
9066
9067 ctx->mic = *xd->mi[0];
9068 ctx->mbmi_ext = *x->mbmi_ext;
9069 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9070}
9071
Yaowu Xuc27fc142016-08-22 16:08:15 -07009072// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009073int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009074 return (cpi->oxcf.pass == 2) &&
9075 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9076 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9077}
9078
9079// Checks to see if a super block is on a horizontal image edge.
9080// In most cases this is the "real" edge unless there are formatting
9081// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009082int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009083 int top_edge = 0;
9084 int bottom_edge = cpi->common.mi_rows;
9085 int is_active_h_edge = 0;
9086
9087 // For two pass account for any formatting bars detected.
9088 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009089 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009090
9091 // The inactive region is specified in MBs not mi units.
9092 // The image edge is in the following MB row.
9093 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9094
9095 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009096 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009097 }
9098
9099 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9100 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9101 is_active_h_edge = 1;
9102 }
9103 return is_active_h_edge;
9104}
9105
9106// Checks to see if a super block is on a vertical image edge.
9107// In most cases this is the "real" edge unless there are formatting
9108// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009109int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009110 int left_edge = 0;
9111 int right_edge = cpi->common.mi_cols;
9112 int is_active_v_edge = 0;
9113
9114 // For two pass account for any formatting bars detected.
9115 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009116 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009117
9118 // The inactive region is specified in MBs not mi units.
9119 // The image edge is in the following MB row.
9120 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9121
9122 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009123 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009124 }
9125
9126 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9127 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9128 is_active_v_edge = 1;
9129 }
9130 return is_active_v_edge;
9131}
9132
9133// Checks to see if a super block is at the edge of the active image.
9134// In most cases this is the "real" edge unless there are formatting
9135// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009136int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009137 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9138 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009139}
9140
Urvang Joshib100db72016-10-12 16:28:56 -07009141#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009142static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009143 MACROBLOCKD *const xd = &x->e_mbd;
9144 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9145 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9146 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009147 int src_stride = x->plane[1].src.stride;
9148 const uint8_t *const src_u = x->plane[1].src.buf;
9149 const uint8_t *const src_v = x->plane[2].src.buf;
9150 float *const data = x->palette_buffer->kmeans_data_buf;
9151 float centroids[2 * PALETTE_MAX_SIZE];
9152 uint8_t *const color_map = xd->plane[1].color_index_map;
9153 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07009154#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009155 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9156 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07009157#endif // CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009158 int plane_block_width, plane_block_height, rows, cols;
9159 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9160 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009161 (void)cpi;
9162
9163 for (r = 0; r < rows; ++r) {
9164 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009165#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009166 if (cpi->common.use_highbitdepth) {
9167 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9168 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9169 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009170#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009171 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9172 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07009173#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009174 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009175#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009176 }
9177 }
9178
9179 for (r = 1; r < 3; ++r) {
9180 for (c = 0; c < pmi->palette_size[1]; ++c) {
9181 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9182 }
9183 }
9184
Yaowu Xuf883b422016-08-30 14:01:10 -07009185 av1_calc_indices(data, centroids, color_map, rows * cols,
9186 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009187 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9188 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009189}
Urvang Joshib100db72016-10-12 16:28:56 -07009190#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009191
hui su5db97432016-10-14 16:10:14 -07009192#if CONFIG_FILTER_INTRA
9193static void pick_filter_intra_interframe(
9194 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009195 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9196 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9197 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009198#if CONFIG_EXT_INTRA
9199 int8_t *uv_angle_delta,
9200#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009201#if CONFIG_PALETTE
9202 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9203#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009204 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9205 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9206 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9207#if CONFIG_SUPERTX
9208 int *returnrate_nocoef,
9209#endif // CONFIG_SUPERTX
9210 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009211 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009212 MACROBLOCKD *const xd = &x->e_mbd;
9213 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009214#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009215 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009216#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009217 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9218 int dc_mode_index;
9219 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009220 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9221 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009222 TX_SIZE uv_tx;
9223
9224 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009225 if (av1_mode_order[i].mode == DC_PRED &&
9226 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009227 break;
9228 dc_mode_index = i;
9229 assert(i < MAX_MODES);
9230
9231 // TODO(huisu): use skip_mask for further speedup.
9232 (void)skip_mask;
9233 mbmi->mode = DC_PRED;
9234 mbmi->uv_mode = DC_PRED;
9235 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009236 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009237 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9238 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009239 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009240 return;
hui su5db97432016-10-14 16:10:14 -07009241 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009242 if (rate_y == INT_MAX) return;
9243
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009244 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9245 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009246 if (rate_uv_intra[uv_tx] == INT_MAX) {
9247 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9248 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9249 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009250#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009251 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009252#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009253 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9254#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009255 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009256#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009257 }
9258
9259 rate_uv = rate_uv_tokenonly[uv_tx];
9260 distortion_uv = dist_uv[uv_tx];
9261 skippable = skippable && skip_uv[uv_tx];
9262 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009263#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009264 if (cm->allow_screen_content_tools) {
9265 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9266 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9267 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9268 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9269 }
Urvang Joshib100db72016-10-12 16:28:56 -07009270#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009271#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009272 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009273#endif // CONFIG_EXT_INTRA
9274 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9275 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9276 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9277 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9278 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009279 }
9280
9281 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9282 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009283#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009284 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009285 rate2 += av1_cost_bit(
9286 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009287#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009288
9289 if (!xd->lossless[mbmi->segment_id]) {
9290 // super_block_yrd above includes the cost of the tx_size in the
9291 // tokenonly rate, but for intra blocks, tx_size is always coded
9292 // (prediction granularity), so we account for it in the full rate,
9293 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009294 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009295 }
9296
hui su5db97432016-10-14 16:10:14 -07009297 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9298 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9299 rate2 += write_uniform_cost(
9300 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9301#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009302 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
9303 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
9304 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009305 }
hui su5db97432016-10-14 16:10:14 -07009306#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009307 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009308 rate2 +=
9309 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9310 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9311 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9312 rate2 +=
9313 write_uniform_cost(FILTER_INTRA_MODES,
9314 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009315 }
9316 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009317 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9318 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009319
9320 rate2 += ref_costs_single[INTRA_FRAME];
9321
9322 if (skippable) {
9323 rate2 -= (rate_y + rate_uv);
9324 rate_y = 0;
9325 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009326 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009327 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009328 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009329 }
9330 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009331
9332 if (this_rd < *best_intra_rd) {
9333 *best_intra_rd = this_rd;
9334 *best_intra_mode = mbmi->mode;
9335 }
9336 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009337 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009338
9339 if (this_rd < *best_rd) {
9340 *best_mode_index = dc_mode_index;
9341 mbmi->mv[0].as_int = 0;
9342 rd_cost->rate = rate2;
9343#if CONFIG_SUPERTX
9344 if (x->skip)
9345 *returnrate_nocoef = rate2;
9346 else
9347 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009348 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9349 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9350 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009351#endif // CONFIG_SUPERTX
9352 rd_cost->dist = distortion2;
9353 rd_cost->rdcost = this_rd;
9354 *best_rd = this_rd;
9355 *best_mbmode = *mbmi;
9356 *best_skip2 = 0;
9357 *best_mode_skippable = skippable;
9358 }
9359}
hui su5db97432016-10-14 16:10:14 -07009360#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009361
Yue Chencb60b182016-10-13 15:18:22 -07009362#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009363static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9364 const MACROBLOCKD *xd, int mi_row,
9365 int mi_col, const uint8_t *above,
9366 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009367 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009368#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009369
Urvang Joshi52648442016-10-13 17:27:51 -07009370void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009371 MACROBLOCK *x, int mi_row, int mi_col,
9372 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009373#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009374 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009375#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009376 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9377 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009378 const AV1_COMMON *const cm = &cpi->common;
9379 const RD_OPT *const rd_opt = &cpi->rd;
9380 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009381 MACROBLOCKD *const xd = &x->e_mbd;
9382 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009383#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009384 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009385#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009386 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9387 const struct segmentation *const seg = &cm->seg;
9388 PREDICTION_MODE this_mode;
9389 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9390 unsigned char segment_id = mbmi->segment_id;
9391 int comp_pred, i, k;
9392 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9393 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
9394#if CONFIG_EXT_INTER
9395 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
9396 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
9397 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9398#else
9399 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9400#endif // CONFIG_EXT_INTER
James Zern7b9407a2016-05-18 23:48:05 -07009401 InterpFilter single_inter_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009402 int single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9403 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9404 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009405 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009406#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009407 AOM_LAST2_FLAG,
9408 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009409#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009410 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009411#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009412 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009413#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009414 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009415 };
9416 int64_t best_rd = best_rd_so_far;
9417 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9418 int64_t best_pred_diff[REFERENCE_MODES];
9419 int64_t best_pred_rd[REFERENCE_MODES];
9420 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009421#if CONFIG_REF_MV
9422 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9423 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9424#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009425 int best_mode_skippable = 0;
9426 int midx, best_mode_index = -1;
9427 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9428 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009429 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009430 int64_t best_intra_rd = INT64_MAX;
9431 unsigned int best_pred_sse = UINT_MAX;
9432 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009433 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9434 int64_t dist_uvs[TX_SIZES_ALL];
9435 int skip_uvs[TX_SIZES_ALL];
9436 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009437#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009438 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009439#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009440#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009441 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009442 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009443 uint8_t directional_mode_skip_mask[INTRA_MODES];
9444#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009445#if CONFIG_FILTER_INTRA
9446 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009447 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009448#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009449 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009450 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9451 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9452 int best_skip2 = 0;
9453 uint8_t ref_frame_skip_mask[2] = { 0 };
9454#if CONFIG_EXT_INTER
9455 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9456 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9457 int64_t best_single_inter_rd = INT64_MAX;
9458#else
9459 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9460#endif // CONFIG_EXT_INTER
9461 int mode_skip_start = sf->mode_skip_start + 1;
9462 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9463 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9464 int64_t mode_threshold[MAX_MODES];
9465 int *mode_map = tile_data->mode_map[bsize];
9466 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009467#if CONFIG_PVQ
9468 od_rollback_buffer pre_buf;
9469#endif
9470
Urvang Joshib100db72016-10-12 16:28:56 -07009471#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009472 const int rows = block_size_high[bsize];
9473 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009474#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9475#if CONFIG_PALETTE
9476 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009477 const MODE_INFO *above_mi = xd->above_mi;
9478 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009479#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009480#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009481#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009482 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9483 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9484#else
9485 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9486 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07009487#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009488 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9489 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
9490 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
9491 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9492 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9493 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9494 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9495 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9496 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9497
Yaowu Xuf883b422016-08-30 14:01:10 -07009498#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9500 int len = sizeof(uint16_t);
9501 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9502 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9503 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
9504 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9505 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9506 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
9507 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009508#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009509 dst_buf1[0] = tmp_buf1;
9510 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
9511 dst_buf1[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9512 dst_buf2[0] = tmp_buf2;
9513 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
9514 dst_buf2[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07009515#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009516 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009517#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009518#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009519
Yaowu Xuf883b422016-08-30 14:01:10 -07009520 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009521
Urvang Joshib100db72016-10-12 16:28:56 -07009522#if CONFIG_PALETTE
9523 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009524 if (cm->allow_screen_content_tools) {
9525 if (above_mi)
9526 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9527 if (left_mi)
9528 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9529 }
Urvang Joshib100db72016-10-12 16:28:56 -07009530#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009531
9532#if CONFIG_EXT_INTRA
9533 memset(directional_mode_skip_mask, 0,
9534 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
9535#endif // CONFIG_EXT_INTRA
9536
9537 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9538 &comp_mode_p);
9539
9540 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009541 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009542 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9543 for (i = 0; i < MB_MODE_COUNT; ++i) {
9544 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
9545 single_inter_filter[i][k] = SWITCHABLE;
9546 single_skippable[i][k] = 0;
9547 }
9548 }
9549
9550 rd_cost->rate = INT_MAX;
9551#if CONFIG_SUPERTX
9552 *returnrate_nocoef = INT_MAX;
9553#endif // CONFIG_SUPERTX
9554
9555 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9556 x->pred_mv_sad[ref_frame] = INT_MAX;
9557 x->mbmi_ext->mode_context[ref_frame] = 0;
9558#if CONFIG_REF_MV && CONFIG_EXT_INTER
9559 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9560#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9561 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9562 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9563 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9564 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9565 }
9566 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009567#if CONFIG_GLOBAL_MOTION
9568 frame_mv[ZEROMV][ref_frame].as_int =
David Barker45390c12017-02-20 14:44:40 +00009569 gm_get_motion_vector(
9570 &cm->global_motion[ref_frame], cm->allow_high_precision_mv,
9571 mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +00009572 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009573#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009574 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009575#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009576#if CONFIG_EXT_INTER
9577 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9578 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009579#if CONFIG_GLOBAL_MOTION
9580 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
David Barker45390c12017-02-20 14:44:40 +00009581 gm_get_motion_vector(
9582 &cm->global_motion[ref_frame], cm->allow_high_precision_mv,
9583 mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009584 .as_int;
9585#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009586 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009587#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009588#endif // CONFIG_EXT_INTER
9589 }
9590
9591#if CONFIG_REF_MV
9592 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9593 MODE_INFO *const mi = xd->mi[0];
9594 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9595 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009596 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9597 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009598#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009599 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009600#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009601 candidates, mi_row, mi_col, NULL, NULL,
9602 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009603 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9604 MV_REFERENCE_FRAME rf[2];
9605 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009606 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9607 frame_mv[ZEROMV][rf[0]].as_int ||
9608 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9609 frame_mv[ZEROMV][rf[0]].as_int ||
9610 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9611 frame_mv[ZEROMV][rf[1]].as_int ||
9612 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009613 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9614 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009615 }
9616#endif // CONFIG_REF_MV
9617
Yue Chencb60b182016-10-13 15:18:22 -07009618#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009619 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
9620 dst_width1, dst_height1, dst_stride1);
9621 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
9622 dst_width2, dst_height2, dst_stride2);
9623 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yue Chene9638cc2016-10-10 12:37:54 -07009624 x->mask_buf = mask2d_buf;
9625 x->wsrc_buf = weighted_src_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009626 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, dst_buf1[0],
Yue Chene9638cc2016-10-10 12:37:54 -07009627 dst_stride1[0], dst_buf2[0], dst_stride2[0]);
Yue Chencb60b182016-10-13 15:18:22 -07009628#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009629
9630 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9631 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9632// Skip checking missing references in both single and compound reference
9633// modes. Note that a mode will be skipped iff both reference frames
9634// are masked out.
9635#if CONFIG_EXT_REFS
9636 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9637 ref_frame_skip_mask[0] |= (1 << ref_frame);
9638 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9639 } else {
9640#endif // CONFIG_EXT_REFS
9641 ref_frame_skip_mask[0] |= (1 << ref_frame);
9642 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9643#if CONFIG_EXT_REFS
9644 }
9645#endif // CONFIG_EXT_REFS
9646 } else {
9647 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9648 // Skip fixed mv modes for poor references
9649 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9650 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9651 break;
9652 }
9653 }
9654 }
9655 // If the segment reference frame feature is enabled....
9656 // then do nothing if the current ref frame is not allowed..
9657 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9658 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9659 ref_frame_skip_mask[0] |= (1 << ref_frame);
9660 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9661 }
9662 }
9663
9664 // Disable this drop out case if the ref frame
9665 // segment level feature is enabled for this segment. This is to
9666 // prevent the possibility that we end up unable to pick any mode.
9667 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9668 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9669 // unless ARNR filtering is enabled in which case we want
9670 // an unfiltered alternative. We allow near/nearest as well
9671 // because they may result in zero-zero MVs but be cheaper.
9672 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009673 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009674 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9675#if CONFIG_EXT_REFS
9676 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9677 (1 << BWDREF_FRAME) |
9678#endif // CONFIG_EXT_REFS
9679 (1 << GOLDEN_FRAME);
9680 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9681 // TODO(zoeliu): To further explore whether following needs to be done for
9682 // BWDREF_FRAME as well.
9683 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009684#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009685 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
David Barker45390c12017-02-20 14:44:40 +00009686 cm->allow_high_precision_mv,
9687 mi_col * MI_SIZE + MI_SIZE / 2,
9688 mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +00009689 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009690#else
9691 zeromv.as_int = 0;
9692#endif // CONFIG_GLOBAL_MOTION
9693 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009694 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009695 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009696 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9697#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009698 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009699 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009700 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009702 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009703 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009704 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009705 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9706#endif // CONFIG_EXT_INTER
9707 }
9708 }
9709
9710 if (cpi->rc.is_src_frame_alt_ref) {
9711 if (sf->alt_ref_search_fp) {
9712 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9713 mode_skip_mask[ALTREF_FRAME] = 0;
9714 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9715 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9716 }
9717 }
9718
9719 if (sf->alt_ref_search_fp)
9720 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9721 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9722 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9723
9724 if (sf->adaptive_mode_search) {
9725 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9726 cpi->rc.frames_since_golden >= 3)
9727 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
9728 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9729 }
9730
9731 if (bsize > sf->max_intra_bsize) {
9732 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9733 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9734 }
9735
9736 mode_skip_mask[INTRA_FRAME] |=
9737 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9738
9739 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9740 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9741 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9742
9743 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9744 while (midx > 4) {
9745 uint8_t end_pos = 0;
9746 for (i = 5; i < midx; ++i) {
9747 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9748 uint8_t tmp = mode_map[i];
9749 mode_map[i] = mode_map[i - 1];
9750 mode_map[i - 1] = tmp;
9751 end_pos = i;
9752 }
9753 }
9754 midx = end_pos;
9755 }
9756
9757 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9758 x->use_default_intra_tx_type = 1;
9759 else
9760 x->use_default_intra_tx_type = 0;
9761
9762 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9763 x->use_default_inter_tx_type = 1;
9764 else
9765 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009766#if CONFIG_PVQ
9767 od_encode_checkpoint(&x->daala_enc, &pre_buf);
9768#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009769#if CONFIG_EXT_INTER
9770 for (i = 0; i < MB_MODE_COUNT; ++i)
9771 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9772 modelled_rd[i][ref_frame] = INT64_MAX;
9773#endif // CONFIG_EXT_INTER
9774
9775 for (midx = 0; midx < MAX_MODES; ++midx) {
9776 int mode_index;
9777 int mode_excluded = 0;
9778 int64_t this_rd = INT64_MAX;
9779 int disable_skip = 0;
9780 int compmode_cost = 0;
9781#if CONFIG_EXT_INTER
9782 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009783 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009784#endif // CONFIG_EXT_INTER
9785 int rate2 = 0, rate_y = 0, rate_uv = 0;
9786 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9787 int skippable = 0;
9788 int this_skip2 = 0;
9789 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009790#if CONFIG_REF_MV
9791 uint8_t ref_frame_type;
9792#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07009793#if CONFIG_PVQ
9794 od_encode_rollback(&x->daala_enc, &pre_buf);
9795#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009796 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009797 this_mode = av1_mode_order[mode_index].mode;
9798 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9799 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009800#if CONFIG_REF_MV
9801 mbmi->ref_mv_idx = 0;
9802#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009803
9804#if CONFIG_EXT_INTER
9805 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9806 // Mode must by compatible
9807 assert(is_interintra_allowed_mode(this_mode));
9808
David Barkerac37fa32016-12-02 12:30:21 +00009809#if !USE_RECT_INTERINTRA
David Barker561eb722017-01-19 11:19:24 +00009810 // Note: If the subsampling is unequal, any block size we pick will
9811 // result in either a rectangular luma block or a rectangular chroma
9812 // block. So in this case, we can't use any interintra modes.
David Barkerac37fa32016-12-02 12:30:21 +00009813 if (xd->plane[1].subsampling_x != xd->plane[1].subsampling_y ||
9814 xd->plane[2].subsampling_x != xd->plane[2].subsampling_y)
9815 continue;
9816#endif
9817
Yaowu Xuc27fc142016-08-22 16:08:15 -07009818 if (!is_interintra_allowed_bsize(bsize)) continue;
9819 }
9820
9821 if (is_inter_compound_mode(this_mode)) {
9822 frame_mv[this_mode][ref_frame].as_int =
9823 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9824 frame_mv[this_mode][second_ref_frame].as_int =
9825 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
9826 }
9827#endif // CONFIG_EXT_INTER
9828
9829 // Look at the reference frame of the best mode so far and set the
9830 // skip mask to look at a subset of the remaining modes.
9831 if (midx == mode_skip_start && best_mode_index >= 0) {
9832 switch (best_mbmode.ref_frame[0]) {
9833 case INTRA_FRAME: break;
9834 case LAST_FRAME:
9835 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9836 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9837 break;
9838#if CONFIG_EXT_REFS
9839 case LAST2_FRAME:
9840 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9841 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9842 break;
9843 case LAST3_FRAME:
9844 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9845 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9846 break;
9847#endif // CONFIG_EXT_REFS
9848 case GOLDEN_FRAME:
9849 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9850 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9851 break;
9852#if CONFIG_EXT_REFS
9853 case BWDREF_FRAME:
9854 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9855 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9856 break;
9857#endif // CONFIG_EXT_REFS
9858 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9859#if CONFIG_EXT_REFS
9860 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9861#endif // CONFIG_EXT_REFS
9862 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009863 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009864 case TOTAL_REFS_PER_FRAME:
9865 assert(0 && "Invalid Reference frame");
9866 break;
9867 }
9868 }
9869
9870 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009871 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009872 continue;
9873
9874 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
9875
9876 // Test best rd so far against threshold for trying this mode.
9877 if (best_mode_skippable && sf->schedule_mode_search)
9878 mode_threshold[mode_index] <<= 1;
9879
9880 if (best_rd < mode_threshold[mode_index]) continue;
9881
9882 comp_pred = second_ref_frame > INTRA_FRAME;
9883 if (comp_pred) {
9884 if (!cpi->allow_comp_inter_inter) continue;
9885
9886 // Skip compound inter modes if ARF is not available.
9887 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
9888
9889 // Do not allow compound prediction if the segment level reference frame
9890 // feature is in use as in this case there can only be one reference.
9891 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
9892
9893 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
9894 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
9895 continue;
9896
9897 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
9898 } else {
9899 if (ref_frame != INTRA_FRAME)
9900 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
9901 }
9902
9903 if (ref_frame == INTRA_FRAME) {
9904 if (sf->adaptive_mode_search)
9905 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
9906 continue;
9907
9908 if (this_mode != DC_PRED) {
9909 // Disable intra modes other than DC_PRED for blocks with low variance
9910 // Threshold for intra skipping based on source variance
9911 // TODO(debargha): Specialize the threshold for super block sizes
9912 const unsigned int skip_intra_var_thresh = 64;
9913 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
9914 x->source_variance < skip_intra_var_thresh)
9915 continue;
9916 // Only search the oblique modes if the best so far is
9917 // one of the neighboring directional modes
9918 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
9919 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
9920 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
9921 continue;
9922 }
9923 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
9924 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
9925 }
9926 }
Sarah Parkere5299862016-08-16 14:57:37 -07009927#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00009928 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07009929 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00009930 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009931#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009932 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07009933#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009934 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
9935 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
9936#if CONFIG_REF_MV && CONFIG_EXT_INTER
9937 mbmi_ext->compound_mode_context,
9938#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00009939 frame_mv, this_mode, ref_frames, bsize, -1,
9940 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009941 continue;
9942 }
9943
9944 mbmi->mode = this_mode;
9945 mbmi->uv_mode = DC_PRED;
9946 mbmi->ref_frame[0] = ref_frame;
9947 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07009948#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009949 pmi->palette_size[0] = 0;
9950 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009951#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009952#if CONFIG_FILTER_INTRA
9953 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9954 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9955#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009956 // Evaluate all sub-pel filters irrespective of whether we can use
9957 // them for this frame.
9958#if CONFIG_DUAL_FILTER
9959 for (i = 0; i < 4; ++i) {
9960 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
9961 ? EIGHTTAP_REGULAR
9962 : cm->interp_filter;
9963 }
9964#else
9965 mbmi->interp_filter =
9966 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
9967#endif
9968 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009969 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009970
9971 x->skip = 0;
9972 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9973
9974 // Select prediction reference frames.
9975 for (i = 0; i < MAX_MB_PLANE; i++) {
9976 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9977 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9978 }
9979
9980#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009981 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009982#endif // CONFIG_EXT_INTER
9983
9984 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009985 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009986 TX_SIZE uv_tx;
9987 struct macroblockd_plane *const pd = &xd->plane[1];
9988#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009989 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009990 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08009991 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -08009992 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009993 if (!angle_stats_ready) {
9994 const int src_stride = x->plane[0].src.stride;
9995 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07009996#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009997 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
9998 highbd_angle_estimation(src, src_stride, rows, cols,
9999 directional_mode_skip_mask);
10000 else
10001#endif
10002 angle_estimation(src, src_stride, rows, cols,
10003 directional_mode_skip_mask);
10004 angle_stats_ready = 1;
10005 }
10006 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010007 rd_stats_y.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -080010008 this_rd = rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y,
10009 bsize, intra_mode_cost[mbmi->mode],
10010 best_rd, &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010011 } else {
10012 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010013 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010014 }
10015#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010016 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010017#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010018 rate_y = rd_stats_y.rate;
10019 distortion_y = rd_stats_y.dist;
10020 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010021
10022 if (rate_y == INT_MAX) continue;
10023
hui su5db97432016-10-14 16:10:14 -070010024#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010025 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010026#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010027
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010028 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10029 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010030 if (rate_uv_intra[uv_tx] == INT_MAX) {
10031 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010032 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10033 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010034#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010035 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010036#endif // CONFIG_PALETTE
10037
Yaowu Xuc27fc142016-08-22 16:08:15 -070010038#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010039 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10040#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010041#if CONFIG_FILTER_INTRA
10042 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10043#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010044 }
10045
10046 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010047 distortion_uv = dist_uvs[uv_tx];
10048 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010049 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010050#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010051 if (cm->allow_screen_content_tools) {
10052 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10053 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10054 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10055 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10056 }
Urvang Joshib100db72016-10-12 16:28:56 -070010057#endif // CONFIG_PALETTE
10058
Yaowu Xuc27fc142016-08-22 16:08:15 -070010059#if CONFIG_EXT_INTRA
10060 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010061#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010062#if CONFIG_FILTER_INTRA
10063 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10064 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10065 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10066 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10067 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10068 }
10069#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010070
Jingning Han36fe3202017-02-20 22:31:49 -080010071#if CONFIG_CB4X4
10072 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10073 if (!x->skip_chroma_rd)
10074 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10075#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010076 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10077 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Jingning Han36fe3202017-02-20 22:31:49 -080010078#endif
10079
Urvang Joshib100db72016-10-12 16:28:56 -070010080#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010081 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -070010082 rate2 += av1_cost_bit(
10083 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -070010084#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010085
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010086 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010087 // super_block_yrd above includes the cost of the tx_size in the
10088 // tokenonly rate, but for intra blocks, tx_size is always coded
10089 // (prediction granularity), so we account for it in the full rate,
10090 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010091 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010092 }
10093#if CONFIG_EXT_INTRA
10094 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010095 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -080010096#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010097 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -070010098 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -080010099 p_angle = mode_to_angle_map[mbmi->mode] +
10100 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -070010101 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010102 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010103#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -080010104 rate2 += write_uniform_cost(2 * max_angle_delta + 1,
10105 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010106 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010107 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su45dc5972016-12-08 17:42:50 -080010108 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
10109 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010110 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010111#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010112#if CONFIG_FILTER_INTRA
10113 if (mbmi->mode == DC_PRED) {
10114 rate2 +=
10115 av1_cost_bit(cm->fc->filter_intra_probs[0],
10116 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10117 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10118 rate2 += write_uniform_cost(
10119 FILTER_INTRA_MODES,
10120 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10121 }
10122 }
10123 if (mbmi->uv_mode == DC_PRED) {
10124 rate2 +=
10125 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10126 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10127 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10128 rate2 += write_uniform_cost(
10129 FILTER_INTRA_MODES,
10130 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10131 }
10132#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010133 if (this_mode != DC_PRED && this_mode != TM_PRED)
10134 rate2 += intra_cost_penalty;
10135 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010136 } else {
10137#if CONFIG_REF_MV
10138 int_mv backup_ref_mv[2];
10139
10140 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10141 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
10142#endif
10143#if CONFIG_EXT_INTER
10144 if (second_ref_frame == INTRA_FRAME) {
10145 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010146 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010147// TODO(debargha|geza.lore):
10148// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010149#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010150 mbmi->angle_delta[0] = 0;
10151 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010152#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010153 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010154#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010155#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010156#if CONFIG_FILTER_INTRA
10157 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10158 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10159#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010160 }
10161#endif // CONFIG_EXT_INTER
10162#if CONFIG_REF_MV
10163 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010164 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165
10166 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
10167 int ref;
10168 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10169 int_mv this_mv =
10170 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10171 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010172 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10173 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010174 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10175 }
10176 }
10177#endif
Angie Chiang76159122016-11-09 12:13:22 -080010178 {
10179 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10180 av1_init_rd_stats(&rd_stats);
10181 rd_stats.rate = rate2;
10182 this_rd = handle_inter_mode(
10183 cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &disable_skip,
10184 frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -070010185#if CONFIG_MOTION_VAR
Angie Chiang76159122016-11-09 12:13:22 -080010186 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -070010187#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -070010188#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010189 single_newmvs, single_newmvs_rate, &compmode_interintra_cost,
Sarah Parker6fdc8532016-11-16 17:47:13 -080010190 &compmode_interinter_cost, modelled_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010191#else
Angie Chiang76159122016-11-09 12:13:22 -080010192 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010193#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010194 single_inter_filter, single_skippable, best_rd);
10195
10196 rate2 = rd_stats.rate;
10197 skippable = rd_stats.skip;
10198 distortion2 = rd_stats.dist;
10199 total_sse = rd_stats.sse;
10200 rate_y = rd_stats_y.rate;
10201 rate_uv = rd_stats_uv.rate;
10202 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010203
10204#if CONFIG_REF_MV
Yue Chen6e601e92016-12-05 18:19:00 -080010205// TODO(jingning): This needs some refactoring to improve code quality
10206// and reduce redundant steps.
10207#if CONFIG_EXT_INTER
10208 if (((mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) &&
10209 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10210 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10211 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10212#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010213 if ((mbmi->mode == NEARMV &&
10214 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10215 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Yue Chen6e601e92016-12-05 18:19:00 -080010216#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010217 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10218 MB_MODE_INFO backup_mbmi = *mbmi;
10219 int backup_skip = x->skip;
10220 int64_t tmp_ref_rd = this_rd;
10221 int ref_idx;
10222
Yue Chen6e601e92016-12-05 18:19:00 -080010223// TODO(jingning): This should be deprecated shortly.
10224#if CONFIG_EXT_INTER
10225 int idx_offset =
10226 (mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) ? 1 : 0;
10227#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010228 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010229#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010230 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010231 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010232
10233 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010234 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010235 // Dummy
10236 int_mv backup_fmv[2];
10237 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10238 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10239
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010240 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010241
10242 if (this_rd < INT64_MAX) {
10243 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10244 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10245 tmp_ref_rd =
10246 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010247 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010248 distortion2);
10249 else
10250 tmp_ref_rd =
10251 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010252 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010253 rate_y - rate_uv,
10254 total_sse);
10255 }
10256#if CONFIG_VAR_TX
10257 for (i = 0; i < MAX_MB_PLANE; ++i)
10258 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10259 sizeof(uint8_t) * ctx->num_4x4_blk);
10260#endif
10261
10262 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10263 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010264 int dummy_disable_skip = 0;
10265 int ref;
10266 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010267 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010268#if CONFIG_EXT_INTER
10269 int tmp_compmode_interintra_cost = 0;
10270 int tmp_compmode_interinter_cost = 0;
10271#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010272
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010273 av1_invalid_rd_stats(&tmp_rd_stats);
10274
Yaowu Xuc27fc142016-08-22 16:08:15 -070010275 mbmi->ref_mv_idx = 1 + ref_idx;
10276
10277 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10278 int_mv this_mv =
10279 (ref == 0)
10280 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10281 .this_mv
10282 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10283 .comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010284 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10285 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010286 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10287 }
10288
10289 cur_mv =
10290 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10291 .this_mv;
10292 clamp_mv2(&cur_mv.as_mv, xd);
10293
10294 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
clang-format55ce9e02017-02-15 22:27:12 -080010295 int dummy_single_skippable[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME] = {
10296 { 0 }
10297 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010298#if CONFIG_EXT_INTER
10299 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
10300 { { 0 } } };
10301 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
10302 { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010303#else
10304 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
10305#endif
10306
10307 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010308 av1_init_rd_stats(&tmp_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010309 tmp_alt_rd = handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -080010310 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10311 &dummy_disable_skip, frame_mv, mi_row, mi_col,
Yue Chencb60b182016-10-13 15:18:22 -070010312#if CONFIG_MOTION_VAR
Yue Chene9638cc2016-10-10 12:37:54 -070010313 dst_buf1, dst_stride1, dst_buf2, dst_stride2,
Yue Chencb60b182016-10-13 15:18:22 -070010314#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -070010315#if CONFIG_EXT_INTER
10316 dummy_single_newmvs, dummy_single_newmvs_rate,
Yue Chen6e601e92016-12-05 18:19:00 -080010317 &tmp_compmode_interintra_cost, &tmp_compmode_interinter_cost,
10318 NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010319#else
10320 dummy_single_newmv,
10321#endif
Angie Chiang76159122016-11-09 12:13:22 -080010322 single_inter_filter, dummy_single_skippable, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010323 }
10324
10325 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10326 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010327 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10328 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010329 tmp_rd_stats.rate +=
10330 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10331 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010332 }
10333
10334 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10335 mbmi->ref_mv_idx + idx_offset + 1 &&
10336 ref_idx < ref_set - 1) {
10337 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010338 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10339 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010340 tmp_rd_stats.rate +=
10341 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10342 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010343 }
10344
10345 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010346#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010347 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10348 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010349#else
Angie Chiang76159122016-11-09 12:13:22 -080010350 if (RDCOST(x->rdmult, x->rddiv,
10351 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10352 tmp_rd_stats.dist) <
10353 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010354 tmp_alt_rd =
10355 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010356 tmp_rd_stats.rate +
10357 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10358 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010359 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010360 tmp_alt_rd =
10361 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010362 tmp_rd_stats.rate +
10363 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10364 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10365 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010366#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010367 }
10368
10369 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010370 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010371 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010372 distortion2 = tmp_rd_stats.dist;
10373 skippable = tmp_rd_stats.skip;
10374 rate_y = tmp_rd_stats_y.rate;
10375 rate_uv = tmp_rd_stats_uv.rate;
10376 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010377 this_rd = tmp_alt_rd;
10378 tmp_ref_rd = tmp_alt_rd;
10379 backup_mbmi = *mbmi;
10380 backup_skip = x->skip;
10381#if CONFIG_VAR_TX
10382 for (i = 0; i < MAX_MB_PLANE; ++i)
10383 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10384 sizeof(uint8_t) * ctx->num_4x4_blk);
10385#endif
Yue Chen6e601e92016-12-05 18:19:00 -080010386#if CONFIG_EXT_INTER
10387 compmode_interintra_cost = tmp_compmode_interintra_cost;
10388 compmode_interinter_cost = tmp_compmode_interinter_cost;
10389#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010390 } else {
10391 *mbmi = backup_mbmi;
10392 x->skip = backup_skip;
10393 }
10394 }
10395
10396 frame_mv[NEARMV][ref_frame] = backup_mv;
10397 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10398 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10399#if CONFIG_VAR_TX
10400 for (i = 0; i < MAX_MB_PLANE; ++i)
10401 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10402 sizeof(uint8_t) * ctx->num_4x4_blk);
10403#endif
10404 }
10405 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10406 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
10407#endif // CONFIG_REF_MV
10408
10409 if (this_rd == INT64_MAX) continue;
10410
Yaowu Xuf883b422016-08-30 14:01:10 -070010411 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010412
10413 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10414 }
10415
10416#if CONFIG_EXT_INTER
10417 rate2 += compmode_interintra_cost;
10418 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010419#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10420 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10421#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010422 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010423#endif // CONFIG_EXT_INTER
10424
10425 // Estimate the reference frame signaling cost and add it
10426 // to the rolling cost variable.
10427 if (comp_pred) {
10428 rate2 += ref_costs_comp[ref_frame];
10429#if CONFIG_EXT_REFS
10430 rate2 += ref_costs_comp[second_ref_frame];
10431#endif // CONFIG_EXT_REFS
10432 } else {
10433 rate2 += ref_costs_single[ref_frame];
10434 }
10435
Yue Chen69f18e12016-09-08 14:48:15 -070010436#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010437 if (ref_frame == INTRA_FRAME) {
10438#else
10439 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010440#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010441 if (skippable) {
10442 // Back out the coefficient coding costs
10443 rate2 -= (rate_y + rate_uv);
10444 rate_y = 0;
10445 rate_uv = 0;
10446 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010447 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010448 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010449#if CONFIG_REF_MV
10450 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10451 distortion2) <
10452 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
10453#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010454 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10455 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010456#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010457 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010458 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010459 } else {
10460 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010461 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010462 distortion2 = total_sse;
10463 assert(total_sse >= 0);
10464 rate2 -= (rate_y + rate_uv);
10465 this_skip2 = 1;
10466 rate_y = 0;
10467 rate_uv = 0;
10468 }
10469 } else {
10470 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010471 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010472 }
10473
10474 // Calculate the final RD estimate for this mode.
10475 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010476#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010477 } else {
10478 this_skip2 = mbmi->skip;
10479 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10480 if (this_skip2) {
10481 rate_y = 0;
10482 rate_uv = 0;
10483 }
Yue Chen69f18e12016-09-08 14:48:15 -070010484#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010485 }
10486
Yaowu Xuc27fc142016-08-22 16:08:15 -070010487 if (ref_frame == INTRA_FRAME) {
10488 // Keep record of best intra rd
10489 if (this_rd < best_intra_rd) {
10490 best_intra_rd = this_rd;
10491 best_intra_mode = mbmi->mode;
10492 }
10493#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -050010494 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010495 if (this_rd < best_single_inter_rd) {
10496 best_single_inter_rd = this_rd;
10497 best_single_inter_ref = mbmi->ref_frame[0];
10498 }
10499#endif // CONFIG_EXT_INTER
10500 }
10501
10502 if (!disable_skip && ref_frame == INTRA_FRAME) {
10503 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010504 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010505 }
10506
10507 // Did this mode help.. i.e. is it the new best mode
10508 if (this_rd < best_rd || x->skip) {
10509 if (!mode_excluded) {
10510 // Note index of best mode so far
10511 best_mode_index = mode_index;
10512
10513 if (ref_frame == INTRA_FRAME) {
10514 /* required for left and above block mv */
10515 mbmi->mv[0].as_int = 0;
10516 } else {
10517 best_pred_sse = x->pred_sse[ref_frame];
10518 }
10519
10520 rd_cost->rate = rate2;
10521#if CONFIG_SUPERTX
10522 if (x->skip)
10523 *returnrate_nocoef = rate2;
10524 else
10525 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010526 *returnrate_nocoef -= av1_cost_bit(
10527 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10528 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10529 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010530#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -070010531#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10532 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
10533#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010534 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010535#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10536 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
10537 *returnrate_nocoef -=
10538 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
10539#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010540#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010541#endif // CONFIG_SUPERTX
10542 rd_cost->dist = distortion2;
10543 rd_cost->rdcost = this_rd;
10544 best_rd = this_rd;
10545 best_mbmode = *mbmi;
10546 best_skip2 = this_skip2;
10547 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010548 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10549 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010550 best_rate_uv = rate_uv;
10551
10552#if CONFIG_VAR_TX
10553 for (i = 0; i < MAX_MB_PLANE; ++i)
10554 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10555 sizeof(uint8_t) * ctx->num_4x4_blk);
10556#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010557 }
10558 }
10559
10560 /* keep record of best compound/single-only prediction */
10561 if (!disable_skip && ref_frame != INTRA_FRAME) {
10562 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10563
10564 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10565 single_rate = rate2 - compmode_cost;
10566 hybrid_rate = rate2;
10567 } else {
10568 single_rate = rate2;
10569 hybrid_rate = rate2 + compmode_cost;
10570 }
10571
10572 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10573 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10574
10575 if (!comp_pred) {
10576 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10577 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10578 } else {
10579 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10580 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10581 }
10582 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10583 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10584 }
10585
Yaowu Xuc27fc142016-08-22 16:08:15 -070010586 if (x->skip && !comp_pred) break;
10587 }
10588
10589 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10590 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10591 is_inter_mode(best_mbmode.mode)) ||
10592 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10593 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010594 int skip_blk = 0;
10595 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010596
10597 x->use_default_inter_tx_type = 0;
10598 x->use_default_intra_tx_type = 0;
10599
10600 *mbmi = best_mbmode;
10601
10602 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10603
10604 // Select prediction reference frames.
10605 for (i = 0; i < MAX_MB_PLANE; i++) {
10606 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10607 if (has_second_ref(mbmi))
10608 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10609 }
10610
10611 if (is_inter_mode(mbmi->mode)) {
Yue Chen69f18e12016-09-08 14:48:15 -070010612#if CONFIG_WARPED_MOTION
10613 if (mbmi->motion_mode == WARPED_CAUSAL) {
10614 int plane;
10615#if CONFIG_AOM_HIGHBITDEPTH
10616 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
10617#endif // CONFIG_AOM_HIGHBITDEPTH
10618 assert(!has_second_ref(mbmi));
10619
10620 for (plane = 0; plane < 3; ++plane) {
10621 const struct macroblockd_plane *pd = &xd->plane[plane];
10622
10623 av1_warp_plane(&mbmi->wm_params[0],
10624#if CONFIG_AOM_HIGHBITDEPTH
10625 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
10626#endif // CONFIG_AOM_HIGHBITDEPTH
10627 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
10628 pd->pre[0].stride, pd->dst.buf,
10629 ((mi_col * MI_SIZE) >> pd->subsampling_x),
10630 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010631 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
10632 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
10633 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
10634 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -070010635 }
10636 } else {
10637#endif // CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +000010638 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Yue Chen69f18e12016-09-08 14:48:15 -070010639#if CONFIG_WARPED_MOTION
10640 }
10641#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010642#if CONFIG_MOTION_VAR
10643 if (mbmi->motion_mode == OBMC_CAUSAL)
Yaowu Xuf883b422016-08-30 14:01:10 -070010644 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1,
10645 dst_stride1, dst_buf2, dst_stride2);
Yue Chencb60b182016-10-13 15:18:22 -070010646#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010647 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010648#if CONFIG_VAR_TX
10649 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010650 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010651 } else {
10652 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010653 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010654 for (idy = 0; idy < xd->n8_h; ++idy)
10655 for (idx = 0; idx < xd->n8_w; ++idx)
10656 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010657 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010658 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10659 }
10660
Angie Chiangb5dda482016-11-02 16:19:58 -070010661 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010662#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010663 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010664 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010665#endif // CONFIG_VAR_TX
10666 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010667 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010668 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010669 }
10670
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010671 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10672 (rd_stats_y.dist + rd_stats_uv.dist)) >
10673 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010675 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10676 rd_stats_uv.rate = 0;
10677 rd_stats_y.dist = rd_stats_y.sse;
10678 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010679 } else {
10680 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010681 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010682 }
10683
10684 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010685 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10686 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010687#if CONFIG_VAR_TX
10688 int idx, idy;
10689#endif
10690 best_mbmode.tx_type = mbmi->tx_type;
10691 best_mbmode.tx_size = mbmi->tx_size;
10692#if CONFIG_VAR_TX
10693 for (idy = 0; idy < xd->n8_h; ++idy)
10694 for (idx = 0; idx < xd->n8_w; ++idx)
10695 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
10696
10697 for (i = 0; i < MAX_MB_PLANE; ++i)
10698 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10699 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070010700
10701 best_mbmode.min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010702#endif
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010703 rd_cost->rate +=
10704 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
10705 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010706 rd_cost->rdcost =
10707 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
10708 best_skip2 = skip_blk;
10709 }
10710 }
10711
Urvang Joshib100db72016-10-12 16:28:56 -070010712#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010713 // Only try palette mode when the best mode so far is an intra mode.
10714 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010715 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010716#if CONFIG_SUPERTX
10717 int best_rate_nocoef;
10718#endif
Urvang Joshi451e0f22017-01-31 11:18:31 -080010719 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10720 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010721 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010722 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010723 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010724 uint8_t *const best_palette_color_map =
10725 x->palette_buffer->best_palette_color_map;
10726 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010727 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010728
10729 mbmi->mode = DC_PRED;
10730 mbmi->uv_mode = DC_PRED;
10731 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010732 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010733 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010734 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10735 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10736 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010737 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10738 memcpy(color_map, best_palette_color_map,
10739 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010740 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10741 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010742 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10743 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010744 if (rate_uv_intra[uv_tx] == INT_MAX) {
10745 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010746 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10747 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010748 pmi_uv[uv_tx] = *pmi;
10749#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010750 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10751#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010752#if CONFIG_FILTER_INTRA
10753 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10754#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010755 }
10756 mbmi->uv_mode = mode_uv[uv_tx];
10757 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080010758 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010759 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10760 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10761 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080010762 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010763#if CONFIG_EXT_INTRA
10764 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010765#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010766#if CONFIG_FILTER_INTRA
10767 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10768 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10769 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10770 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10771 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10772 }
10773#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010774 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
10775 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
10776 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010777 rate2 += ref_costs_single[INTRA_FRAME];
10778
10779 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010780 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010781#if CONFIG_SUPERTX
10782 best_rate_nocoef = rate2;
10783#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010784 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010785 } else {
10786#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010787 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010788#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070010789 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010790 }
10791 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10792 if (this_rd < best_rd) {
10793 best_mode_index = 3;
10794 mbmi->mv[0].as_int = 0;
10795 rd_cost->rate = rate2;
10796#if CONFIG_SUPERTX
10797 *returnrate_nocoef = best_rate_nocoef;
10798#endif
10799 rd_cost->dist = distortion2;
10800 rd_cost->rdcost = this_rd;
10801 best_rd = this_rd;
10802 best_mbmode = *mbmi;
10803 best_skip2 = 0;
10804 best_mode_skippable = skippable;
10805 }
10806 }
10807PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070010808#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010809
hui su5db97432016-10-14 16:10:14 -070010810#if CONFIG_FILTER_INTRA
10811 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070010812 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070010813 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070010814#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080010815 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070010816#endif // CONFIG_PALETTE
10817 !dc_skipped && best_mode_index >= 0 &&
10818 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070010819 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080010820 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
10821 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070010822#if CONFIG_EXT_INTRA
10823 uv_angle_delta,
10824#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070010825#if CONFIG_PALETTE
10826 pmi_uv, palette_ctx,
10827#endif // CONFIG_PALETTE
10828 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010829 &best_mode_index, &best_skip2, &best_mode_skippable,
10830#if CONFIG_SUPERTX
10831 returnrate_nocoef,
10832#endif // CONFIG_SUPERTX
10833 best_pred_rd, &best_mbmode, rd_cost);
10834 }
hui su5db97432016-10-14 16:10:14 -070010835#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010836
10837 // The inter modes' rate costs are not calculated precisely in some cases.
10838 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
10839 // ZEROMV. Here, checks are added for those cases, and the mode decisions
10840 // are corrected.
10841 if (best_mbmode.mode == NEWMV
10842#if CONFIG_EXT_INTER
10843 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
10844#endif // CONFIG_EXT_INTER
10845 ) {
10846 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10847 best_mbmode.ref_frame[1] };
10848 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070010849 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010850#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -070010851 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070010852#endif // CONFIG_REF_MV
10853#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000010854 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000010855 cm->allow_high_precision_mv,
10856 mi_col * MI_SIZE + MI_SIZE / 2,
10857 mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +000010858 .as_int;
David Barker45390c12017-02-20 14:44:40 +000010859 zeromv[1].as_int =
10860 comp_pred_mode
10861 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
10862 cm->allow_high_precision_mv,
10863 mi_col * MI_SIZE + MI_SIZE / 2,
10864 mi_row * MI_SIZE + MI_SIZE / 2)
10865 .as_int
10866 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010867#else
10868 zeromv[0].as_int = 0;
10869 zeromv[1].as_int = 0;
10870#endif // CONFIG_GLOBAL_MOTION
10871#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010872 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010873 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010874 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010875 : INT_MAX;
10876
10877 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10878 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10879 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
10880 best_mbmode.mode = NEARMV;
10881 best_mbmode.ref_mv_idx = i;
10882 }
10883 }
10884
10885 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
10886 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010887 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010888 best_mbmode.mode = ZEROMV;
10889 } else {
10890 int_mv nearestmv[2];
10891 int_mv nearmv[2];
10892
10893#if CONFIG_EXT_INTER
10894 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
10895 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
10896 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
10897 } else {
10898 nearmv[0] = frame_mv[NEARMV][refs[0]];
10899 nearmv[1] = frame_mv[NEARMV][refs[1]];
10900 }
10901#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010902 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010903 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010904 : INT_MAX;
10905
10906 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10907 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10908 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
10909
10910 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10911 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
10912 best_mbmode.mode = NEARMV;
10913 best_mbmode.ref_mv_idx = i;
10914 }
10915 }
10916#endif
10917 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
10918 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
10919 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
10920 } else {
10921 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
10922 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
10923 }
10924
10925 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
10926 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
10927#if CONFIG_EXT_INTER
10928 best_mbmode.mode = NEAREST_NEARESTMV;
10929 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
10930 nearmv[1].as_int == best_mbmode.mv[1].as_int)
10931 best_mbmode.mode = NEAREST_NEARMV;
10932 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10933 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
10934 best_mbmode.mode = NEAR_NEARESTMV;
10935 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10936 nearmv[1].as_int == best_mbmode.mv[1].as_int)
10937 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080010938 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10939 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010940 best_mbmode.mode = ZERO_ZEROMV;
10941#else
10942 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010943 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10944 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010945 best_mbmode.mode = ZEROMV;
10946#endif // CONFIG_EXT_INTER
10947 }
10948#else
10949#if CONFIG_EXT_INTER
10950 if (!comp_pred_mode) {
10951#endif // CONFIG_EXT_INTER
10952 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10953 ((comp_pred_mode &&
10954 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
10955 !comp_pred_mode))
10956 best_mbmode.mode = NEARESTMV;
10957 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
10958 ((comp_pred_mode &&
10959 frame_mv[NEARMV][refs[1]].as_int ==
10960 best_mbmode.mv[1].as_int) ||
10961 !comp_pred_mode))
10962 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010963 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10964 ((comp_pred_mode &&
10965 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -070010966 !comp_pred_mode))
10967 best_mbmode.mode = ZEROMV;
10968#if CONFIG_EXT_INTER
10969 } else {
Sarah Parkerc2d38712017-01-24 15:15:41 -080010970 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10971 best_mbmode.ref_frame[1] };
10972 int_mv zeromv[2];
10973#if CONFIG_GLOBAL_MOTION
10974 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000010975 cm->allow_high_precision_mv,
10976 mi_col * MI_SIZE + MI_SIZE / 2,
10977 mi_row * MI_SIZE + MI_SIZE / 2)
Sarah Parkerc2d38712017-01-24 15:15:41 -080010978 .as_int;
David Barker45390c12017-02-20 14:44:40 +000010979 zeromv[1].as_int =
10980 comp_pred_mode
10981 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
10982 cm->allow_high_precision_mv,
10983 mi_col * MI_SIZE + MI_SIZE / 2,
10984 mi_row * MI_SIZE + MI_SIZE / 2)
10985 .as_int
10986 : 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -080010987#else
10988 zeromv[0].as_int = 0;
10989 zeromv[1].as_int = 0;
10990#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010991 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
10992 best_mbmode.mv[0].as_int &&
10993 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
10994 best_mbmode.mv[1].as_int)
10995 best_mbmode.mode = NEAREST_NEARESTMV;
10996 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
10997 best_mbmode.mv[0].as_int &&
10998 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
10999 best_mbmode.mv[1].as_int)
11000 best_mbmode.mode = NEAREST_NEARMV;
11001 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
11002 best_mbmode.mv[0].as_int &&
11003 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
11004 best_mbmode.mv[1].as_int)
11005 best_mbmode.mode = NEAR_NEARESTMV;
11006 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
11007 best_mbmode.mv[0].as_int &&
11008 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
11009 best_mbmode.mv[1].as_int)
11010 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011011 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11012 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011013 best_mbmode.mode = ZERO_ZEROMV;
11014 }
11015#endif // CONFIG_EXT_INTER
11016#endif
11017 }
11018
11019#if CONFIG_REF_MV
David Barkercdcac6d2016-12-01 17:04:16 +000011020 {
Jingning Han731af492016-11-17 11:53:23 -080011021 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11022 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011023 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011024 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011025#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011026 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11027 best_mbmode.ref_frame[1] };
11028 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011029 cm->allow_high_precision_mv,
11030 mi_col * MI_SIZE + MI_SIZE / 2,
11031 mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +000011032 .as_int;
11033 zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
David Barker45390c12017-02-20 14:44:40 +000011034 cm->allow_high_precision_mv,
11035 mi_col * MI_SIZE + MI_SIZE / 2,
11036 mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +000011037 .as_int;
11038 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11039 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11040#else
11041 zeromv[0].as_int = zeromv[1].as_int = 0;
11042#endif // CONFIG_GLOBAL_MOTION
11043 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11044 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11045#if CONFIG_EXT_INTER
11046 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11047#else
Emil Keyder01770b32017-01-20 18:03:11 -050011048 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011049 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11050#endif // CONFIG_EXT_INTER
11051 ) {
11052 best_mbmode.mode = ZEROMV;
11053 }
David Barker68e6e862016-11-24 15:10:15 +000011054 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011055 }
11056#endif
11057
11058 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11059 rd_cost->rate = INT_MAX;
11060 rd_cost->rdcost = INT64_MAX;
11061 return;
11062 }
11063
Yaowu Xuc27fc142016-08-22 16:08:15 -070011064#if CONFIG_DUAL_FILTER
11065 assert((cm->interp_filter == SWITCHABLE) ||
11066 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11067 !is_inter_block(&best_mbmode));
11068 assert((cm->interp_filter == SWITCHABLE) ||
11069 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11070 !is_inter_block(&best_mbmode));
11071 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11072 assert((cm->interp_filter == SWITCHABLE) ||
11073 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11074 !is_inter_block(&best_mbmode));
11075 assert((cm->interp_filter == SWITCHABLE) ||
11076 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11077 !is_inter_block(&best_mbmode));
11078 }
11079#else
11080 assert((cm->interp_filter == SWITCHABLE) ||
11081 (cm->interp_filter == best_mbmode.interp_filter) ||
11082 !is_inter_block(&best_mbmode));
11083#endif
11084
11085 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011086 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11087 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011088
11089 // macroblock modes
11090 *mbmi = best_mbmode;
11091 x->skip |= best_skip2;
11092
Yue Chen19e7aa82016-11-30 14:05:39 -080011093// Note: this section is needed since the mode may have been forced to
11094// ZEROMV by the all-zero mode handling of ref-mv.
11095#if CONFIG_GLOBAL_MOTION
11096 if (mbmi->mode == ZEROMV
11097#if CONFIG_EXT_INTER
11098 || mbmi->mode == ZERO_ZEROMV
11099#endif // CONFIG_EXT_INTER
11100 ) {
11101 if (is_nontrans_global_motion(xd)) {
11102#if CONFIG_DUAL_FILTER
11103 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11104 ? EIGHTTAP_REGULAR
11105 : cm->interp_filter;
11106 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11107 ? EIGHTTAP_REGULAR
11108 : cm->interp_filter;
11109#else
11110 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11111 : cm->interp_filter;
11112#endif // CONFIG_DUAL_FILTER
11113 }
11114 }
11115#endif // CONFIG_GLOBAL_MOTION
11116
Yaowu Xuc27fc142016-08-22 16:08:15 -070011117#if CONFIG_REF_MV
11118 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11119 if (mbmi->mode != NEWMV)
11120 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11121 else
11122 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11123 }
11124#endif
11125
11126 for (i = 0; i < REFERENCE_MODES; ++i) {
11127 if (best_pred_rd[i] == INT64_MAX)
11128 best_pred_diff[i] = INT_MIN;
11129 else
11130 best_pred_diff[i] = best_rd - best_pred_rd[i];
11131 }
11132
11133 x->skip |= best_mode_skippable;
11134
11135 assert(best_mode_index >= 0);
11136
11137 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11138 best_mode_skippable);
11139
Urvang Joshib100db72016-10-12 16:28:56 -070011140#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011141 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11142 restore_uv_color_map(cpi, x);
11143 }
Urvang Joshib100db72016-10-12 16:28:56 -070011144#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011145}
11146
Urvang Joshi52648442016-10-13 17:27:51 -070011147void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11148 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011149 int mi_row, int mi_col,
Urvang Joshi52648442016-10-13 17:27:51 -070011150 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011151 PICK_MODE_CONTEXT *ctx,
11152 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011153 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011154 MACROBLOCKD *const xd = &x->e_mbd;
11155 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11156 unsigned char segment_id = mbmi->segment_id;
11157 const int comp_pred = 0;
11158 int i;
11159 int64_t best_pred_diff[REFERENCE_MODES];
11160 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11161 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011162 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011163 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011164 int64_t this_rd = INT64_MAX;
11165 int rate2 = 0;
11166 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011167 (void)mi_row;
11168 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011169
11170 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11171 &comp_mode_p);
11172
11173 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11174 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11175 x->pred_mv_sad[i] = INT_MAX;
11176
11177 rd_cost->rate = INT_MAX;
11178
11179 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11180
Urvang Joshib100db72016-10-12 16:28:56 -070011181#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011182 mbmi->palette_mode_info.palette_size[0] = 0;
11183 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011184#endif // CONFIG_PALETTE
11185
hui su5db97432016-10-14 16:10:14 -070011186#if CONFIG_FILTER_INTRA
11187 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11188 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11189#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011190 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011191 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011192 mbmi->uv_mode = DC_PRED;
11193 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011194 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011195#if CONFIG_GLOBAL_MOTION
11196 mbmi->mv[0].as_int =
David Barker45390c12017-02-20 14:44:40 +000011197 gm_get_motion_vector(
11198 &cm->global_motion[mbmi->ref_frame[0]], cm->allow_high_precision_mv,
11199 mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
David Barkercdcac6d2016-12-01 17:04:16 +000011200 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011201#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011202 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011203#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011204 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011205 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011206
Yaowu Xuc27fc142016-08-22 16:08:15 -070011207#if CONFIG_REF_MV
11208 mbmi->ref_mv_idx = 0;
11209 mbmi->pred_mv[0].as_int = 0;
11210#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011211
11212 if (cm->interp_filter != BILINEAR) {
11213 best_filter = EIGHTTAP_REGULAR;
11214 if (cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011215 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11216 int rs;
11217 int best_rs = INT_MAX;
11218 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11219#if CONFIG_DUAL_FILTER
11220 int k;
11221 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11222#else
11223 mbmi->interp_filter = i;
11224#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070011225 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011226 if (rs < best_rs) {
11227 best_rs = rs;
11228#if CONFIG_DUAL_FILTER
11229 best_filter = mbmi->interp_filter[0];
11230#else
11231 best_filter = mbmi->interp_filter;
11232#endif
11233 }
11234 }
11235 }
11236 }
11237 // Set the appropriate filter
11238 if (cm->interp_filter == SWITCHABLE) {
11239#if CONFIG_DUAL_FILTER
11240 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
11241#else
11242 mbmi->interp_filter = best_filter;
11243#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070011244 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011245 } else {
11246#if CONFIG_DUAL_FILTER
11247 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
11248#else
11249 mbmi->interp_filter = cm->interp_filter;
11250#endif
11251 }
11252
11253 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011254 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011255
11256 // Estimate the reference frame signaling cost and add it
11257 // to the rolling cost variable.
11258 rate2 += ref_costs_single[LAST_FRAME];
11259 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11260
11261 rd_cost->rate = rate2;
11262 rd_cost->dist = distortion2;
11263 rd_cost->rdcost = this_rd;
11264
11265 if (this_rd >= best_rd_so_far) {
11266 rd_cost->rate = INT_MAX;
11267 rd_cost->rdcost = INT64_MAX;
11268 return;
11269 }
11270
11271#if CONFIG_DUAL_FILTER
11272 assert((cm->interp_filter == SWITCHABLE) ||
11273 (cm->interp_filter == mbmi->interp_filter[0]));
11274#else
11275 assert((cm->interp_filter == SWITCHABLE) ||
11276 (cm->interp_filter == mbmi->interp_filter));
11277#endif
11278
Yaowu Xuf883b422016-08-30 14:01:10 -070011279 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11280 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011281
Yaowu Xuf883b422016-08-30 14:01:10 -070011282 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011283
11284 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11285}
11286
Urvang Joshi52648442016-10-13 17:27:51 -070011287void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11288 TileDataEnc *tile_data, struct macroblock *x,
11289 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070011290 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011291#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011292 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011293#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011294 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11295 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011296 const AV1_COMMON *const cm = &cpi->common;
11297 const RD_OPT *const rd_opt = &cpi->rd;
11298 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011299 MACROBLOCKD *const xd = &x->e_mbd;
11300 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11301 const struct segmentation *const seg = &cm->seg;
11302 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11303 unsigned char segment_id = mbmi->segment_id;
11304 int comp_pred, i;
11305 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11306 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11307 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11308 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011309 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011310#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011311 AOM_LAST2_FLAG,
11312 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011313#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011314 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011315#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011316 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011317#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011318 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011319 };
11320 int64_t best_rd = best_rd_so_far;
11321 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11322 int64_t best_pred_diff[REFERENCE_MODES];
11323 int64_t best_pred_rd[REFERENCE_MODES];
11324 MB_MODE_INFO best_mbmode;
11325 int ref_index, best_ref_index = 0;
11326 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11327 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011328 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011329#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011330 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011331#else
James Zern7b9407a2016-05-18 23:48:05 -070011332 InterpFilter tmp_best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011333#endif
Jingning Han3f167252016-06-07 16:11:42 -070011334 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11335 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011336 int skip_uv;
11337 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011338 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011339 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
11340#if CONFIG_EXT_INTER
11341 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
11342#else
11343 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
11344#endif // CONFIG_EXT_INTER
11345 b_mode_info best_bmodes[4];
11346 int best_skip2 = 0;
11347 int ref_frame_skip_mask[2] = { 0 };
11348 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011349 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011350#if CONFIG_PVQ
11351 od_rollback_buffer pre_buf;
11352
11353 od_encode_checkpoint(&x->daala_enc, &pre_buf);
11354#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011355
11356#if CONFIG_SUPERTX
11357 best_rd_so_far = INT64_MAX;
11358 best_rd = best_rd_so_far;
11359 best_yrd = best_rd_so_far;
11360#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011361 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011362
hui su5db97432016-10-14 16:10:14 -070011363#if CONFIG_FILTER_INTRA
11364 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11365 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11366#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011367 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011368#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -080011369 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011370 mbmi->use_wedge_interintra = 0;
11371#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011372#if CONFIG_WARPED_MOTION
11373 mbmi->num_proj_ref[0] = 0;
11374 mbmi->num_proj_ref[1] = 0;
11375#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011376
11377 for (i = 0; i < 4; i++) {
11378 int j;
11379#if CONFIG_EXT_INTER
11380 int k;
11381
11382 for (k = 0; k < 2; k++)
11383 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11384 seg_mvs[i][k][j].as_int = INVALID_MV;
11385#else
11386 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11387 seg_mvs[i][j].as_int = INVALID_MV;
11388#endif // CONFIG_EXT_INTER
11389 }
11390
11391 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11392 &comp_mode_p);
11393
11394 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11395 rate_uv_intra = INT_MAX;
11396
11397 rd_cost->rate = INT_MAX;
11398#if CONFIG_SUPERTX
11399 *returnrate_nocoef = INT_MAX;
11400#endif
11401
11402 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11403 x->mbmi_ext->mode_context[ref_frame] = 0;
11404#if CONFIG_REF_MV && CONFIG_EXT_INTER
11405 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
11406#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
11407 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11408 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11409 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11410 } else {
11411 ref_frame_skip_mask[0] |= (1 << ref_frame);
11412 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11413 }
11414 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11415#if CONFIG_EXT_INTER
11416 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
11417#endif // CONFIG_EXT_INTER
11418 frame_mv[ZEROMV][ref_frame].as_int = 0;
11419 }
11420
Urvang Joshib100db72016-10-12 16:28:56 -070011421#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011422 mbmi->palette_mode_info.palette_size[0] = 0;
11423 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011424#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011425
11426 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11427 int mode_excluded = 0;
11428 int64_t this_rd = INT64_MAX;
11429 int disable_skip = 0;
11430 int compmode_cost = 0;
11431 int rate2 = 0, rate_y = 0, rate_uv = 0;
11432 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11433 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011434 int this_skip2 = 0;
11435 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011436
Yushin Cho77bba8d2016-11-04 16:36:56 -070011437#if CONFIG_PVQ
11438 od_encode_rollback(&x->daala_enc, &pre_buf);
11439#endif
11440
Yaowu Xuf883b422016-08-30 14:01:10 -070011441 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11442 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011443
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011444#if CONFIG_REF_MV
11445 mbmi->ref_mv_idx = 0;
11446#endif
11447
Yaowu Xuc27fc142016-08-22 16:08:15 -070011448 // Look at the reference frame of the best mode so far and set the
11449 // skip mask to look at a subset of the remaining modes.
11450 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11451 if (ref_index == 3) {
11452 switch (best_mbmode.ref_frame[0]) {
11453 case INTRA_FRAME: break;
11454 case LAST_FRAME:
11455 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11456#if CONFIG_EXT_REFS
11457 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11458 (1 << BWDREF_FRAME) |
11459#endif // CONFIG_EXT_REFS
11460 (1 << ALTREF_FRAME);
11461 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11462 break;
11463#if CONFIG_EXT_REFS
11464 case LAST2_FRAME:
11465 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11466 (1 << GOLDEN_FRAME) |
11467 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11468 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11469 break;
11470 case LAST3_FRAME:
11471 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11472 (1 << GOLDEN_FRAME) |
11473 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11474 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11475 break;
11476#endif // CONFIG_EXT_REFS
11477 case GOLDEN_FRAME:
11478 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11479#if CONFIG_EXT_REFS
11480 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11481 (1 << BWDREF_FRAME) |
11482#endif // CONFIG_EXT_REFS
11483 (1 << ALTREF_FRAME);
11484 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11485 break;
11486#if CONFIG_EXT_REFS
11487 case BWDREF_FRAME:
11488 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11489 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11490 (1 << ALTREF_FRAME);
11491 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11492 break;
11493#endif // CONFIG_EXT_REFS
11494 case ALTREF_FRAME:
11495 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11496#if CONFIG_EXT_REFS
11497 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11498 (1 << BWDREF_FRAME) |
11499#endif // CONFIG_EXT_REFS
11500 (1 << GOLDEN_FRAME);
11501#if CONFIG_EXT_REFS
11502 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11503#endif // CONFIG_EXT_REFS
11504 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011505 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011506 case TOTAL_REFS_PER_FRAME:
11507 assert(0 && "Invalid Reference frame");
11508 break;
11509 }
11510 }
11511 }
11512
11513 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011514 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011515 continue;
11516
11517 // Test best rd so far against threshold for trying this mode.
11518 if (!internal_active_edge &&
11519 rd_less_than_thresh(best_rd,
11520 rd_opt->threshes[segment_id][bsize][ref_index],
11521 tile_data->thresh_freq_fact[bsize][ref_index]))
11522 continue;
11523
11524 comp_pred = second_ref_frame > INTRA_FRAME;
11525 if (comp_pred) {
11526 if (!cpi->allow_comp_inter_inter) continue;
11527 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11528 // Do not allow compound prediction if the segment level reference frame
11529 // feature is in use as in this case there can only be one reference.
11530 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11531
11532 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11533 best_mbmode.ref_frame[0] == INTRA_FRAME)
11534 continue;
11535 }
11536
11537 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11538 // sub8x8 blocks.
11539 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011540 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011541 continue;
11542
11543 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011544 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011545 continue;
11546
11547 if (comp_pred)
11548 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11549 else if (ref_frame != INTRA_FRAME)
11550 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11551
11552 // If the segment reference frame feature is enabled....
11553 // then do nothing if the current ref frame is not allowed..
11554 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11555 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11556 continue;
11557 // Disable this drop out case if the ref frame
11558 // segment level feature is enabled for this segment. This is to
11559 // prevent the possibility that we end up unable to pick any mode.
11560 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11561 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11562 // unless ARNR filtering is enabled in which case we want
11563 // an unfiltered alternative. We allow near/nearest as well
11564 // because they may result in zero-zero MVs but be cheaper.
11565 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11566 continue;
11567 }
11568
11569 mbmi->tx_size = TX_4X4;
11570 mbmi->uv_mode = DC_PRED;
11571 mbmi->ref_frame[0] = ref_frame;
11572 mbmi->ref_frame[1] = second_ref_frame;
11573// Evaluate all sub-pel filters irrespective of whether we can use
11574// them for this frame.
11575#if CONFIG_DUAL_FILTER
11576 for (i = 0; i < 4; ++i)
11577 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11578 ? EIGHTTAP_REGULAR
11579 : cm->interp_filter;
11580#else
11581 mbmi->interp_filter =
11582 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
11583#endif
11584 x->skip = 0;
11585 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11586
11587 // Select prediction reference frames.
11588 for (i = 0; i < MAX_MB_PLANE; i++) {
11589 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11590 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11591 }
11592
11593#if CONFIG_VAR_TX
11594 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011595 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011596#endif
11597
11598 if (ref_frame == INTRA_FRAME) {
11599 int rate;
11600 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011601 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011602 continue;
11603 rate2 += rate;
11604 rate2 += intra_cost_penalty;
11605 distortion2 += distortion_y;
11606
11607 if (rate_uv_intra == INT_MAX) {
11608 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11609 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11610 }
11611 rate2 += rate_uv_intra;
11612 rate_uv = rate_uv_tokenonly;
11613 distortion2 += dist_uv;
11614 distortion_uv = dist_uv;
11615 mbmi->uv_mode = mode_uv;
11616 } else {
11617 int rate;
11618 int64_t distortion;
11619 int64_t this_rd_thresh;
11620 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11621 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11622 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11623 int tmp_best_skippable = 0;
11624 int switchable_filter_index;
11625 int_mv *second_ref =
11626 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11627 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11628 MB_MODE_INFO tmp_best_mbmode;
11629#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011630 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011631#else
11632 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
11633#endif
11634 int pred_exists = 0;
11635 int uv_skippable;
11636#if CONFIG_EXT_INTER
11637 int_mv compound_seg_newmvs[4][2];
11638 for (i = 0; i < 4; i++) {
11639 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11640 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11641 }
11642#endif // CONFIG_EXT_INTER
11643
11644 this_rd_thresh = (ref_frame == LAST_FRAME)
11645 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11646 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11647#if CONFIG_EXT_REFS
11648 this_rd_thresh = (ref_frame == LAST2_FRAME)
11649 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11650 : this_rd_thresh;
11651 this_rd_thresh = (ref_frame == LAST3_FRAME)
11652 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11653 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011654 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11655 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11656 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011657#endif // CONFIG_EXT_REFS
11658 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11659 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11660 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011661
11662 // TODO(any): Add search of the tx_type to improve rd performance at the
11663 // expense of speed.
11664 mbmi->tx_type = DCT_DCT;
11665
11666 if (cm->interp_filter != BILINEAR) {
11667#if CONFIG_DUAL_FILTER
11668 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11669 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11670 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11671 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11672#else
11673 tmp_best_filter = EIGHTTAP_REGULAR;
11674#endif
11675 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11676#if CONFIG_DUAL_FILTER
11677 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11678#else
11679 tmp_best_filter = EIGHTTAP_REGULAR;
11680#endif
11681 } else if (sf->adaptive_pred_interp_filter == 1 &&
11682 ctx->pred_interp_filter < SWITCHABLE) {
11683#if CONFIG_DUAL_FILTER
11684 tmp_best_filter[0] = ctx->pred_interp_filter;
11685#else
11686 tmp_best_filter = ctx->pred_interp_filter;
11687#endif
11688 } else if (sf->adaptive_pred_interp_filter == 2) {
11689#if CONFIG_DUAL_FILTER
11690 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
11691 ? ctx->pred_interp_filter
11692 : 0;
11693#else
11694 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
11695 ? ctx->pred_interp_filter
11696 : 0;
11697#endif
11698 } else {
11699#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011700 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011701#else
Angie Chiang5678ad92016-11-21 09:38:40 -080011702 const int filter_set_size = SWITCHABLE_FILTERS;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011703#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011704 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080011705 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011706 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011707 int newbest, rs;
11708 int64_t rs_rd;
11709 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
11710#if CONFIG_DUAL_FILTER
11711 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
11712 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
11713 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
11714 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
11715#else
11716 mbmi->interp_filter = switchable_filter_index;
11717#endif
Yushin Cho482016d2017-01-06 14:06:13 -080011718 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011719 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11720 &rate, &rate_y, &distortion, &skippable, &total_sse,
11721 (int)this_rd_thresh, seg_mvs,
11722#if CONFIG_EXT_INTER
11723 compound_seg_newmvs,
11724#endif // CONFIG_EXT_INTER
11725 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011726 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070011727 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011728 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
11729 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
11730
11731 newbest = (tmp_rd < tmp_best_rd);
11732 if (newbest) {
11733#if CONFIG_DUAL_FILTER
11734 tmp_best_filter[0] = mbmi->interp_filter[0];
11735 tmp_best_filter[1] = mbmi->interp_filter[1];
11736 tmp_best_filter[2] = mbmi->interp_filter[2];
11737 tmp_best_filter[3] = mbmi->interp_filter[3];
11738#else
11739 tmp_best_filter = mbmi->interp_filter;
11740#endif
11741 tmp_best_rd = tmp_rd;
11742 }
11743 if ((newbest && cm->interp_filter == SWITCHABLE) ||
11744 (
11745#if CONFIG_DUAL_FILTER
11746 mbmi->interp_filter[0] == cm->interp_filter
11747#else
11748 mbmi->interp_filter == cm->interp_filter
11749#endif
11750 && cm->interp_filter != SWITCHABLE)) {
11751 tmp_best_rdu = tmp_rd;
11752 tmp_best_rate = rate;
11753 tmp_best_ratey = rate_y;
11754 tmp_best_distortion = distortion;
11755 tmp_best_sse = total_sse;
11756 tmp_best_skippable = skippable;
11757 tmp_best_mbmode = *mbmi;
11758 for (i = 0; i < 4; i++) {
11759 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
11760 }
11761 pred_exists = 1;
11762 }
11763 } // switchable_filter_index loop
11764 }
11765 }
11766
11767 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
11768
11769#if CONFIG_DUAL_FILTER
11770 mbmi->interp_filter[0] =
11771 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
11772 : cm->interp_filter);
11773 mbmi->interp_filter[1] =
11774 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
11775 : cm->interp_filter);
11776 mbmi->interp_filter[2] =
11777 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
11778 : cm->interp_filter);
11779 mbmi->interp_filter[3] =
11780 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
11781 : cm->interp_filter);
11782#else
11783 mbmi->interp_filter =
11784 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
11785 : cm->interp_filter);
11786#endif
11787
11788 if (!pred_exists) {
11789 // Handles the special case when a filter that is not in the
11790 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080011791 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011792 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11793 &rate, &rate_y, &distortion, &skippable, &total_sse,
11794 (int)this_rd_thresh, seg_mvs,
11795#if CONFIG_EXT_INTER
11796 compound_seg_newmvs,
11797#endif // CONFIG_EXT_INTER
11798 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011799 if (tmp_rd == INT64_MAX) continue;
11800 } else {
11801 total_sse = tmp_best_sse;
11802 rate = tmp_best_rate;
11803 rate_y = tmp_best_ratey;
11804 distortion = tmp_best_distortion;
11805 skippable = tmp_best_skippable;
11806 *mbmi = tmp_best_mbmode;
11807 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
11808 }
11809 // Add in the cost of the transform type
11810 if (!xd->lossless[mbmi->segment_id]) {
11811 int rate_tx_type = 0;
11812#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080011813 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
11814 1) {
11815 const int eset =
11816 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011817 rate_tx_type =
11818 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
11819 }
11820#else
11821 if (mbmi->tx_size < TX_32X32) {
11822 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
11823 }
11824#endif
11825 rate += rate_tx_type;
11826 rate_y += rate_tx_type;
11827 }
11828
11829 rate2 += rate;
11830 distortion2 += distortion;
11831
11832 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070011833 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011834
11835 if (!mode_excluded)
11836 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
11837 : cm->reference_mode == COMPOUND_REFERENCE;
11838
Yaowu Xuf883b422016-08-30 14:01:10 -070011839 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011840
11841 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070011842 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011843 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
11844
11845 if (tmp_best_rdu > 0) {
11846 // If even the 'Y' rd value of split is higher than best so far
11847 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070011848 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070011849 RD_STATS rd_stats_uv;
David Barkerac37fa32016-12-02 12:30:21 +000011850 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
11851 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011852#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070011853 is_cost_valid_uv =
11854 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080011855#else
11856 is_cost_valid_uv =
11857 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
11858#endif
Angie Chiangb5dda482016-11-02 16:19:58 -070011859 rate_uv = rd_stats_uv.rate;
11860 distortion_uv = rd_stats_uv.dist;
11861 uv_skippable = rd_stats_uv.skip;
11862 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080011863
Angie Chiangb5dda482016-11-02 16:19:58 -070011864 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011865 rate2 += rate_uv;
11866 distortion2 += distortion_uv;
11867 skippable = skippable && uv_skippable;
11868 total_sse += uv_sse;
11869 } else {
11870 continue;
11871 }
11872 }
11873
11874 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
11875
11876 // Estimate the reference frame signaling cost and add it
11877 // to the rolling cost variable.
11878 if (second_ref_frame > INTRA_FRAME) {
11879 rate2 += ref_costs_comp[ref_frame];
11880#if CONFIG_EXT_REFS
11881 rate2 += ref_costs_comp[second_ref_frame];
11882#endif // CONFIG_EXT_REFS
11883 } else {
11884 rate2 += ref_costs_single[ref_frame];
11885 }
11886
11887 if (!disable_skip) {
11888 // Skip is never coded at the segment level for sub8x8 blocks and instead
11889 // always coded in the bitstream at the mode info level.
11890
11891 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
11892 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
11893 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
11894 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070011895 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011896 } else {
11897 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070011898 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011899 distortion2 = total_sse;
11900 assert(total_sse >= 0);
11901 rate2 -= (rate_y + rate_uv);
11902 rate_y = 0;
11903 rate_uv = 0;
11904 this_skip2 = 1;
11905 }
11906 } else {
11907 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070011908 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011909 }
11910
11911 // Calculate the final RD estimate for this mode.
11912 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11913 }
11914
11915 if (!disable_skip && ref_frame == INTRA_FRAME) {
11916 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070011917 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011918 }
11919
11920 // Did this mode help.. i.e. is it the new best mode
11921 if (this_rd < best_rd || x->skip) {
11922 if (!mode_excluded) {
11923 // Note index of best mode so far
11924 best_ref_index = ref_index;
11925
11926 if (ref_frame == INTRA_FRAME) {
11927 /* required for left and above block mv */
11928 mbmi->mv[0].as_int = 0;
11929 }
11930
11931 rd_cost->rate = rate2;
11932#if CONFIG_SUPERTX
11933 *returnrate_nocoef = rate2 - rate_y - rate_uv;
11934 if (!disable_skip)
11935 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070011936 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
11937 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
11938 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011939 assert(*returnrate_nocoef > 0);
11940#endif // CONFIG_SUPERTX
11941 rd_cost->dist = distortion2;
11942 rd_cost->rdcost = this_rd;
11943 best_rd = this_rd;
11944 best_yrd =
11945 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
11946 best_mbmode = *mbmi;
11947 best_skip2 = this_skip2;
11948
11949#if CONFIG_VAR_TX
11950 for (i = 0; i < MAX_MB_PLANE; ++i)
11951 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
11952#endif
11953
11954 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011955 }
11956 }
11957
11958 /* keep record of best compound/single-only prediction */
11959 if (!disable_skip && ref_frame != INTRA_FRAME) {
11960 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
11961
11962 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
11963 single_rate = rate2 - compmode_cost;
11964 hybrid_rate = rate2;
11965 } else {
11966 single_rate = rate2;
11967 hybrid_rate = rate2 + compmode_cost;
11968 }
11969
11970 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
11971 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
11972
11973 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
11974 best_pred_rd[SINGLE_REFERENCE] = single_rd;
11975 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
11976 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
11977
11978 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
11979 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
11980 }
11981
Yaowu Xuc27fc142016-08-22 16:08:15 -070011982 if (x->skip && !comp_pred) break;
11983 }
11984
11985 if (best_rd >= best_rd_so_far) {
11986 rd_cost->rate = INT_MAX;
11987 rd_cost->rdcost = INT64_MAX;
11988#if CONFIG_SUPERTX
11989 *returnrate_nocoef = INT_MAX;
11990#endif // CONFIG_SUPERTX
11991 return;
11992 }
11993
Yaowu Xuc27fc142016-08-22 16:08:15 -070011994 if (best_rd == INT64_MAX) {
11995 rd_cost->rate = INT_MAX;
11996 rd_cost->dist = INT64_MAX;
11997 rd_cost->rdcost = INT64_MAX;
11998#if CONFIG_SUPERTX
11999 *returnrate_nocoef = INT_MAX;
12000#endif // CONFIG_SUPERTX
12001 return;
12002 }
12003
12004#if CONFIG_DUAL_FILTER
12005 assert((cm->interp_filter == SWITCHABLE) ||
12006 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12007 !is_inter_block(&best_mbmode));
12008#else
12009 assert((cm->interp_filter == SWITCHABLE) ||
12010 (cm->interp_filter == best_mbmode.interp_filter) ||
12011 !is_inter_block(&best_mbmode));
12012#endif
12013
Yaowu Xuf883b422016-08-30 14:01:10 -070012014 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12015 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012016
12017 // macroblock modes
12018 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012019#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012020 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hanfe45b212016-11-22 10:30:23 -080012021#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070012022
12023 x->skip |= best_skip2;
12024 if (!is_inter_block(&best_mbmode)) {
12025 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12026 } else {
12027 for (i = 0; i < 4; ++i)
12028 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12029
Yaowu Xuc27fc142016-08-22 16:08:15 -070012030#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012031 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12032 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012033#endif
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012034 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12035 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012036 }
12037
Yue Chen19e7aa82016-11-30 14:05:39 -080012038// Note: this section is needed since the mode may have been forced to ZEROMV
12039#if CONFIG_GLOBAL_MOTION
12040 if (mbmi->mode == ZEROMV
12041#if CONFIG_EXT_INTER
12042 || mbmi->mode == ZERO_ZEROMV
12043#endif // CONFIG_EXT_INTER
12044 ) {
12045 if (is_nontrans_global_motion(xd)) {
12046#if CONFIG_DUAL_FILTER
12047 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12048 ? EIGHTTAP_REGULAR
12049 : cm->interp_filter;
12050 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12051 ? EIGHTTAP_REGULAR
12052 : cm->interp_filter;
12053#else
12054 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12055 : cm->interp_filter;
12056#endif // CONFIG_DUAL_FILTER
12057 }
12058 }
12059#endif // CONFIG_GLOBAL_MOTION
12060
Yaowu Xuc27fc142016-08-22 16:08:15 -070012061 for (i = 0; i < REFERENCE_MODES; ++i) {
12062 if (best_pred_rd[i] == INT64_MAX)
12063 best_pred_diff[i] = INT_MIN;
12064 else
12065 best_pred_diff[i] = best_rd - best_pred_rd[i];
12066 }
12067
12068 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12069}
12070
Yue Chencb60b182016-10-13 15:18:22 -070012071#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012072// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012073//
12074// The OBMC predictor is computed as:
12075//
12076// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012077// AOM_BLEND_A64(Mh(x),
12078// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012079// PLeft(x, y))
12080//
Yaowu Xuf883b422016-08-30 14:01:10 -070012081// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012082// rounding, this can be written as:
12083//
Yaowu Xuf883b422016-08-30 14:01:10 -070012084// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012085// Mh(x) * Mv(y) * P(x,y) +
12086// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012087// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012088//
12089// Where :
12090//
Yaowu Xuf883b422016-08-30 14:01:10 -070012091// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12092// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012093//
12094// This function computes 'wsrc' and 'mask' as:
12095//
12096// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012097// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012098// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012099// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012100//
12101// mask(x, y) = Mh(x) * Mv(y)
12102//
12103// These can then be used to efficiently approximate the error for any
12104// predictor P in the context of the provided neighbouring predictors by
12105// computing:
12106//
12107// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012108// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012109//
Yaowu Xuf883b422016-08-30 14:01:10 -070012110static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012111 const MACROBLOCKD *xd, int mi_row,
12112 int mi_col, const uint8_t *above,
12113 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012114 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012115 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12116 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012117 const int bw = xd->n8_w << MI_SIZE_LOG2;
12118 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012119 int32_t *mask_buf = x->mask_buf;
12120 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012121 const int wsrc_stride = bw;
12122 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012123 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
12124#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012125 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12126#else
12127 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070012128#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012129
12130 // plane 0 should not be subsampled
12131 assert(xd->plane[0].subsampling_x == 0);
12132 assert(xd->plane[0].subsampling_y == 0);
12133
Yaowu Xuf883b422016-08-30 14:01:10 -070012134 av1_zero_array(wsrc_buf, bw * bh);
12135 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012136
12137 // handle above row
12138 if (xd->up_available) {
12139 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012140 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012141 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012142 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012143
12144 assert(miw > 0);
12145
12146 i = 0;
12147 do { // for each mi in the above row
12148 const int mi_col_offset = i;
12149 const MB_MODE_INFO *const above_mbmi =
12150 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12151 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012152 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012153 const int neighbor_bw = mi_step * MI_SIZE;
12154
12155 if (is_neighbor_overlappable(above_mbmi)) {
12156 const int tmp_stride = above_stride;
12157 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12158 int32_t *mask = mask_buf + (i * MI_SIZE);
12159
12160 if (!is_hbd) {
12161 const uint8_t *tmp = above;
12162
12163 for (row = 0; row < overlap; ++row) {
12164 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012165 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012166 for (col = 0; col < neighbor_bw; ++col) {
12167 wsrc[col] = m1 * tmp[col];
12168 mask[col] = m0;
12169 }
12170 wsrc += wsrc_stride;
12171 mask += mask_stride;
12172 tmp += tmp_stride;
12173 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012174#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012175 } else {
12176 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12177
12178 for (row = 0; row < overlap; ++row) {
12179 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012180 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012181 for (col = 0; col < neighbor_bw; ++col) {
12182 wsrc[col] = m1 * tmp[col];
12183 mask[col] = m0;
12184 }
12185 wsrc += wsrc_stride;
12186 mask += mask_stride;
12187 tmp += tmp_stride;
12188 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012189#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012190 }
12191 }
12192
12193 above += neighbor_bw;
12194 i += mi_step;
12195 } while (i < miw);
12196 }
12197
12198 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012199 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12200 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012201 }
12202
12203 // handle left column
12204 if (xd->left_available) {
12205 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012206 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012207 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012208 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012209
12210 assert(mih > 0);
12211
12212 i = 0;
12213 do { // for each mi in the left column
12214 const int mi_row_offset = i;
12215 const MB_MODE_INFO *const left_mbmi =
12216 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12217 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012218 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012219 const int neighbor_bh = mi_step * MI_SIZE;
12220
12221 if (is_neighbor_overlappable(left_mbmi)) {
12222 const int tmp_stride = left_stride;
12223 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12224 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12225
12226 if (!is_hbd) {
12227 const uint8_t *tmp = left;
12228
12229 for (row = 0; row < neighbor_bh; ++row) {
12230 for (col = 0; col < overlap; ++col) {
12231 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012232 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12233 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12234 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12235 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012236 }
12237 wsrc += wsrc_stride;
12238 mask += mask_stride;
12239 tmp += tmp_stride;
12240 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012241#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012242 } else {
12243 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
12244
12245 for (row = 0; row < neighbor_bh; ++row) {
12246 for (col = 0; col < overlap; ++col) {
12247 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012248 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12249 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12250 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12251 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012252 }
12253 wsrc += wsrc_stride;
12254 mask += mask_stride;
12255 tmp += tmp_stride;
12256 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012257#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012258 }
12259 }
12260
12261 left += neighbor_bh * left_stride;
12262 i += mi_step;
12263 } while (i < mih);
12264 }
12265
12266 if (!is_hbd) {
12267 const uint8_t *src = x->plane[0].src.buf;
12268
12269 for (row = 0; row < bh; ++row) {
12270 for (col = 0; col < bw; ++col) {
12271 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12272 }
12273 wsrc_buf += wsrc_stride;
12274 src += x->plane[0].src.stride;
12275 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012276#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012277 } else {
12278 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12279
12280 for (row = 0; row < bh; ++row) {
12281 for (col = 0; col < bw; ++col) {
12282 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12283 }
12284 wsrc_buf += wsrc_stride;
12285 src += x->plane[0].src.stride;
12286 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012287#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012288 }
12289}
Yue Chenf27b1602017-01-13 11:11:43 -080012290
12291#if CONFIG_NCOBMC
12292void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12293 int mi_row, int mi_col) {
12294 const AV1_COMMON *const cm = &cpi->common;
12295 MACROBLOCKD *const xd = &x->e_mbd;
12296 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12297 MB_MODE_INFO backup_mbmi;
12298 BLOCK_SIZE bsize = mbmi->sb_type;
12299 int ref, skip_blk, backup_skip = x->skip;
12300 int64_t rd_causal;
12301 RD_STATS rd_stats_y, rd_stats_uv;
12302 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12303 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12304
12305 // Recompute the best causal predictor and rd
12306 mbmi->motion_mode = SIMPLE_TRANSLATION;
12307 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12308 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12309 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12310 assert(cfg != NULL);
12311 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12312 &xd->block_refs[ref]->sf);
12313 }
12314 av1_setup_dst_planes(x->e_mbd.plane, get_frame_new_buffer(&cpi->common),
12315 mi_row, mi_col);
12316
12317 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
12318
12319 av1_subtract_plane(x, bsize, 0);
12320 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12321 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12322 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12323 if (rd_stats_y.skip && rd_stats_uv.skip) {
12324 rd_stats_y.rate = rate_skip1;
12325 rd_stats_uv.rate = 0;
12326 rd_stats_y.dist = rd_stats_y.sse;
12327 rd_stats_uv.dist = rd_stats_uv.sse;
12328 skip_blk = 0;
12329 } else if (RDCOST(x->rdmult, x->rddiv,
12330 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12331 (rd_stats_y.dist + rd_stats_uv.dist)) >
12332 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12333 (rd_stats_y.sse + rd_stats_uv.sse))) {
12334 rd_stats_y.rate = rate_skip1;
12335 rd_stats_uv.rate = 0;
12336 rd_stats_y.dist = rd_stats_y.sse;
12337 rd_stats_uv.dist = rd_stats_uv.sse;
12338 skip_blk = 1;
12339 } else {
12340 rd_stats_y.rate += rate_skip0;
12341 skip_blk = 0;
12342 }
12343 backup_skip = skip_blk;
12344 backup_mbmi = *mbmi;
12345 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12346 (rd_stats_y.dist + rd_stats_uv.dist));
12347 rd_causal += RDCOST(x->rdmult, x->rddiv,
12348 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12349
12350 // Check non-causal mode
12351 mbmi->motion_mode = OBMC_CAUSAL;
12352 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12353
12354 av1_subtract_plane(x, bsize, 0);
12355 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12356 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12357 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12358 if (rd_stats_y.skip && rd_stats_uv.skip) {
12359 rd_stats_y.rate = rate_skip1;
12360 rd_stats_uv.rate = 0;
12361 rd_stats_y.dist = rd_stats_y.sse;
12362 rd_stats_uv.dist = rd_stats_uv.sse;
12363 skip_blk = 0;
12364 } else if (RDCOST(x->rdmult, x->rddiv,
12365 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12366 (rd_stats_y.dist + rd_stats_uv.dist)) >
12367 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12368 (rd_stats_y.sse + rd_stats_uv.sse))) {
12369 rd_stats_y.rate = rate_skip1;
12370 rd_stats_uv.rate = 0;
12371 rd_stats_y.dist = rd_stats_y.sse;
12372 rd_stats_uv.dist = rd_stats_uv.sse;
12373 skip_blk = 1;
12374 } else {
12375 rd_stats_y.rate += rate_skip0;
12376 skip_blk = 0;
12377 }
12378
12379 if (rd_causal >
12380 RDCOST(x->rdmult, x->rddiv,
12381 rd_stats_y.rate + rd_stats_uv.rate +
12382 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12383 (rd_stats_y.dist + rd_stats_uv.dist))) {
12384 x->skip = skip_blk;
12385 } else {
12386 *mbmi = backup_mbmi;
12387 x->skip = backup_skip;
12388 }
12389}
12390#endif
Yue Chencb60b182016-10-13 15:18:22 -070012391#endif // CONFIG_MOTION_VAR