blob: daee3c4cdcb828d20c1398593194bf889271874b [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"
Fergus Simpson4063a682017-02-28 16:52:22 -080057#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -080058#if CONFIG_PVQ || CONFIG_DAALA_DIST
59#include "av1/common/pvq.h"
Fergus Simpson4063a682017-02-28 16:52:22 -080060#endif // CONFIG_PVQ || CONFIG_DAALA_DIST
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;
Fergus Simpson4063a682017-02-28 16:52:22 -0800527#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800528 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}
Fergus Simpson4063a682017-02-28 16:52:22 -0800633#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800634
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 };
Fergus Simpson4063a682017-02-28 16:52:22 -0800887#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888
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;
Fergus Simpson4063a682017-02-28 16:52:22 -0800906#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907 }
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;
Fergus Simpson4063a682017-02-28 16:52:22 -0800924#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925}
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);
Fergus Simpson4063a682017-02-28 16:52:22 -0800981#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
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;
Fergus Simpson4063a682017-02-28 16:52:22 -0800989#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -0800990
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}
Fergus Simpson4063a682017-02-28 16:52:22 -08001038#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07001039
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
Jingning Hanab77e732017-02-28 15:20:59 -08001091#if !CONFIG_PVQ || CONFIG_VAR_TX
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];
Thomas Davies10525752017-03-06 12:10:46 +00001119
Fergus Simpson4063a682017-02-28 16:52:22 -08001120#endif // CONFIG_NEW_TOKENSET
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001121
Yaowu Xuf883b422016-08-30 14:01:10 -07001122#if CONFIG_AOM_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001123 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001124#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001125 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Fergus Simpson4063a682017-02-28 16:52:22 -08001126#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001127
1128#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1129 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001130 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001132 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133
1134 if (eob == 0) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001135#if CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001137 cost = av1_cost_bit(blockz_probs[pt], 0);
1138#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001139 cost = token_costs[0][0][pt][EOB_TOKEN];
Fergus Simpson4063a682017-02-28 16:52:22 -08001140#endif // CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001141 } else {
1142 if (use_fast_coef_costing) {
1143 int band_left = *band_count++;
1144
1145 // dc token
1146 int v = qcoeff[0];
1147 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001148 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001149#if CONFIG_NEW_TOKENSET
1150 cost += (*token_costs)[!prev_t][pt][prev_t];
1151#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001152 cost += (*token_costs)[0][pt][prev_t];
Thomas Davies10525752017-03-06 12:10:46 +00001153#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154
Yaowu Xuf883b422016-08-30 14:01:10 -07001155 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001156 ++token_costs;
1157
1158 // ac tokens
1159 for (c = 1; c < eob; c++) {
1160 const int rc = scan[c];
1161 int16_t t;
1162
1163 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001164 cost += av1_get_token_cost(v, &t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001165#if CONFIG_NEW_TOKENSET
1166 cost += (*token_costs)[!t][!prev_t][t];
1167#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001168 cost += (*token_costs)[!prev_t][!prev_t][t];
Thomas Davies10525752017-03-06 12:10:46 +00001169#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 prev_t = t;
1171 if (!--band_left) {
1172 band_left = *band_count++;
1173 ++token_costs;
1174 }
1175 }
1176
1177 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001178 if (band_left || CONFIG_NEW_TOKENSET)
1179 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180
1181 } else { // !use_fast_coef_costing
1182 int band_left = *band_count++;
1183
1184 // dc token
1185 int v = qcoeff[0];
1186 int16_t tok;
Thomas Davies10525752017-03-06 12:10:46 +00001187#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Thomas Davies10525752017-03-06 12:10:46 +00001189#endif
Alex Converseda3d94f2017-03-15 14:54:29 -07001190 cost = av1_get_token_cost(v, &tok, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001191#if CONFIG_NEW_TOKENSET
1192 cost += (*token_costs)[!tok][pt][tok];
1193#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001194 cost += (*token_costs)[0][pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001195#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001196
Yaowu Xuf883b422016-08-30 14:01:10 -07001197 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198 ++token_costs;
1199
Thomas Davies10525752017-03-06 12:10:46 +00001200#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001201 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001202#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001203
1204 // ac tokens
1205 for (c = 1; c < eob; c++) {
1206 const int rc = scan[c];
1207
1208 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001209 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210 pt = get_coef_context(nb, token_cache, c);
Thomas Davies10525752017-03-06 12:10:46 +00001211#if CONFIG_NEW_TOKENSET
1212 cost += (*token_costs)[!tok][pt][tok];
1213#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001214 cost += (*tok_cost_ptr)[pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001215#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001216 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217 if (!--band_left) {
1218 band_left = *band_count++;
1219 ++token_costs;
1220 }
Thomas Davies10525752017-03-06 12:10:46 +00001221#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001223#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224 }
1225
1226 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001227 if (band_left || CONFIG_NEW_TOKENSET) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001228 pt = get_coef_context(nb, token_cache, c);
1229 cost += (*token_costs)[0][pt][EOB_TOKEN];
1230 }
1231 }
1232 }
1233
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234 return cost;
1235}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001236#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237
Yaowu Xuf883b422016-08-30 14:01:10 -07001238static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1239 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001240 int64_t *out_dist, int64_t *out_sse) {
1241 MACROBLOCKD *const xd = &x->e_mbd;
1242 const struct macroblock_plane *const p = &x->plane[plane];
1243 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001244#if CONFIG_DAALA_DIST
1245 int qm = OD_HVS_QM;
1246 int use_activity_masking = 0;
1247#if CONFIG_PVQ
1248 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001249#endif // CONFIG_PVQ
1250#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001251
1252 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001253 // Transform domain distortion computation is more accurate as it does
1254 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001255 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001256 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001257 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001258 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1259 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001260#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001261 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Fergus Simpson4063a682017-02-28 16:52:22 -08001262#endif // CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001263#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001265 *out_dist =
1266 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1267 shift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001268#elif CONFIG_PVQ
1269 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1270 &this_sse) >>
1271 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001272#else
1273 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001274 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Yaowu Xuf883b422016-08-30 14:01:10 -07001275#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001276 *out_sse = this_sse >> shift;
1277 } else {
1278 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001279 const int bsw = block_size_wide[tx_bsize];
1280 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001281 const int src_stride = x->plane[plane].src.stride;
1282 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001283 // Scale the transform block index to pixel unit.
1284 const int src_idx = (blk_row * src_stride + blk_col)
1285 << tx_size_wide_log2[0];
1286 const int dst_idx = (blk_row * dst_stride + blk_col)
1287 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1289 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1290 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1291 const uint16_t eob = p->eobs[block];
1292
1293 unsigned int tmp;
1294
1295 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001296 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001297
Yushin Cho7a428ba2017-01-12 16:28:49 -08001298#if CONFIG_DAALA_DIST
1299 if (plane == 0) {
1300 if (bsw >= 8 && bsh >= 8)
1301 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1302 use_activity_masking, x->qindex);
1303 else
1304 tmp = 0;
1305 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001306#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001307 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1308
Yaowu Xuc27fc142016-08-22 16:08:15 -07001309 *out_sse = (int64_t)tmp * 16;
1310
1311 if (eob) {
1312 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001313#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001314 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1315 uint8_t *recon = (uint8_t *)recon16;
1316#else
1317 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001318#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319
Luc Trudeau005feb62017-02-22 13:34:01 -05001320 const PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001321
1322 INV_TXFM_PARAM inv_txfm_param;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001323 const int block_raster_idx =
1324 av1_block_index_to_raster_order(tx_size, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001325
Urvang Joshifeb925f2016-12-05 10:37:29 -08001326 inv_txfm_param.tx_type =
1327 get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001328 inv_txfm_param.tx_size = tx_size;
1329 inv_txfm_param.eob = eob;
1330 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1331
Yaowu Xuf883b422016-08-30 14:01:10 -07001332#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001333 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1334 recon = CONVERT_TO_BYTEPTR(recon);
1335 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001336 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337 NULL, 0, bsw, bsh, xd->bd);
1338 highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1339 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001340#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001341 {
Yushin Cho721868c2016-11-14 16:04:33 +09001342#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001343 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001344 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001345#else
1346 int i, j;
1347
1348 for (j = 0; j < bsh; j++)
1349 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08001350#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001351 inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
1352 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001353#if CONFIG_DAALA_DIST
1354 if (plane == 0) {
1355 if (bsw >= 8 && bsh >= 8)
1356 tmp = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, tx_size, qm,
1357 use_activity_masking, x->qindex);
1358 else
1359 tmp = 0;
1360 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001361#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001362 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001364 *out_dist = (int64_t)tmp * 16;
1365 }
1366}
1367
Yushin Cho77bba8d2016-11-04 16:36:56 -07001368#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001369static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001370 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001371 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1372 tx_size, args->scan_order->scan,
1373 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001374 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001375}
Fergus Simpson4063a682017-02-28 16:52:22 -08001376#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001377
1378static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1379 TX_SIZE tx_size) {
1380 uint64_t sse;
1381 switch (tx_size) {
Jingning Han2194eec2016-12-01 15:20:16 -08001382#if CONFIG_CB4X4
1383 case TX_2X2:
1384 sse = aom_sum_squares_2d_i16_c(diff, diff_stride, tx_size_wide[tx_size]);
1385 break;
Fergus Simpson4063a682017-02-28 16:52:22 -08001386#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001387 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001388 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1389 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390 break;
1391 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001392 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1393 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001394 break;
1395 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001396 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1397 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001398 break;
1399 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001400 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1401 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402 break;
1403 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001404 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1405 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001406 break;
1407 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001408 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1409 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001410 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001411 default:
1412 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001413 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001414 break;
1415 }
1416 return sse;
1417}
1418
1419static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1420 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1421 struct rdcost_block_args *args = arg;
1422 MACROBLOCK *const x = args->x;
1423 MACROBLOCKD *const xd = &x->e_mbd;
1424 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001425 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001426 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001427 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1428 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001429 RD_STATS this_rd_stats;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001430#if CONFIG_DAALA_DIST
1431 int qm = OD_HVS_QM;
1432 int use_activity_masking = 0;
1433#if CONFIG_PVQ
1434 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001435#endif // CONFIG_PVQ
1436#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001437
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001438 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001439
1440 if (args->exit_early) return;
1441
1442 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001443 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001444 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001445 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001446 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001447 &b_args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001448 if (args->cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001449 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1450 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001451 } else {
1452 // Note that the encode block_intra call above already calls
1453 // inv_txfm_add, so we can't just call dist_block here.
1454 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001455 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456 const struct macroblock_plane *const p = &x->plane[plane];
1457 const struct macroblockd_plane *const pd = &xd->plane[plane];
1458
1459 const int src_stride = p->src.stride;
1460 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001461 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462
Jingning Han81492262016-12-05 15:48:47 -08001463 const uint8_t *src =
1464 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1465 const uint8_t *dst =
1466 &pd->dst
1467 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1468 const int16_t *diff = &p->src_diff[(blk_row * diff_stride + blk_col)
1469 << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001470 unsigned int tmp;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001471
1472#if CONFIG_DAALA_DIST
1473 if (plane == 0) {
1474 const int bsw = block_size_wide[tx_bsize];
1475 const int bsh = block_size_high[tx_bsize];
1476
1477 if (bsw >= 8 && bsh >= 8) {
1478 const int16_t *pred = &pd->pred[(blk_row * diff_stride + blk_col)
1479 << tx_size_wide_log2[0]];
1480 int i, j;
1481 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1482
1483 for (j = 0; j < bsh; j++)
1484 for (i = 0; i < bsw; i++)
1485 pred8[j * bsw + i] = pred[j * diff_stride + i];
1486
1487 this_rd_stats.sse =
1488 av1_daala_dist(src, src_stride, pred8, bsw, tx_size, qm,
1489 use_activity_masking, x->qindex);
1490 } else {
1491 this_rd_stats.sse = 0;
1492 }
1493 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001494#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001495 {
1496 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497
Yaowu Xuf883b422016-08-30 14:01:10 -07001498#if CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001499 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1500 this_rd_stats.sse =
1501 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001502#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001503 }
1504
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001505 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001506
Yushin Cho7a428ba2017-01-12 16:28:49 -08001507#if CONFIG_DAALA_DIST
1508 if (plane == 0) {
1509 const int bsw = block_size_wide[tx_bsize];
1510 const int bsh = block_size_high[tx_bsize];
1511
1512 if (bsw >= 8 && bsh >= 8)
1513 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1514 use_activity_masking, x->qindex);
1515 else
1516 tmp = 0;
1517 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001518#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001519 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001520 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521 }
1522 } else {
1523// full forward transform and quantization
1524#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001525 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1526 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001527#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001528 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001529 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001530#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001531#if !CONFIG_PVQ
Yaowu Xufd873802016-12-12 09:37:54 -08001532 if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id]) {
1533 args->t_above[blk_col] = args->t_left[blk_row] =
1534 (av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx) > 0);
1535 } else {
1536 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1537 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1538 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001539#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001540 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1541 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542 }
1543
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001544 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545 if (args->this_rd + rd > args->best_rd) {
1546 args->exit_early = 1;
1547 return;
1548 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001549#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001550 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001551#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001552 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1553 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001554#endif // CONFIG_RD_DEBUG
Angie Chiang3963d632016-11-10 18:41:40 -08001555
Yushin Cho77bba8d2016-11-04 16:36:56 -07001556#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001557 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001558 args->t_above[blk_col] = !x->pvq_skip[plane];
1559 args->t_left[blk_row] = !x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001560#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001561 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1562 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001563
1564 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001565 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001566
Yushin Cho7a428ba2017-01-12 16:28:49 -08001567#if CONFIG_DAALA_DIST
1568 if (plane == 0 && tx_size <= TX_4X4) {
1569 rd = 0;
1570 x->rate_4x4[block] = this_rd_stats.rate;
1571 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001572#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001573
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001574#if !CONFIG_PVQ
1575 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1576#else
1577 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001578#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001579 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001580
Yaowu Xuc27fc142016-08-22 16:08:15 -07001581 args->this_rd += rd;
1582
1583 if (args->this_rd > args->best_rd) {
1584 args->exit_early = 1;
1585 return;
1586 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001587}
1588
Yushin Cho7a428ba2017-01-12 16:28:49 -08001589#if CONFIG_DAALA_DIST
1590static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
1591 int blk_col, BLOCK_SIZE plane_bsize,
1592 TX_SIZE tx_size, void *arg) {
1593 struct rdcost_block_args *args = arg;
1594 MACROBLOCK *const x = args->x;
1595 MACROBLOCKD *const xd = &x->e_mbd;
1596 // MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1597 // const AV1_COMMON *cm = &args->cpi->common;
1598 int64_t rd1, rd2, rd;
1599 RD_STATS this_rd_stats;
1600 int qm = OD_HVS_QM;
1601 int use_activity_masking = 0;
1602
1603#if CONFIG_PVQ
1604 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001605#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08001606 av1_init_rd_stats(&this_rd_stats);
1607
1608 if (args->exit_early) return;
1609
1610 {
1611 const struct macroblock_plane *const p = &x->plane[plane];
1612 const struct macroblockd_plane *const pd = &xd->plane[plane];
1613
1614 const int src_stride = p->src.stride;
1615 const int dst_stride = pd->dst.stride;
1616 const int diff_stride = block_size_wide[plane_bsize];
1617
1618 const uint8_t *src =
1619 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1620 const uint8_t *dst =
1621 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1622
1623 unsigned int tmp;
1624
1625 int qindex = x->qindex;
1626
1627 const int16_t *pred =
1628 &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
1629 int i, j;
1630 const int tx_blk_size = 1 << (tx_size + 2);
1631 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1632
1633 for (j = 0; j < tx_blk_size; j++)
1634 for (i = 0; i < tx_blk_size; i++)
1635 pred8[j * tx_blk_size + i] = pred[j * diff_stride + i];
1636
1637 this_rd_stats.sse =
1638 av1_daala_dist(src, src_stride, pred8, tx_blk_size, tx_size, qm,
1639 use_activity_masking, qindex);
1640
1641 this_rd_stats.sse = this_rd_stats.sse * 16;
1642
1643 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1644 use_activity_masking, qindex);
1645
1646 this_rd_stats.dist = (int64_t)tmp * 16;
1647 }
1648
1649 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
1650 if (args->this_rd + rd > args->best_rd) {
1651 args->exit_early = 1;
1652 return;
1653 }
1654
1655 {
1656 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
1657 // The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
1658 this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
1659 x->rate_4x4[block - max_blocks_wide] +
1660 x->rate_4x4[block - 1] + x->rate_4x4[block];
1661 }
1662 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1663 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
1664
1665 rd = AOMMIN(rd1, rd2);
1666
1667 args->rd_stats.dist += this_rd_stats.dist;
1668 args->rd_stats.sse += this_rd_stats.sse;
1669
1670 args->this_rd += rd;
1671
1672 if (args->this_rd > args->best_rd) {
1673 args->exit_early = 1;
1674 return;
1675 }
1676}
Fergus Simpson4063a682017-02-28 16:52:22 -08001677#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001678
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001679static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1680 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1681 BLOCK_SIZE bsize, TX_SIZE tx_size,
1682 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001683 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001684 MACROBLOCKD *const xd = &x->e_mbd;
1685 const struct macroblockd_plane *const pd = &xd->plane[plane];
1686 TX_TYPE tx_type;
1687 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001688 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001689 args.x = x;
1690 args.cpi = cpi;
1691 args.best_rd = ref_best_rd;
1692 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001693 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001694
1695 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1696
Yaowu Xuf883b422016-08-30 14:01:10 -07001697 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001698
1699 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001700 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001701 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001702
Yushin Cho7a428ba2017-01-12 16:28:49 -08001703#if CONFIG_DAALA_DIST
1704 if (plane == 0 &&
1705 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
1706 av1_foreach_8x8_transformed_block_in_plane(
1707 xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
1708 else
Fergus Simpson4063a682017-02-28 16:52:22 -08001709#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001710 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1711 &args);
1712
Yaowu Xuc27fc142016-08-22 16:08:15 -07001713 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001714 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001716 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001717 }
1718}
1719
1720#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001721void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1722 int64_t *distortion, int *skippable,
1723 int64_t *sse, int64_t ref_best_rd, int plane,
1724 BLOCK_SIZE bsize, TX_SIZE tx_size,
1725 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001726 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001727 MACROBLOCKD *const xd = &x->e_mbd;
1728 const struct macroblockd_plane *const pd = &xd->plane[plane];
1729 struct rdcost_block_args args;
1730 TX_TYPE tx_type;
1731
Yaowu Xuf883b422016-08-30 14:01:10 -07001732 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001733 args.cpi = cpi;
1734 args.x = x;
1735 args.best_rd = ref_best_rd;
1736 args.use_fast_coef_costing = use_fast_coef_casting;
1737
1738#if CONFIG_EXT_TX
1739 assert(tx_size < TX_SIZES);
1740#endif // CONFIG_EXT_TX
1741
1742 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1743
Yaowu Xuf883b422016-08-30 14:01:10 -07001744 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745
1746 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001747 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001748 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001749
1750 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1751 &args);
1752
1753 if (args.exit_early) {
1754 *rate = INT_MAX;
1755 *distortion = INT64_MAX;
1756 *sse = INT64_MAX;
1757 *skippable = 0;
1758 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001759 *distortion = args.rd_stats.dist;
1760 *rate = args.rd_stats.rate;
1761 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001762 *skippable = !x->plane[plane].eobs[0];
1763 }
1764}
1765#endif // CONFIG_SUPERTX
1766
Urvang Joshifeb925f2016-12-05 10:37:29 -08001767static int tx_size_cost(const AV1_COMP *const cpi, MACROBLOCK *x,
1768 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1769 const AV1_COMMON *const cm = &cpi->common;
1770 MACROBLOCKD *const xd = &x->e_mbd;
1771 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1772
1773 const int tx_select =
1774 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1775
1776 if (tx_select) {
1777 const int is_inter = is_inter_block(mbmi);
1778 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1779 : intra_tx_size_cat_lookup[bsize];
1780 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1781 const int depth = tx_size_to_depth(coded_tx_size);
1782 const int tx_size_ctx = get_tx_size_context(xd);
1783 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1784 return r_tx_size;
1785 } else {
1786 return 0;
1787 }
1788}
1789
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001790static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1791 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1792 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001793 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001794 MACROBLOCKD *const xd = &x->e_mbd;
1795 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1796 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001797 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001798 int s0, s1;
1799 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001800 const int tx_select =
1801 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001802
1803 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001804
1805 assert(skip_prob > 0);
1806#if CONFIG_EXT_TX && CONFIG_RECT_TX
1807 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1808#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1809
Yaowu Xuf883b422016-08-30 14:01:10 -07001810 s0 = av1_cost_bit(skip_prob, 0);
1811 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001812
1813 mbmi->tx_type = tx_type;
1814 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001815 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001817 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001818#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001819 if (get_ext_tx_types(tx_size, bs, is_inter, cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08001821 const int ext_tx_set =
1822 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001823 if (is_inter) {
1824 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001825 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001826 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1827 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 } else {
1829 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Urvang Joshifeb925f2016-12-05 10:37:29 -08001830 rd_stats->rate +=
1831 cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1832 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001833 }
1834 }
1835#else
1836 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1837 !FIXED_TX_TYPE) {
1838 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001839 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001840 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001841 rd_stats->rate +=
1842 cpi->intra_tx_type_costs[mbmi->tx_size]
1843 [intra_mode_to_tx_type_context[mbmi->mode]]
1844 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001845 }
1846 }
1847#endif // CONFIG_EXT_TX
1848
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001849 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001850 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001851 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001852 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001853 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1854 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001855 }
1856 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001857 rd = RDCOST(x->rdmult, x->rddiv,
1858 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 }
1860
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001861 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001863 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1864 !(rd_stats->skip))
1865 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866
1867 return rd;
1868}
1869
Urvang Joshi52648442016-10-13 17:27:51 -07001870static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001871 MACROBLOCK *x, RD_STATS *rd_stats,
1872 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001873#if CONFIG_PVQ
1874 od_rollback_buffer buf,
Fergus Simpson4063a682017-02-28 16:52:22 -08001875#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001876 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001877 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001878 MACROBLOCKD *const xd = &x->e_mbd;
1879 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880 int64_t rd = INT64_MAX;
1881 int n;
1882 int start_tx, end_tx;
1883 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1884 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1885 TX_SIZE best_tx_size = max_tx_size;
1886 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1887 const int is_inter = is_inter_block(mbmi);
1888#if CONFIG_EXT_TX
1889#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001890 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891#endif // CONFIG_RECT_TX
1892 int ext_tx_set;
1893#endif // CONFIG_EXT_TX
1894
1895 if (tx_select) {
1896#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001897 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001898#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1899 start_tx = max_tx_size;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001900 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001901 } else {
1902 const TX_SIZE chosen_tx_size =
1903 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1904#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001905 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1906 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001907#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1908 start_tx = chosen_tx_size;
1909 end_tx = chosen_tx_size;
1910 }
1911
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001912 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001913
1914 mbmi->tx_type = tx_type;
1915
1916#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001917 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001918 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001919 RD_STATS this_rd_stats;
Sarah Parkere68a3e42017-02-16 14:03:24 -08001920 ext_tx_set =
1921 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08001922 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
1923 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001924 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001925 rect_tx_size);
1926 best_tx_size = rect_tx_size;
1927 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001928 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001929 }
1930 }
1931#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1932
1933 last_rd = INT64_MAX;
1934 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001935 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001936#if CONFIG_EXT_TX && CONFIG_RECT_TX
1937 if (is_rect_tx(n)) break;
1938#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1939 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1940 if (!is_inter && x->use_default_intra_tx_type &&
1941 tx_type != get_default_tx_type(0, xd, 0, n))
1942 continue;
1943 if (is_inter && x->use_default_inter_tx_type &&
1944 tx_type != get_default_tx_type(0, xd, 0, n))
1945 continue;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001946 if (max_tx_size >= TX_32X32 && n == TX_4X4) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001947#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001948 ext_tx_set = get_ext_tx_set(n, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949 if (is_inter) {
1950 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1951 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1952 if (!do_tx_type_search(tx_type, prune)) continue;
1953 }
1954 } else {
1955 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1956 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1957 }
1958 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1959 }
1960#else // CONFIG_EXT_TX
1961 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1962 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1963 !do_tx_type_search(tx_type, prune))
1964 continue;
1965#endif // CONFIG_EXT_TX
1966
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001967 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001968#if CONFIG_PVQ
1969 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08001970#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 // Early termination in transform size search.
1972 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001973 (rd == INT64_MAX ||
1974 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975 (n < (int)max_tx_size && rd > last_rd)))
1976 break;
1977
1978 last_rd = rd;
1979 if (rd < best_rd) {
1980 best_tx_size = n;
1981 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001982 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001983 }
1984 }
1985 mbmi->tx_size = best_tx_size;
1986
1987 return best_rd;
1988}
1989
1990#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001991static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1992 MACROBLOCK *x, int *r, int64_t *d, int *s,
1993 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001994 RD_STATS rd_stats;
1995 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1996 max_txsize_lookup[bs]);
1997 *r = rd_stats.rate;
1998 *d = rd_stats.dist;
1999 *s = rd_stats.skip;
2000 *sse = rd_stats.sse;
2001 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002}
2003#endif // CONFIG_EXT_INTER
2004
Urvang Joshi52648442016-10-13 17:27:51 -07002005static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002006 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07002007 BLOCK_SIZE bs) {
2008 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002009 MACROBLOCKD *const xd = &x->e_mbd;
2010 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2011 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002012 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002013 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
2014 int s0 = av1_cost_bit(skip_prob, 0);
2015 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002016 const int is_inter = is_inter_block(mbmi);
2017 int prune = 0;
2018#if CONFIG_EXT_TX
2019 int ext_tx_set;
2020#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002021 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002022
2023 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002024#if CONFIG_VAR_TX
2025 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002026#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002027#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002028 ext_tx_set =
2029 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002030#endif // CONFIG_EXT_TX
2031
2032 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2033#if CONFIG_EXT_TX
2034 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2035#else
2036 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08002037#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002038#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002039 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2040 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002041 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002042#if CONFIG_PVQ
2043 od_rollback_buffer pre_buf, post_buf;
2044
2045 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2046 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002047#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002048
2049 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002050 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002051 if (is_inter) {
2052 if (x->use_default_inter_tx_type &&
2053 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2054 continue;
2055 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2056 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2057 if (!do_tx_type_search(tx_type, prune)) continue;
2058 }
2059 } else {
2060 if (x->use_default_intra_tx_type &&
2061 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2062 continue;
2063 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2064 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2065 }
2066 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2067 }
2068
2069 mbmi->tx_type = tx_type;
2070
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002071 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002072 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002073#if CONFIG_PVQ
2074 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002075#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002076 if (this_rd_stats.rate == INT_MAX) continue;
Sarah Parkere68a3e42017-02-16 14:03:24 -08002077 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter,
2078 cm->reduced_tx_set_used) > 1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002079 if (is_inter) {
2080 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002081 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002082 cpi->inter_tx_type_costs[ext_tx_set]
2083 [txsize_sqr_map[mbmi->tx_size]]
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002084 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002085 } else {
2086 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002087 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002088 cpi->intra_tx_type_costs[ext_tx_set]
2089 [txsize_sqr_map[mbmi->tx_size]]
2090 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002091 }
2092 }
2093
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002094 if (this_rd_stats.skip)
2095 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002096 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002097 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2098 this_rd_stats.dist);
2099 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2100 !this_rd_stats.skip)
2101 this_rd =
2102 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002103
2104 if (this_rd < best_rd) {
2105 best_rd = this_rd;
2106 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002107 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002108#if CONFIG_PVQ
2109 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002110#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002111 }
2112 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002113#if CONFIG_PVQ
2114 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002115#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002116 } else {
2117 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002118 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2119 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121#else // CONFIG_EXT_TX
2122 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2123 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002124 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002125 if (!is_inter && x->use_default_intra_tx_type &&
2126 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2127 continue;
2128 if (is_inter && x->use_default_inter_tx_type &&
2129 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2130 continue;
2131 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002132 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002134 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002135 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002136 this_rd_stats.rate +=
2137 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002138 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2139 !do_tx_type_search(tx_type, prune))
2140 continue;
2141 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002142 this_rd_stats.rate +=
2143 cpi->intra_tx_type_costs[mbmi->tx_size]
2144 [intra_mode_to_tx_type_context[mbmi->mode]]
2145 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002146 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002147 if (this_rd_stats.skip)
2148 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002149 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002150 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2151 this_rd_stats.dist);
2152 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2153 this_rd =
2154 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155
2156 if (this_rd < best_rd) {
2157 best_rd = this_rd;
2158 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002159 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002160 }
2161 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002162 } else {
2163 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002164 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2165 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002166 }
2167#endif // CONFIG_EXT_TX
2168 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002169}
2170
Urvang Joshi52648442016-10-13 17:27:51 -07002171static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002172 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002173 BLOCK_SIZE bs) {
2174 MACROBLOCKD *const xd = &x->e_mbd;
2175 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2176
2177 mbmi->tx_size = TX_4X4;
2178 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002179#if CONFIG_VAR_TX
2180 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002181#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002182
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002183 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2184 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002185}
2186
Urvang Joshi52648442016-10-13 17:27:51 -07002187static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002188 MACROBLOCK *x, RD_STATS *rd_stats,
2189 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002190 MACROBLOCKD *const xd = &x->e_mbd;
2191 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002192 int64_t rd = INT64_MAX;
2193 int64_t best_rd = INT64_MAX;
2194 TX_SIZE best_tx = max_txsize_lookup[bs];
2195 const int is_inter = is_inter_block(mbmi);
2196 TX_TYPE tx_type, best_tx_type = DCT_DCT;
2197 int prune = 0;
2198
Yushin Cho77bba8d2016-11-04 16:36:56 -07002199#if CONFIG_PVQ
2200 od_rollback_buffer buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08002201#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002202 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2203 // passing -1 in for tx_type indicates that all 1D
2204 // transforms should be considered for pruning
2205 prune = prune_tx_types(cpi, bs, x, xd, -1);
2206
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002207 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002208
Yushin Cho77bba8d2016-11-04 16:36:56 -07002209#if CONFIG_PVQ
2210 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002211#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002212 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002213 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002214#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07002215 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -08002216#endif // CONFIG_REF_MV
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002217 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08002218 tx_type,
2219#if CONFIG_PVQ
2220 buf,
Fergus Simpson4063a682017-02-28 16:52:22 -08002221#endif // CONFIG_PVQ
Yushin Cho55711e62016-11-10 18:49:24 -08002222 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002223 if (rd < best_rd) {
2224 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002225 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226 best_tx_type = tx_type;
2227 best_tx = mbmi->tx_size;
2228 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002229#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2230 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002231#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232 }
2233
2234 mbmi->tx_size = best_tx;
2235 mbmi->tx_type = best_tx_type;
2236
Jingning Hane67b38a2016-11-04 10:30:00 -07002237#if CONFIG_VAR_TX
2238 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002239#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002240
Yaowu Xuc27fc142016-08-22 16:08:15 -07002241#if !CONFIG_EXT_TX
2242 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002243#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002244#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002245 if (best_rd != INT64_MAX) {
Guillaume Martres930118c2016-12-06 20:26:22 -10002246 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx);
Yushin Cho05f540a2016-11-08 22:12:51 -08002247 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002248#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002249}
2250
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002251static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2252 RD_STATS *rd_stats, BLOCK_SIZE bs,
2253 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002254 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002255 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256
2257 assert(bs == xd->mi[0]->mbmi.sb_type);
2258
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002259 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002260 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002261 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002262 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002263 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002264 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002265 }
2266}
2267
2268static int conditional_skipintra(PREDICTION_MODE mode,
2269 PREDICTION_MODE best_intra_mode) {
2270 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2271 best_intra_mode != D135_PRED)
2272 return 1;
2273 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2274 best_intra_mode != D45_PRED)
2275 return 1;
2276 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2277 best_intra_mode != D45_PRED)
2278 return 1;
2279 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2280 best_intra_mode != D135_PRED)
2281 return 1;
2282 return 0;
2283}
2284
hui su308a6392017-01-12 14:49:57 -08002285// Model based RD estimation for luma intra blocks.
2286static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002287 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002288 MACROBLOCKD *const xd = &x->e_mbd;
2289 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2290 RD_STATS this_rd_stats;
2291 int row, col;
2292 int64_t temp_sse, this_rd;
2293 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2294 const int stepr = tx_size_high_unit[tx_size];
2295 const int stepc = tx_size_wide_unit[tx_size];
2296 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2297 const int max_blocks_high = max_block_high(xd, bsize, 0);
2298 mbmi->tx_size = tx_size;
2299 // Prediction.
2300 for (row = 0; row < max_blocks_high; row += stepr) {
2301 for (col = 0; col < max_blocks_wide; col += stepc) {
2302 struct macroblockd_plane *const pd = &xd->plane[0];
2303 uint8_t *dst =
2304 &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
David Barker839467f2017-01-19 11:06:15 +00002305 av1_predict_intra_block(xd, pd->width, pd->height,
2306 txsize_to_bsize[tx_size], mbmi->mode, dst,
2307 pd->dst.stride, dst, pd->dst.stride, col, row, 0);
hui su308a6392017-01-12 14:49:57 -08002308 }
2309 }
2310 // RD estimation.
2311 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2312 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002313#if CONFIG_EXT_INTRA
2314 if (av1_is_directional_mode(mbmi->mode, bsize)) {
2315 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
2316 mode_cost += write_uniform_cost(2 * max_angle_delta + 1,
2317 max_angle_delta + mbmi->angle_delta[0]);
2318 }
2319#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002320#if CONFIG_FILTER_INTRA
2321 if (mbmi->mode == DC_PRED) {
2322 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2323 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2324 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2325 mode_cost += (av1_cost_bit(prob, 1) +
2326 write_uniform_cost(FILTER_INTRA_MODES, mode));
2327 } else {
2328 mode_cost += av1_cost_bit(prob, 0);
2329 }
2330 }
2331#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002332 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2333 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002334 return this_rd;
2335}
2336
Urvang Joshib100db72016-10-12 16:28:56 -07002337#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002338// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2339// new_height'. Extra rows and columns are filled in by copying last valid
2340// row/column.
2341static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2342 int orig_height, int new_width,
2343 int new_height) {
2344 int j;
2345 assert(new_width >= orig_width);
2346 assert(new_height >= orig_height);
2347 if (new_width == orig_width && new_height == orig_height) return;
2348
2349 for (j = orig_height - 1; j >= 0; --j) {
2350 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2351 // Copy last column to extra columns.
2352 memset(color_map + j * new_width + orig_width,
2353 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2354 }
2355 // Copy last row to extra rows.
2356 for (j = orig_height; j < new_height; ++j) {
2357 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2358 new_width);
2359 }
2360}
2361
hui sude0c70a2017-01-09 17:12:17 -08002362static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2363 BLOCK_SIZE bsize, int palette_ctx,
2364 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2365 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002366 int64_t *best_rd, int64_t *best_model_rd,
2367 int *rate, int *rate_tokenonly,
2368 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002369 int rate_overhead = 0;
2370 MACROBLOCKD *const xd = &x->e_mbd;
2371 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002372 MB_MODE_INFO *const mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002373 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002374 const int src_stride = x->plane[0].src.stride;
2375 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002376 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002377 int block_width, block_height, rows, cols;
2378 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2379 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002380
2381 assert(cpi->common.allow_screen_content_tools);
2382
Yaowu Xuf883b422016-08-30 14:01:10 -07002383#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002384 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002385 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2386 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002387 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002388#endif // CONFIG_AOM_HIGHBITDEPTH
2389 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002390#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002391 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002392#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002393
2394 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002395 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002396 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002397 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002398 float *const data = x->palette_buffer->kmeans_data_buf;
2399 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002400 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002401 RD_STATS tokenonly_rd_stats;
2402 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002403 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07002404#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002405 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2406 if (cpi->common.use_highbitdepth)
2407 lb = ub = src16[0];
2408 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002409#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002410 lb = ub = src[0];
2411
Yaowu Xuf883b422016-08-30 14:01:10 -07002412#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413 if (cpi->common.use_highbitdepth) {
2414 for (r = 0; r < rows; ++r) {
2415 for (c = 0; c < cols; ++c) {
2416 val = src16[r * src_stride + c];
2417 data[r * cols + c] = val;
2418 if (val < lb)
2419 lb = val;
2420 else if (val > ub)
2421 ub = val;
2422 }
2423 }
2424 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002425#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002426 for (r = 0; r < rows; ++r) {
2427 for (c = 0; c < cols; ++c) {
2428 val = src[r * src_stride + c];
2429 data[r * cols + c] = val;
2430 if (val < lb)
2431 lb = val;
2432 else if (val > ub)
2433 ub = val;
2434 }
2435 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002436#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002437 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002438#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002439
2440 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002441#if CONFIG_FILTER_INTRA
2442 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2443#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002444
2445 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2446
2447 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2448 --n) {
2449 for (i = 0; i < n; ++i)
2450 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07002451 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
2452 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002453
Yaowu Xuf883b422016-08-30 14:01:10 -07002454#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002455 if (cpi->common.use_highbitdepth)
2456 for (i = 0; i < k; ++i)
2457 pmi->palette_colors[i] =
2458 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2459 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002460#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002461 for (i = 0; i < k; ++i)
2462 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2463 pmi->palette_size[0] = k;
2464
Yaowu Xuf883b422016-08-30 14:01:10 -07002465 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002466 extend_palette_color_map(color_map, cols, rows, block_width,
2467 block_height);
hui su78c611a2017-01-13 17:06:04 -08002468 palette_mode_cost =
2469 dc_mode_cost + cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08002470 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002472 av1_cost_bit(
2473 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002474 1);
2475 for (i = 0; i < rows; ++i) {
2476 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002477 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002478 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002479 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002480 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002481 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2482 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002483 }
2484 }
hui su78c611a2017-01-13 17:06:04 -08002485 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2486 if (*best_model_rd != INT64_MAX &&
2487 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2488 continue;
2489 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2490 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2491 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2492 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002493 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002494 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002495 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002496 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002497 if (this_rd < *best_rd) {
2498 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002499 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002500 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002501 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002502 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002503 if (rate) *rate = this_rate;
2504 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2505 if (distortion) *distortion = tokenonly_rd_stats.dist;
2506 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002507 }
2508 }
2509 }
hui sude0c70a2017-01-09 17:12:17 -08002510
2511 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2512 memcpy(color_map, best_palette_color_map,
2513 rows * cols * sizeof(best_palette_color_map[0]));
2514 }
2515 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002516 return rate_overhead;
2517}
Urvang Joshib100db72016-10-12 16:28:56 -07002518#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002519
Urvang Joshifeb925f2016-12-05 10:37:29 -08002520// Wrappers to make function pointers usable.
2521static void inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2522 int stride, int eob, TX_TYPE tx_type,
2523 int lossless) {
2524 (void)lossless;
2525 av1_inv_txfm_add_4x8(input, dest, stride, eob, tx_type);
2526}
2527
2528static void inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2529 int stride, int eob, TX_TYPE tx_type,
2530 int lossless) {
2531 (void)lossless;
2532 av1_inv_txfm_add_8x4(input, dest, stride, eob, tx_type);
2533}
2534
2535typedef void (*inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int, int,
2536 TX_TYPE, int);
2537#if CONFIG_AOM_HIGHBITDEPTH
2538
2539void highbd_inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2540 int stride, int eob, int bd,
2541 TX_TYPE tx_type, int is_lossless) {
2542 (void)is_lossless;
2543 av1_highbd_inv_txfm_add_4x8(input, dest, stride, eob, bd, tx_type);
2544}
2545
2546void highbd_inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2547 int stride, int eob, int bd,
2548 TX_TYPE tx_type, int is_lossless) {
2549 (void)is_lossless;
2550 av1_highbd_inv_txfm_add_8x4(input, dest, stride, eob, bd, tx_type);
2551}
2552
2553typedef void (*highbd_inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int,
2554 int, int, TX_TYPE, int);
2555#endif // CONFIG_AOM_HIGHBITDEPTH
2556
2557static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002558 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2559 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2560 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002561 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002562 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002563 PREDICTION_MODE mode;
2564 MACROBLOCKD *const xd = &x->e_mbd;
2565 int64_t best_rd = rd_thresh;
2566 struct macroblock_plane *p = &x->plane[0];
2567 struct macroblockd_plane *pd = &xd->plane[0];
2568 const int src_stride = p->src.stride;
2569 const int dst_stride = pd->dst.stride;
2570 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002571 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002572#if CONFIG_CB4X4
2573 // TODO(jingning): This is a temporal change. The whole function should be
2574 // out when cb4x4 is enabled.
2575 ENTROPY_CONTEXT ta[4], tempa[4];
2576 ENTROPY_CONTEXT tl[4], templ[4];
2577#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578 ENTROPY_CONTEXT ta[2], tempa[2];
2579 ENTROPY_CONTEXT tl[2], templ[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08002580#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002581
2582 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2583 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2584 const int tx_width_unit = tx_size_wide_unit[tx_size];
2585 const int tx_height_unit = tx_size_high_unit[tx_size];
2586 const int pred_block_width = block_size_wide[bsize];
2587 const int pred_block_height = block_size_high[bsize];
2588 const int tx_width = tx_size_wide[tx_size];
2589 const int tx_height = tx_size_high[tx_size];
2590 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2591 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002592 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002593 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002594 uint8_t best_dst[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002595 inv_txfm_func_ptr inv_txfm_func =
2596 (tx_size == TX_4X4) ? av1_inv_txfm_add_4x4
2597 : (tx_size == TX_4X8) ? inv_txfm_add_4x8_wrapper
2598 : inv_txfm_add_8x4_wrapper;
Yaowu Xuf883b422016-08-30 14:01:10 -07002599#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002600 uint16_t best_dst16[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002601 highbd_inv_txfm_func_ptr highbd_inv_txfm_func =
2602 (tx_size == TX_4X4)
2603 ? av1_highbd_inv_txfm_add_4x4
2604 : (tx_size == TX_4X8) ? highbd_inv_txfm_add_4x8_wrapper
2605 : highbd_inv_txfm_add_8x4_wrapper;
Fergus Simpson4063a682017-02-28 16:52:22 -08002606#endif // CONFIG_AOM_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002607 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2608#if CONFIG_EXT_TX && CONFIG_RECT_TX
2609 const int sub_bsize = bsize;
2610#else
2611 const int sub_bsize = BLOCK_4X4;
2612#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002613
Yushin Cho77bba8d2016-11-04 16:36:56 -07002614#if CONFIG_PVQ
2615 od_rollback_buffer pre_buf, post_buf;
2616 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2617 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002618#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002619
Urvang Joshifeb925f2016-12-05 10:37:29 -08002620 assert(bsize < BLOCK_8X8);
2621 assert(tx_width < 8 || tx_height < 8);
2622#if CONFIG_EXT_TX && CONFIG_RECT_TX
2623 assert(tx_width == pred_block_width && tx_height == pred_block_height);
2624#else
2625 assert(tx_width == 4 && tx_height == 4);
2626#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2627
2628 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2629 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2630
2631 xd->mi[0]->mbmi.tx_size = tx_size;
2632
Urvang Joshib100db72016-10-12 16:28:56 -07002633#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002635#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002636
Yaowu Xuf883b422016-08-30 14:01:10 -07002637#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002638 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2639 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2640 int64_t this_rd;
2641 int ratey = 0;
2642 int64_t distortion = 0;
2643 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002644 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002645
Urvang Joshifeb925f2016-12-05 10:37:29 -08002646 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2647 (1 << mode)))
2648 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002649
2650 // Only do the oblique modes if the best so far is
2651 // one of the neighboring directional modes
2652 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2653 if (conditional_skipintra(mode, *best_mode)) continue;
2654 }
2655
Urvang Joshifeb925f2016-12-05 10:37:29 -08002656 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2657 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002658
Urvang Joshifeb925f2016-12-05 10:37:29 -08002659 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2660 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2661 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2662 const int block =
2663 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002664 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2665 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002666 int16_t *const src_diff = av1_raster_block_offset_int16(
2667 BLOCK_8X8, block_raster_idx, p->src_diff);
2668 int skip;
2669 assert(block < 4);
2670 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2671 idx == 0 && idy == 0));
2672 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2673 block == 0 || block == 2));
2674 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002675 av1_predict_intra_block(
2676 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2677 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002678 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2679 src_stride, dst, dst_stride, xd->bd);
2680 if (is_lossless) {
2681 TX_TYPE tx_type =
2682 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2683 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002684 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002685 combine_entropy_contexts(tempa[idx], templ[idy]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002686#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002687 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002688 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002689#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002690 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002691 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002692#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002693 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002694 scan_order->scan, scan_order->neighbors,
2695 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002696 skip = (p->eobs[block] == 0);
2697 can_skip &= skip;
2698 tempa[idx] = !skip;
2699 templ[idy] = !skip;
2700#if CONFIG_EXT_TX
2701 if (tx_size == TX_8X4) {
2702 tempa[idx + 1] = tempa[idx];
2703 } else if (tx_size == TX_4X8) {
2704 templ[idy + 1] = templ[idy];
2705 }
2706#endif // CONFIG_EXT_TX
2707
Yaowu Xuc27fc142016-08-22 16:08:15 -07002708 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2709 goto next_highbd;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002710 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2711 dst_stride, p->eobs[block], xd->bd, DCT_DCT,
2712 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002713 } else {
2714 int64_t dist;
2715 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002716 TX_TYPE tx_type =
2717 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2718 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002719 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002720 combine_entropy_contexts(tempa[idx], templ[idy]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002721#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002722 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002723 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002724#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002725 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002726 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002727#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002728 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
2729 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002730 scan_order->scan, scan_order->neighbors,
2731 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002732 skip = (p->eobs[block] == 0);
2733 can_skip &= skip;
2734 tempa[idx] = !skip;
2735 templ[idy] = !skip;
2736#if CONFIG_EXT_TX
2737 if (tx_size == TX_8X4) {
2738 tempa[idx + 1] = tempa[idx];
2739 } else if (tx_size == TX_4X8) {
2740 templ[idy + 1] = templ[idy];
2741 }
2742#endif // CONFIG_EXT_TX
2743 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2744 dst_stride, p->eobs[block], xd->bd, tx_type,
2745 0);
2746 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747 dist = (int64_t)tmp << 4;
2748 distortion += dist;
2749 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2750 goto next_highbd;
2751 }
2752 }
2753 }
2754
2755 rate += ratey;
2756 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2757
2758 if (this_rd < best_rd) {
2759 *bestrate = rate;
2760 *bestratey = ratey;
2761 *bestdistortion = distortion;
2762 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002763 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002764 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002765 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2766 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
2767 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002768 memcpy(best_dst16 + idy * 8,
2769 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002770 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002771 }
2772 }
2773 next_highbd : {}
2774 }
2775
2776 if (best_rd >= rd_thresh) return best_rd;
2777
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002778 if (y_skip) *y_skip &= best_can_skip;
2779
Urvang Joshifeb925f2016-12-05 10:37:29 -08002780 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002781 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002782 best_dst16 + idy * 8,
2783 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002784 }
2785
2786 return best_rd;
2787 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002788#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002789
Yushin Cho77bba8d2016-11-04 16:36:56 -07002790#if CONFIG_PVQ
2791 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002792#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002793
Yaowu Xuc27fc142016-08-22 16:08:15 -07002794 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2795 int64_t this_rd;
2796 int ratey = 0;
2797 int64_t distortion = 0;
2798 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002799 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002800
Urvang Joshifeb925f2016-12-05 10:37:29 -08002801 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2802 (1 << mode))) {
2803 continue;
2804 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002805
2806 // Only do the oblique modes if the best so far is
2807 // one of the neighboring directional modes
2808 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2809 if (conditional_skipintra(mode, *best_mode)) continue;
2810 }
2811
Urvang Joshifeb925f2016-12-05 10:37:29 -08002812 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2813 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002814
Urvang Joshifeb925f2016-12-05 10:37:29 -08002815 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2816 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2817 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2818 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002819 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2820 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002821#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002822 int16_t *const src_diff = av1_raster_block_offset_int16(
2823 BLOCK_8X8, block_raster_idx, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002824#else
Urvang Joshifeb925f2016-12-05 10:37:29 -08002825 int i, j;
Fergus Simpson4063a682017-02-28 16:52:22 -08002826#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002827 int skip;
2828 assert(block < 4);
2829 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2830 idx == 0 && idy == 0));
2831 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2832 block == 0 || block == 2));
2833 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002834 av1_predict_intra_block(xd, pd->width, pd->height,
2835 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2836 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002837#if CONFIG_CB4X4
2838 2 * (col + idx), 2 * (row + idy),
2839#else
2840 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002841#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002842 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002843#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002844 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2845 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002846#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847
Urvang Joshifeb925f2016-12-05 10:37:29 -08002848 if (is_lossless) {
2849 TX_TYPE tx_type =
2850 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2851 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002853 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002854#if CONFIG_CB4X4
2855 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002856#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002857#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002858#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002859 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002860 tx_size, coeff_ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002862 av1_xform_quant(cm, x, 0, block,
2863#if CONFIG_CB4X4
2864 2 * (row + idy), 2 * (col + idx),
2865#else
2866 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002867#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002868 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002869#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002870 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002871 scan_order->scan, scan_order->neighbors,
2872 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002873 skip = (p->eobs[block] == 0);
2874 can_skip &= skip;
2875 tempa[idx] = !skip;
2876 templ[idy] = !skip;
2877#if CONFIG_EXT_TX
2878 if (tx_size == TX_8X4) {
2879 tempa[idx + 1] = tempa[idx];
2880 } else if (tx_size == TX_4X8) {
2881 templ[idy + 1] = templ[idy];
2882 }
2883#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002884#else
Yushin Cho900243b2017-01-03 11:02:38 -08002885 (void)scan_order;
2886
2887 av1_xform_quant(cm, x, 0, block,
2888#if CONFIG_CB4X4
2889 2 * (row + idy), 2 * (col + idx),
2890#else
2891 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002892#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002893 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yushin Cho900243b2017-01-03 11:02:38 -08002894
2895 ratey += x->rate;
2896 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002897 tempa[idx] = !skip;
2898 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08002899 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002900#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002901 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2902 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002903#if CONFIG_PVQ
2904 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002905 for (j = 0; j < tx_height; j++)
2906 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08002907#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002908 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
2909 p->eobs[block], DCT_DCT, 1);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002910#if CONFIG_PVQ
2911 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002912#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002913 } else {
2914 int64_t dist;
2915 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002916 TX_TYPE tx_type =
2917 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2918 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002919 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002920 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002921#if CONFIG_CB4X4
2922 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002923#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002924#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002925#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002926 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002927 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002928#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002929 av1_xform_quant(cm, x, 0, block,
2930#if CONFIG_CB4X4
2931 2 * (row + idy), 2 * (col + idx),
2932#else
2933 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002934#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002935 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002936#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002937 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
2938 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002939 scan_order->scan, scan_order->neighbors,
2940 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002941 skip = (p->eobs[block] == 0);
2942 can_skip &= skip;
2943 tempa[idx] = !skip;
2944 templ[idy] = !skip;
2945#if CONFIG_EXT_TX
2946 if (tx_size == TX_8X4) {
2947 tempa[idx + 1] = tempa[idx];
2948 } else if (tx_size == TX_4X8) {
2949 templ[idy + 1] = templ[idy];
2950 }
2951#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002952#else
Yushin Cho900243b2017-01-03 11:02:38 -08002953 (void)scan_order;
2954
2955 av1_xform_quant(cm, x, 0, block,
2956#if CONFIG_CB4X4
2957 2 * (row + idy), 2 * (col + idx),
2958#else
2959 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002960#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002961 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yushin Cho900243b2017-01-03 11:02:38 -08002962 ratey += x->rate;
2963 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002964 tempa[idx] = !skip;
2965 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08002966 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002967#endif // !CONFIG_PVQ
Yushin Chob27a17f2016-12-23 14:33:02 -08002968#if CONFIG_PVQ
2969 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002970 for (j = 0; j < tx_height; j++)
2971 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08002972#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002973 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
2974 p->eobs[block], tx_type, 0);
Yushin Chob27a17f2016-12-23 14:33:02 -08002975#if CONFIG_PVQ
2976 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002977#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002978 // No need for av1_block_error2_c because the ssz is unused
Urvang Joshifeb925f2016-12-05 10:37:29 -08002979 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002980 dist = (int64_t)tmp << 4;
2981 distortion += dist;
2982 // To use the pixel domain distortion, the step below needs to be
2983 // put behind the inv txfm. Compared to calculating the distortion
2984 // in the frequency domain, the overhead of encoding effort is low.
2985 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2986 goto next;
2987 }
2988 }
2989 }
2990
2991 rate += ratey;
2992 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2993
2994 if (this_rd < best_rd) {
2995 *bestrate = rate;
2996 *bestratey = ratey;
2997 *bestdistortion = distortion;
2998 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002999 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003000 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003001 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3002 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003003#if CONFIG_PVQ
3004 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003005#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003006 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003007 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003008 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003009 }
3010 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003011#if CONFIG_PVQ
3012 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003013#endif // CONFIG_PVQ
3014 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003015
3016 if (best_rd >= rd_thresh) return best_rd;
3017
Yushin Cho77bba8d2016-11-04 16:36:56 -07003018#if CONFIG_PVQ
3019 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003020#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003021
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003022 if (y_skip) *y_skip &= best_can_skip;
3023
Urvang Joshifeb925f2016-12-05 10:37:29 -08003024 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003025 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003026 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003027
3028 return best_rd;
3029}
3030
Urvang Joshi52648442016-10-13 17:27:51 -07003031static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3032 MACROBLOCK *mb, int *rate,
3033 int *rate_y, int64_t *distortion,
3034 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003035 const MACROBLOCKD *const xd = &mb->e_mbd;
3036 MODE_INFO *const mic = xd->mi[0];
3037 const MODE_INFO *above_mi = xd->above_mi;
3038 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003039 MB_MODE_INFO *const mbmi = &mic->mbmi;
3040 const BLOCK_SIZE bsize = mbmi->sb_type;
3041 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3042 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043 int idx, idy;
3044 int cost = 0;
3045 int64_t total_distortion = 0;
3046 int tot_rate_y = 0;
3047 int64_t total_rd = 0;
3048 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003049 const int is_lossless = xd->lossless[mbmi->segment_id];
3050#if CONFIG_EXT_TX && CONFIG_RECT_TX
3051 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3052#else
3053 const TX_SIZE tx_size = TX_4X4;
3054#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055
3056#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003057#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003058 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003059#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003060#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003061#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003062 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003063#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003064
3065 // TODO(any): Add search of the tx_type to improve rd performance at the
3066 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003067 mbmi->tx_type = DCT_DCT;
3068 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003070 if (y_skip) *y_skip = 1;
3071
Urvang Joshifeb925f2016-12-05 10:37:29 -08003072 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3073 // 8x8 coding block.
3074 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3075 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003076 PREDICTION_MODE best_mode = DC_PRED;
3077 int r = INT_MAX, ry = INT_MAX;
3078 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003079 int j;
3080 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003082 const PREDICTION_MODE A =
3083 av1_above_block_mode(mic, above_mi, pred_block_idx);
3084 const PREDICTION_MODE L =
3085 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003086
3087 bmode_costs = cpi->y_mode_costs[A][L];
3088 }
3089
Urvang Joshifeb925f2016-12-05 10:37:29 -08003090 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003091 cpi, mb, idy, idx, &best_mode, bmode_costs,
3092 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003093 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003094#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003095 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003096#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003097 total_rd += this_rd;
3098 cost += r;
3099 total_distortion += d;
3100 tot_rate_y += ry;
3101
Urvang Joshifeb925f2016-12-05 10:37:29 -08003102 mic->bmi[pred_block_idx].as_mode = best_mode;
3103 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3104 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3105 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3106 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003107
3108 if (total_rd >= best_rd) return INT64_MAX;
3109 }
3110 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003111 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003112
Yushin Cho7a428ba2017-01-12 16:28:49 -08003113#if CONFIG_DAALA_DIST
3114 {
3115 const struct macroblock_plane *p = &mb->plane[0];
3116 const struct macroblockd_plane *pd = &xd->plane[0];
3117 const int src_stride = p->src.stride;
3118 const int dst_stride = pd->dst.stride;
3119 uint8_t *src = p->src.buf;
3120 uint8_t *dst = pd->dst.buf;
3121 int use_activity_masking = 0;
3122 int qm = OD_HVS_QM;
3123
3124#if CONFIG_PVQ
3125 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003126#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003127 // Daala-defined distortion computed for the block of 8x8 pixels
3128 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, TX_8X8,
3129 qm, use_activity_masking, mb->qindex)
3130 << 4;
3131 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003132#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003133 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003134 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003135 int rate_tx_type = 0;
3136#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003137 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3138 1) {
3139 const int eset =
3140 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003141 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3142 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143 }
3144#else
clang-format67948d32016-09-07 22:40:40 -07003145 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003146 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3147 [intra_mode_to_tx_type_context[mbmi->mode]]
3148 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003149#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003150 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003151 cost += rate_tx_type;
3152 tot_rate_y += rate_tx_type;
3153 }
3154
3155 *rate = cost;
3156 *rate_y = tot_rate_y;
3157 *distortion = total_distortion;
3158
3159 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3160}
3161
hui su5db97432016-10-14 16:10:14 -07003162#if CONFIG_FILTER_INTRA
3163// Return 1 if an filter intra mode is selected; return 0 otherwise.
3164static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3165 int *rate, int *rate_tokenonly,
3166 int64_t *distortion, int *skippable,
3167 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003168 int64_t *best_rd, int64_t *best_model_rd,
3169 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003170 MACROBLOCKD *const xd = &x->e_mbd;
3171 MODE_INFO *const mic = xd->mi[0];
3172 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003173 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003174 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003175 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003176 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 TX_TYPE best_tx_type;
3178
hui su5db97432016-10-14 16:10:14 -07003179 av1_zero(filter_intra_mode_info);
3180 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003181 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003182#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003183 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003184#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003185
3186 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003187 int this_rate;
3188 int64_t this_rd, this_model_rd;
3189 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003190 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003191 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003192 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3193 if (*best_model_rd != INT64_MAX &&
3194 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3195 continue;
3196 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003197 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3198 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003199 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003200 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003202 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203
3204 if (this_rd < *best_rd) {
3205 *best_rd = this_rd;
3206 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003207 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003208 best_tx_type = mic->mbmi.tx_type;
3209 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003210 *rate_tokenonly = tokenonly_rd_stats.rate;
3211 *distortion = tokenonly_rd_stats.dist;
3212 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003213 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003214 }
3215 }
3216
hui su5db97432016-10-14 16:10:14 -07003217 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003218 mbmi->mode = DC_PRED;
3219 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003220 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3221 filter_intra_mode_info.use_filter_intra_mode[0];
3222 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3223 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003224 mbmi->tx_type = best_tx_type;
3225 return 1;
3226 } else {
3227 return 0;
3228 }
3229}
hui su5db97432016-10-14 16:10:14 -07003230#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003231
hui su5db97432016-10-14 16:10:14 -07003232#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003233// Run RD calculation with given luma intra prediction angle., and return
3234// the RD cost. Update the best mode info. if the RD cost is the best so far.
3235static int64_t calc_rd_given_intra_angle(
3236 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3237 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3238 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3239 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003240#if CONFIG_INTRA_INTERP
3241 INTRA_FILTER *best_filter,
3242#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003243 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003244 int this_rate;
3245 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003246 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003247 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003248
hui su45dc5972016-12-08 17:42:50 -08003249 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003250 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3251 if (*best_model_rd != INT64_MAX &&
3252 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3253 return INT64_MAX;
3254 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003255 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3256 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3257
3258 this_rate = tokenonly_rd_stats.rate + mode_cost +
3259 write_uniform_cost(2 * max_angle_delta + 1,
3260 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003261 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262
3263 if (this_rd < *best_rd) {
3264 *best_rd = this_rd;
3265 *best_angle_delta = mbmi->angle_delta[0];
3266 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003267#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003268 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003269#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003270 *best_tx_type = mbmi->tx_type;
3271 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003272 rd_stats->rate = tokenonly_rd_stats.rate;
3273 rd_stats->dist = tokenonly_rd_stats.dist;
3274 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003275 }
hui su45dc5972016-12-08 17:42:50 -08003276 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003277}
3278
hui su45dc5972016-12-08 17:42:50 -08003279// With given luma directional intra prediction mode, pick the best angle delta
3280// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003281static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003282 int *rate, RD_STATS *rd_stats,
3283 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003284 int64_t best_rd,
3285 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003286 MACROBLOCKD *const xd = &x->e_mbd;
3287 MODE_INFO *const mic = xd->mi[0];
3288 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su45dc5972016-12-08 17:42:50 -08003289 int i, angle_delta, best_angle_delta = 0;
3290 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
3291 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003292#if CONFIG_INTRA_INTERP
3293 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003294 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003295 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003296#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003297 int64_t this_rd, best_rd_in, rd_cost[16];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003298 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3299 TX_TYPE best_tx_type = mbmi->tx_type;
3300
hui su45dc5972016-12-08 17:42:50 -08003301 for (i = 0; i < 2 * (max_angle_delta + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302
hui su45dc5972016-12-08 17:42:50 -08003303 for (angle_delta = 0; angle_delta <= max_angle_delta; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003304#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003305 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3306 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3307 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003308#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003309 for (i = 0; i < 2; ++i) {
3310 best_rd_in = (best_rd == INT64_MAX)
3311 ? INT64_MAX
3312 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3313 this_rd = calc_rd_given_intra_angle(
3314 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003315#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003316 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003317#else
hui su45dc5972016-12-08 17:42:50 -08003318 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003319#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003320 best_rd_in, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3321 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003322#if CONFIG_INTRA_INTERP
3323 &best_filter,
3324#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003325 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003326 rd_cost[2 * angle_delta + i] = this_rd;
3327 if (first_try && this_rd == INT64_MAX) return best_rd;
3328 first_try = 0;
3329 if (angle_delta == 0) {
3330 rd_cost[1] = this_rd;
3331 break;
3332 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003333 }
hui su45dc5972016-12-08 17:42:50 -08003334#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003335 }
hui su45dc5972016-12-08 17:42:50 -08003336#endif // CONFIG_INTRA_INTERP
3337 }
3338
3339 assert(best_rd != INT64_MAX);
3340 for (angle_delta = 1; angle_delta <= max_angle_delta; angle_delta += 2) {
3341 int64_t rd_thresh;
3342#if CONFIG_INTRA_INTERP
3343 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3344 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3345 mic->mbmi.intra_filter = filter;
3346#endif // CONFIG_INTRA_INTERP
3347 for (i = 0; i < 2; ++i) {
3348 int skip_search = 0;
3349 rd_thresh = best_rd + (best_rd >> 5);
3350 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3351 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3352 skip_search = 1;
3353 if (!skip_search) {
3354 this_rd = calc_rd_given_intra_angle(
3355 cpi, x, bsize,
3356#if CONFIG_INTRA_INTERP
3357 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3358#else
3359 mode_cost,
3360#endif // CONFIG_INTRA_INTERP
3361 best_rd, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3362 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3363#if CONFIG_INTRA_INTERP
3364 &best_filter,
3365#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003366 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003367 }
3368 }
3369#if CONFIG_INTRA_INTERP
3370 }
3371#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003372 }
3373
hui sueda3d762016-12-06 16:58:23 -08003374#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003375 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
3376 p_angle = mode_to_angle_map[mbmi->mode] +
3377 best_angle_delta * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003378 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003379 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3380 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003381 this_rd = calc_rd_given_intra_angle(
3382 cpi, x, bsize,
3383 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3384 best_rd, best_angle_delta, max_angle_delta, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003385 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003386 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003387 }
3388 }
3389 }
hui sueda3d762016-12-06 16:58:23 -08003390#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003391
3392 mbmi->tx_size = best_tx_size;
3393 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003394#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003395 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003396#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003397 mbmi->tx_type = best_tx_type;
3398 return best_rd;
3399}
3400
3401// Indices are sign, integer, and fractional part of the gradient value
3402static const uint8_t gradient_to_angle_bin[2][7][16] = {
3403 {
3404 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3405 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3406 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3407 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3408 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3409 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3410 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3411 },
3412 {
3413 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3414 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3415 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3416 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3417 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3418 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3419 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3420 },
3421};
3422
3423static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3424 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
3425};
3426
3427static void angle_estimation(const uint8_t *src, int src_stride, int rows,
3428 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003429 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003430 uint64_t hist[DIRECTIONAL_MODES];
3431 uint64_t hist_sum = 0;
3432
3433 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3434 src += src_stride;
3435 for (r = 1; r < rows; ++r) {
3436 for (c = 1; c < cols; ++c) {
3437 dx = src[c] - src[c - 1];
3438 dy = src[c] - src[c - src_stride];
3439 temp = dx * dx + dy * dy;
3440 if (dy == 0) {
3441 index = 2;
3442 } else {
3443 sn = (dx > 0) ^ (dy > 0);
3444 dx = abs(dx);
3445 dy = abs(dy);
3446 remd = dx % dy;
3447 quot = dx / dy;
3448 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003449 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450 }
3451 hist[index] += temp;
3452 }
3453 src += src_stride;
3454 }
3455
3456 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3457 for (i = 0; i < INTRA_MODES; ++i) {
3458 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003459 const uint8_t angle_bin = mode_to_angle_bin[i];
3460 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003461 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003462 if (angle_bin > 0) {
3463 score += hist[angle_bin - 1];
3464 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003465 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003466 if (angle_bin < DIRECTIONAL_MODES - 1) {
3467 score += hist[angle_bin + 1];
3468 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003469 }
3470 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3471 directional_mode_skip_mask[i] = 1;
3472 }
3473 }
3474}
3475
Yaowu Xuf883b422016-08-30 14:01:10 -07003476#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003477static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
3478 int rows, int cols,
3479 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003480 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003481 uint64_t hist[DIRECTIONAL_MODES];
3482 uint64_t hist_sum = 0;
3483 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
3484
3485 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3486 src += src_stride;
3487 for (r = 1; r < rows; ++r) {
3488 for (c = 1; c < cols; ++c) {
3489 dx = src[c] - src[c - 1];
3490 dy = src[c] - src[c - src_stride];
3491 temp = dx * dx + dy * dy;
3492 if (dy == 0) {
3493 index = 2;
3494 } else {
3495 sn = (dx > 0) ^ (dy > 0);
3496 dx = abs(dx);
3497 dy = abs(dy);
3498 remd = dx % dy;
3499 quot = dx / dy;
3500 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003501 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003502 }
3503 hist[index] += temp;
3504 }
3505 src += src_stride;
3506 }
3507
3508 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3509 for (i = 0; i < INTRA_MODES; ++i) {
3510 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003511 const uint8_t angle_bin = mode_to_angle_bin[i];
3512 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003513 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003514 if (angle_bin > 0) {
3515 score += hist[angle_bin - 1];
3516 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003517 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003518 if (angle_bin < DIRECTIONAL_MODES - 1) {
3519 score += hist[angle_bin + 1];
3520 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003521 }
3522 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3523 directional_mode_skip_mask[i] = 1;
3524 }
3525 }
3526}
Yaowu Xuf883b422016-08-30 14:01:10 -07003527#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003528#endif // CONFIG_EXT_INTRA
3529
3530// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003531static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3532 int *rate, int *rate_tokenonly,
3533 int64_t *distortion, int *skippable,
3534 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003535 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003536 MACROBLOCKD *const xd = &x->e_mbd;
3537 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003538 MB_MODE_INFO *const mbmi = &mic->mbmi;
3539 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003540 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003541#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003542 const int rows = block_size_high[bsize];
3543 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003544#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003545 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003546#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003547 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003548 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003549 const int src_stride = x->plane[0].src.stride;
3550 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003551#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003552#if CONFIG_FILTER_INTRA
3553 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003554 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3555#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003556 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003557#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003558 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003559 uint8_t *best_palette_color_map =
3560 cpi->common.allow_screen_content_tools
3561 ? x->palette_buffer->best_palette_color_map
3562 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003563 int palette_y_mode_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003564#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 const MODE_INFO *above_mi = xd->above_mi;
3566 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003567 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3568 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003570#if CONFIG_PVQ
3571 od_rollback_buffer pre_buf, post_buf;
3572
3573 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3574 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003575#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003576 bmode_costs = cpi->y_mode_costs[A][L];
3577
3578#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003579 mbmi->angle_delta[0] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003580 memset(directional_mode_skip_mask, 0,
3581 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07003582#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003583 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3584 highbd_angle_estimation(src, src_stride, rows, cols,
3585 directional_mode_skip_mask);
3586 else
Fergus Simpson4063a682017-02-28 16:52:22 -08003587#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003588 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
3589#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003590#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003591 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003592#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003593#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 pmi->palette_size[0] = 0;
3595 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003596 palette_y_mode_ctx +=
3597 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003598 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003599 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003600#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601
3602 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3603 x->use_default_intra_tx_type = 1;
3604 else
3605 x->use_default_intra_tx_type = 0;
3606
3607 /* Y Search for intra prediction mode */
3608 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003609 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003610 int this_rate, this_rate_tokenonly, s;
3611 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003612 if (mode_idx == FINAL_MODE_SEARCH) {
3613 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003614 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003615 x->use_default_intra_tx_type = 0;
3616 } else {
hui sude0c70a2017-01-09 17:12:17 -08003617 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003619#if CONFIG_PVQ
3620 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003621#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003623 mbmi->angle_delta[0] = 0;
3624#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003625 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003626 if (best_model_rd != INT64_MAX &&
3627 this_model_rd > best_model_rd + (best_model_rd >> 1))
3628 continue;
3629 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3630#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003631 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3632 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003633 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003634 this_rd_stats.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -08003635 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats,
3636 bsize, bmode_costs[mbmi->mode], best_rd,
3637 &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003639 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003640 }
3641#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003642 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003643#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003644 this_rate_tokenonly = this_rd_stats.rate;
3645 this_distortion = this_rd_stats.dist;
3646 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003647
3648 if (this_rate_tokenonly == INT_MAX) continue;
3649
hui sude0c70a2017-01-09 17:12:17 -08003650 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003651
hui sude0c70a2017-01-09 17:12:17 -08003652 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003653 // super_block_yrd above includes the cost of the tx_size in the
3654 // tokenonly rate, but for intra blocks, tx_size is always coded
3655 // (prediction granularity), so we account for it in the full rate,
3656 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003657 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658 }
Urvang Joshib100db72016-10-12 16:28:56 -07003659#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003660 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Urvang Joshi23a61112017-01-30 14:59:27 -08003661 this_rate +=
3662 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3663 [palette_y_mode_ctx],
3664 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003665#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003666#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003667 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003668 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3669#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003670#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003671 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003672 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -08003673#if CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003674 const int p_angle = mode_to_angle_map[mbmi->mode] +
3675 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003676 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003678 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003679#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003680 this_rate += write_uniform_cost(2 * max_angle_delta + 1,
3681 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003682 }
3683#endif // CONFIG_EXT_INTRA
3684 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003685#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003686 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003687 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003688 }
hui su5db97432016-10-14 16:10:14 -07003689#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003690
3691 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003692 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003693 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003694#if CONFIG_FILTER_INTRA
3695 beat_best_rd = 1;
3696#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003697 *rate = this_rate;
3698 *rate_tokenonly = this_rate_tokenonly;
3699 *distortion = this_distortion;
3700 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003701#if CONFIG_PVQ
3702 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003703#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003704 }
3705 }
3706
Yushin Cho77bba8d2016-11-04 16:36:56 -07003707#if CONFIG_PVQ
3708 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003709#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003710
Urvang Joshib100db72016-10-12 16:28:56 -07003711#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003712 if (cpi->common.allow_screen_content_tools) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003713 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3714 bmode_costs[DC_PRED], &best_mbmi,
3715 best_palette_color_map, &best_rd, &best_model_rd,
3716 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003717 }
Urvang Joshib100db72016-10-12 16:28:56 -07003718#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719
hui su5db97432016-10-14 16:10:14 -07003720#if CONFIG_FILTER_INTRA
3721 if (beat_best_rd) {
3722 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3723 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003724 &best_rd, &best_model_rd,
3725 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003726 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003727 }
3728 }
hui su5db97432016-10-14 16:10:14 -07003729#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003730
hui sude0c70a2017-01-09 17:12:17 -08003731 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732 return best_rd;
3733}
3734
Yue Chena1e48dc2016-08-29 17:29:33 -07003735// Return value 0: early termination triggered, no valid rd cost available;
3736// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003737static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3738 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3739 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003740 MACROBLOCKD *const xd = &x->e_mbd;
3741 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3742 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3743 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003744 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003745 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003746
3747 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003748
Jingning Han31b6a4f2017-02-23 11:05:53 -08003749#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003750 if (x->skip_chroma_rd) return is_cost_valid;
3751 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08003752#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003753
Yushin Cho77bba8d2016-11-04 16:36:56 -07003754#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003755 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003756 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3757 av1_subtract_plane(x, bsize, plane);
3758 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003759#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003760
Yushin Cho09de28b2016-06-21 14:51:23 -07003761 if (is_cost_valid) {
3762 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003763 RD_STATS pn_rd_stats;
3764 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3765 uv_tx_size, cpi->sf.use_fast_coef_costing);
3766 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003767 is_cost_valid = 0;
3768 break;
3769 }
Angie Chiang284d7772016-11-08 11:06:45 -08003770 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3771 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003772 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003773 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003774 is_cost_valid = 0;
3775 break;
3776 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003777 }
3778 }
3779
3780 if (!is_cost_valid) {
3781 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003782 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003783 }
3784
3785 return is_cost_valid;
3786}
3787
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003789void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3790 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003791 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003792 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003793 MACROBLOCKD *xd = &x->e_mbd;
3794 const struct macroblock_plane *const p = &x->plane[plane];
3795 struct macroblockd_plane *const pd = &xd->plane[plane];
3796 int64_t tmp;
3797 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003798 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003799 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003800 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003801 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003802 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003803 int bh = block_size_high[txm_bsize];
3804 int bw = block_size_wide[txm_bsize];
3805 int txb_h = tx_size_high_unit[tx_size];
3806 int txb_w = tx_size_wide_unit[tx_size];
3807
Yaowu Xuc27fc142016-08-22 16:08:15 -07003808 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003809 uint8_t *src =
3810 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3811 uint8_t *dst =
3812 &pd->dst
3813 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuf883b422016-08-30 14:01:10 -07003814#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003815 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3816 uint8_t *rec_buffer;
3817#else
3818 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003819#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003820 int max_blocks_high = block_size_high[plane_bsize];
3821 int max_blocks_wide = block_size_wide[plane_bsize];
3822 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003823 const int16_t *diff =
3824 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003825 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003826
3827 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003828
3829 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003830 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003832 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3833
3834 max_blocks_high >>= tx_size_wide_log2[0];
3835 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003836
3837#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003838 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
3839 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003841 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003842 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003843#endif // CONFIG_NEW_QUANT
3844
Yushin Cho721868c2016-11-14 16:04:33 +09003845 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003846 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847
3848// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003849#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003850 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3851 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003852 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003853 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003854 } else {
3855 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003856 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003857 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858 }
3859#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003860 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003861 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003862#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863
Jingning Han9fdc4222016-10-27 21:32:19 -07003864 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003866 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3867 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003868 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003869 for (idy = 0; idy < blocks_height; ++idy) {
3870 for (idx = 0; idx < blocks_width; ++idx) {
3871 const int16_t *d =
3872 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003873 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003874 }
3875 }
3876 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003877 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878 }
3879
Yaowu Xuf883b422016-08-30 14:01:10 -07003880#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003881 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3882 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003883#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003884 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003885
3886 if (p->eobs[block] > 0) {
3887 INV_TXFM_PARAM inv_txfm_param;
3888 inv_txfm_param.tx_type = tx_type;
3889 inv_txfm_param.tx_size = tx_size;
3890 inv_txfm_param.eob = p->eobs[block];
3891 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003892// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003893#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3895 inv_txfm_param.bd = xd->bd;
3896 highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3897 } else {
3898 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
3899 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003900#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003901 inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07003902#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903
Jingning Han4b47c932016-11-03 09:20:08 -07003904 if (txb_w + blk_col > max_blocks_wide ||
3905 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003906 int idx, idy;
3907 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003908 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3909 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003911 for (idy = 0; idy < blocks_height; ++idy) {
3912 for (idx = 0; idx < blocks_width; ++idx) {
3913 uint8_t *const s =
3914 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3915 uint8_t *const r =
3916 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003917 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918 tmp += this_dist;
3919 }
3920 }
3921 } else {
3922 uint32_t this_dist;
3923 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3924 &this_dist);
3925 tmp = this_dist;
3926 }
3927 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003928 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07003929 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
3930 scan_order->scan, scan_order->neighbors, 0);
3931 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07003932 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003933
Angie Chiangd81fdb42016-11-03 12:20:58 -07003934#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003935 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3936 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08003937#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003938}
3939
Yaowu Xuf883b422016-08-30 14:01:10 -07003940static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003941 int blk_col, int plane, int block, int block32,
3942 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003943 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3944 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003945 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003946 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947 MACROBLOCKD *const xd = &x->e_mbd;
3948 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3949 struct macroblock_plane *const p = &x->plane[plane];
3950 struct macroblockd_plane *const pd = &xd->plane[plane];
3951 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3952 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003953 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954 [MAX_MIB_SIZE] =
3955 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003956 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3957 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003958 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959 int64_t this_rd = INT64_MAX;
3960 ENTROPY_CONTEXT *pta = ta + blk_col;
3961 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003962 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003963 int ctx =
3964 txfm_partition_context(tx_above + (blk_col >> 1),
3965 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003967 int tmp_eob = 0;
3968 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003969 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003970 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003971
Jingning Han63cbf342016-11-09 15:37:48 -08003972 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003973
Jingning Hand3fada82016-11-22 10:46:55 -08003974 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975
3976 if (ref_best_rd < 0) {
3977 *is_cost_valid = 0;
3978 return;
3979 }
3980
Jingning Hance059e82016-10-31 16:27:28 -07003981 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982
Angie Chiangc0feea82016-11-03 15:36:18 -07003983 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003984
3985 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3986
Jingning Han1c019f92016-11-21 12:53:32 -08003987 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
3988 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989
3990 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
3991 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08003992
3993 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
3994 rd_stats_stack[block32].rate != INT_MAX) {
3995 *rd_stats = rd_stats_stack[block32];
3996 p->eobs[block] = !rd_stats->skip;
3997 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
3998 } else {
3999 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
4000 plane_bsize, coeff_ctx, rd_stats);
4001 if (tx_size == TX_32X32) {
4002 rd_stats_stack[block32] = *rd_stats;
4003 }
4004 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004005
Angie Chiangb5dda482016-11-02 16:19:58 -07004006 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4007 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4008 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004009 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004010#if CONFIG_RD_DEBUG
4011 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4012 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004013#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004014 rd_stats->rate = zero_blk_rate;
4015 rd_stats->dist = rd_stats->sse;
4016 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004017 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4018 p->eobs[block] = 0;
4019 } else {
4020 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004021 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004022 }
4023
Jingning Han571189c2016-10-24 10:38:43 -07004024 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004025 rd_stats->rate +=
4026 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4027 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004028 tmp_eob = p->eobs[block];
4029 }
4030
Jingning Han571189c2016-10-24 10:38:43 -07004031 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004032 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4033 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004034 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004035 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004036 int this_cost_valid = 1;
4037 int64_t tmp_rd = 0;
4038
Angie Chiangd7246172016-11-03 11:49:15 -07004039 sum_rd_stats.rate =
4040 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004041
4042 assert(tx_size < TX_SIZES_ALL);
4043
Yaowu Xuc27fc142016-08-22 16:08:15 -07004044 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004045 int offsetr = blk_row + (i >> 1) * bsl;
4046 int offsetc = blk_col + (i & 0x01) * bsl;
4047
4048 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4049
Jingning Han63cbf342016-11-09 15:37:48 -08004050 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004051 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004052 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4053 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004054
Angie Chiangc0feea82016-11-03 15:36:18 -07004055 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004056
Angie Chiangd7246172016-11-03 11:49:15 -07004057 tmp_rd =
4058 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004060 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004061 }
4062 if (this_cost_valid) sum_rd = tmp_rd;
4063 }
4064
4065 if (this_rd < sum_rd) {
4066 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004067 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4068 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004069 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004070 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004071 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004072 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4073 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004074 inter_tx_size[idy][idx] = tx_size;
4075 mbmi->tx_size = tx_size;
4076 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004077 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004078 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004079 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004080 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4081 }
4082}
4083
Angie Chiangb5dda482016-11-02 16:19:58 -07004084static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4085 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004086 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004087 MACROBLOCKD *const xd = &x->e_mbd;
4088 int is_cost_valid = 1;
4089 int64_t this_rd = 0;
4090
4091 if (ref_best_rd < 0) is_cost_valid = 0;
4092
Angie Chiangc0feea82016-11-03 15:36:18 -07004093 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004094
4095 if (is_cost_valid) {
4096 const struct macroblockd_plane *const pd = &xd->plane[0];
4097 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004098 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4099 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004100 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004101 const int bh = tx_size_high_unit[max_tx_size];
4102 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004103 int idx, idy;
4104 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004105 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004106 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004107 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4108 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4109 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4110 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4111
Angie Chiangb5dda482016-11-02 16:19:58 -07004112 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004113 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114
Jingning Han9ca05b72017-01-03 14:41:36 -08004115 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004116 memcpy(tx_above, xd->above_txfm_context,
4117 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4118 memcpy(tx_left, xd->left_txfm_context,
4119 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4120
4121 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004122 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004123 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004124 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004125 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004126 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004127 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004128 this_rd += AOMMIN(
4129 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4130 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004131 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004132 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004133 }
4134 }
4135 }
4136
Angie Chiangb5dda482016-11-02 16:19:58 -07004137 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4138 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004139 if (this_rd > ref_best_rd) is_cost_valid = 0;
4140
4141 if (!is_cost_valid) {
4142 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004143 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144 }
4145}
4146
Yaowu Xuf883b422016-08-30 14:01:10 -07004147static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004148 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004149 int64_t ref_best_rd, TX_TYPE tx_type,
4150 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004151 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004152 MACROBLOCKD *const xd = &x->e_mbd;
4153 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004154 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004155 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4156 int s0 = av1_cost_bit(skip_prob, 0);
4157 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004158 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004159 int row, col;
4160 const int max_blocks_high = max_block_high(xd, bsize, 0);
4161 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004162
4163 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004164 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004165 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004166
Angie Chiangb5dda482016-11-02 16:19:58 -07004167 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168
Jingning Hane67b38a2016-11-04 10:30:00 -07004169 for (row = 0; row < max_blocks_high / 2; ++row)
4170 for (col = 0; col < max_blocks_wide / 2; ++col)
4171 mbmi->min_tx_size = AOMMIN(
4172 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4173
Yaowu Xuc27fc142016-08-22 16:08:15 -07004174#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004175 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4176 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004178 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4179 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180 if (is_inter) {
4181 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004182 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004183 cpi->inter_tx_type_costs[ext_tx_set]
4184 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004185 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186 } else {
4187 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004188 rd_stats->rate +=
4189 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4190 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191 }
4192 }
4193#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004194 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4195 rd_stats->rate +=
4196 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197#endif // CONFIG_EXT_TX
4198
Angie Chiangb5dda482016-11-02 16:19:58 -07004199 if (rd_stats->skip)
4200 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004201 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004202 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004203
Angie Chiangb5dda482016-11-02 16:19:58 -07004204 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4205 !(rd_stats->skip))
4206 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004207
4208 return rd;
4209}
4210
Angie Chiangb5dda482016-11-02 16:19:58 -07004211static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4212 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004213 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004214 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4216 MACROBLOCKD *const xd = &x->e_mbd;
4217 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4218 int64_t rd = INT64_MAX;
4219 int64_t best_rd = INT64_MAX;
4220 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4221 const int is_inter = is_inter_block(mbmi);
4222 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004223 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004224 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004225 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
4226 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004227 int idx, idy;
4228 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004229 const int count32 =
4230 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004231#if CONFIG_EXT_PARTITION
4232 RD_STATS rd_stats_stack[16];
4233#else
Jingning Han63cbf342016-11-09 15:37:48 -08004234 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004235#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004237 const int ext_tx_set =
4238 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004239#endif // CONFIG_EXT_TX
4240
4241 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4242#if CONFIG_EXT_TX
4243 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4244#else
4245 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004246#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004247
Angie Chiangc0feea82016-11-03 15:36:18 -07004248 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004249
Jingning Han89d648b2016-11-22 11:22:08 -08004250 for (idx = 0; idx < count32; ++idx)
4251 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004252
Yaowu Xuc27fc142016-08-22 16:08:15 -07004253 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004254 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004255 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004256#if CONFIG_EXT_TX
4257 if (is_inter) {
4258 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4259 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4260 if (!do_tx_type_search(tx_type, prune)) continue;
4261 }
4262 } else {
4263 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4264 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4265 }
4266 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4267 }
4268#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004269 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4270 !do_tx_type_search(tx_type, prune))
4271 continue;
4272#endif // CONFIG_EXT_TX
4273 if (is_inter && x->use_default_inter_tx_type &&
4274 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4275 continue;
4276
Jingning Hane67b38a2016-11-04 10:30:00 -07004277 if (xd->lossless[mbmi->segment_id])
4278 if (tx_type != DCT_DCT) continue;
4279
Angie Chiangb5dda482016-11-02 16:19:58 -07004280 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004281 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282
4283 if (rd < best_rd) {
4284 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004285 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286 best_tx_type = mbmi->tx_type;
4287 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004288 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004289 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4290 for (idy = 0; idy < xd->n8_h; ++idy)
4291 for (idx = 0; idx < xd->n8_w; ++idx)
4292 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4293 }
4294 }
4295
4296 mbmi->tx_type = best_tx_type;
4297 for (idy = 0; idy < xd->n8_h; ++idy)
4298 for (idx = 0; idx < xd->n8_w; ++idx)
4299 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4300 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004301 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004302 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4303}
4304
Yaowu Xuf883b422016-08-30 14:01:10 -07004305static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 int blk_col, int plane, int block, TX_SIZE tx_size,
4307 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004308 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004309 MACROBLOCKD *const xd = &x->e_mbd;
4310 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4311 struct macroblock_plane *const p = &x->plane[plane];
4312 struct macroblockd_plane *const pd = &xd->plane[plane];
4313 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4314 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4315 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4316 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004317 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4318 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004319
Jingning Hand3fada82016-11-22 10:46:55 -08004320 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004321
Yaowu Xuc27fc142016-08-22 16:08:15 -07004322 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4323
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004324 plane_tx_size =
4325 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4326 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004327
4328 if (tx_size == plane_tx_size) {
4329 int coeff_ctx, i;
4330 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4331 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07004332 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07004333 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07004334 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004335
Jingning Han58224042016-10-27 16:35:32 -07004336 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004337 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004338 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004339 tl[i] = !(p->eobs[block] == 0);
4340 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004341 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4342 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004343 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004344 int i;
4345
4346 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004347
4348 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004349 int offsetr = blk_row + (i >> 1) * bsl;
4350 int offsetc = blk_col + (i & 0x01) * bsl;
4351
4352 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4353
4354 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4355 above_ctx, left_ctx, rd_stats);
4356 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004357 }
4358 }
4359}
4360
4361// Return value 0: early termination triggered, no valid rd cost available;
4362// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004363static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4364 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4365 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004366 MACROBLOCKD *const xd = &x->e_mbd;
4367 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4368 int plane;
4369 int is_cost_valid = 1;
4370 int64_t this_rd;
4371
4372 if (ref_best_rd < 0) is_cost_valid = 0;
4373
Angie Chiangc0feea82016-11-03 15:36:18 -07004374 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004375
Jingning Han31b6a4f2017-02-23 11:05:53 -08004376#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004377 if (x->skip_chroma_rd) return is_cost_valid;
4378 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08004379#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004380
Yue Chena1e48dc2016-08-29 17:29:33 -07004381#if CONFIG_EXT_TX && CONFIG_RECT_TX
4382 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004383 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004384 }
4385#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4386
Yaowu Xuc27fc142016-08-22 16:08:15 -07004387 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004388 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004389 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390 }
4391
Yaowu Xuc27fc142016-08-22 16:08:15 -07004392 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4393 const struct macroblockd_plane *const pd = &xd->plane[plane];
4394 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004395 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4396 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004397 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004398 const int bh = tx_size_high_unit[max_tx_size];
4399 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004400 int idx, idy;
4401 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004402 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004403 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4404 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004405 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004406 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407
Jingning Han9ca05b72017-01-03 14:41:36 -08004408 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409
4410 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004411 for (idx = 0; idx < mi_width; idx += bw) {
4412 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004413 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004414 block += step;
4415 }
4416 }
4417
Angie Chiangb5dda482016-11-02 16:19:58 -07004418 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419 is_cost_valid = 0;
4420 break;
4421 }
4422
Angie Chiang628d7c92016-11-03 16:24:56 -07004423 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424
Angie Chiangb5dda482016-11-02 16:19:58 -07004425 this_rd =
4426 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4427 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004428
4429 if (this_rd > ref_best_rd) {
4430 is_cost_valid = 0;
4431 break;
4432 }
4433 }
4434
4435 if (!is_cost_valid) {
4436 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004437 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004438 }
4439
4440 return is_cost_valid;
4441}
4442#endif // CONFIG_VAR_TX
4443
Urvang Joshib100db72016-10-12 16:28:56 -07004444#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004445static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4446 int dc_mode_cost,
4447 uint8_t *best_palette_color_map,
4448 MB_MODE_INFO *const best_mbmi,
4449 int64_t *best_rd, int *rate,
4450 int *rate_tokenonly, int64_t *distortion,
4451 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004452 MACROBLOCKD *const xd = &x->e_mbd;
4453 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui sude0c70a2017-01-09 17:12:17 -08004454 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004456 int this_rate;
4457 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004458 int colors_u, colors_v, colors;
4459 const int src_stride = x->plane[1].src.stride;
4460 const uint8_t *const src_u = x->plane[1].src.buf;
4461 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004462 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004463 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004464 int plane_block_width, plane_block_height, rows, cols;
4465 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4466 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004467 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4468
hui su83c26632017-01-24 17:19:06 -08004469 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004470#if CONFIG_FILTER_INTRA
4471 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4472#endif // CONFIG_FILTER_INTRA
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 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004476 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4477 cpi->common.bit_depth);
4478 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4479 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004480 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004481#endif // CONFIG_AOM_HIGHBITDEPTH
4482 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4483 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
4484#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004485 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004486#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004487
4488 colors = colors_u > colors_v ? colors_u : colors_v;
4489 if (colors > 1 && colors <= 64) {
4490 int r, c, n, i, j;
4491 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004492 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004493 float lb_u, ub_u, val_u;
4494 float lb_v, ub_v, val_v;
4495 float *const data = x->palette_buffer->kmeans_data_buf;
4496 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004497
Yaowu Xuf883b422016-08-30 14:01:10 -07004498#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004499 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4500 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4501 if (cpi->common.use_highbitdepth) {
4502 lb_u = src_u16[0];
4503 ub_u = src_u16[0];
4504 lb_v = src_v16[0];
4505 ub_v = src_v16[0];
4506 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004507#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 lb_u = src_u[0];
4509 ub_u = src_u[0];
4510 lb_v = src_v[0];
4511 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07004512#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004513 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004514#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004515
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516 for (r = 0; r < rows; ++r) {
4517 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004518#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004519 if (cpi->common.use_highbitdepth) {
4520 val_u = src_u16[r * src_stride + c];
4521 val_v = src_v16[r * src_stride + c];
4522 data[(r * cols + c) * 2] = val_u;
4523 data[(r * cols + c) * 2 + 1] = val_v;
4524 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004525#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526 val_u = src_u[r * src_stride + c];
4527 val_v = src_v[r * src_stride + c];
4528 data[(r * cols + c) * 2] = val_u;
4529 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07004530#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004531 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004532#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533 if (val_u < lb_u)
4534 lb_u = val_u;
4535 else if (val_u > ub_u)
4536 ub_u = val_u;
4537 if (val_v < lb_v)
4538 lb_v = val_v;
4539 else if (val_v > ub_v)
4540 ub_v = val_v;
4541 }
4542 }
4543
4544 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4545 --n) {
4546 for (i = 0; i < n; ++i) {
4547 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4548 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4549 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004550 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004551 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4552 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004553 pmi->palette_size[1] = n;
4554 for (i = 1; i < 3; ++i) {
4555 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004556#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557 if (cpi->common.use_highbitdepth)
4558 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4559 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4560 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004561#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004562 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4563 clip_pixel((int)centroids[j * 2 + i - 1]);
4564 }
4565 }
4566
Angie Chiang284d7772016-11-08 11:06:45 -08004567 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4568 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004569 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004570 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07004571 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08004572 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004573 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004574 av1_cost_bit(
4575 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004576
4577 for (i = 0; i < rows; ++i) {
4578 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004579 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004580 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004581 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004582 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004583 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4584 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004585 }
4586 }
4587
Angie Chiang284d7772016-11-08 11:06:45 -08004588 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004589 if (this_rd < *best_rd) {
4590 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004591 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004592 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004593 plane_block_width * plane_block_height *
4594 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004595 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004596 *distortion = tokenonly_rd_stats.dist;
4597 *rate_tokenonly = tokenonly_rd_stats.rate;
4598 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599 }
4600 }
4601 }
hui su83c26632017-01-24 17:19:06 -08004602 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004603 memcpy(color_map, best_palette_color_map,
4604 rows * cols * sizeof(best_palette_color_map[0]));
4605 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004606}
Urvang Joshib100db72016-10-12 16:28:56 -07004607#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004608
hui su5db97432016-10-14 16:10:14 -07004609#if CONFIG_FILTER_INTRA
4610// Return 1 if an filter intra mode is selected; return 0 otherwise.
4611static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4612 int *rate, int *rate_tokenonly,
4613 int64_t *distortion, int *skippable,
4614 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004615 MACROBLOCKD *const xd = &x->e_mbd;
4616 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004617 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004618 int this_rate;
4619 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004620 FILTER_INTRA_MODE mode;
4621 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004622 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004623
hui su5db97432016-10-14 16:10:14 -07004624 av1_zero(filter_intra_mode_info);
4625 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004626 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004627#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004628 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004629#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630
4631 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004632 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004633 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004634 continue;
4635
Angie Chiang284d7772016-11-08 11:06:45 -08004636 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004637 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4639 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004640 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004641 if (this_rd < *best_rd) {
4642 *best_rd = this_rd;
4643 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004644 *rate_tokenonly = tokenonly_rd_stats.rate;
4645 *distortion = tokenonly_rd_stats.dist;
4646 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004647 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4648 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649 }
4650 }
4651
hui su5db97432016-10-14 16:10:14 -07004652 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004654 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4655 filter_intra_mode_info.use_filter_intra_mode[1];
4656 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4657 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004658 return 1;
4659 } else {
4660 return 0;
4661 }
4662}
hui su5db97432016-10-14 16:10:14 -07004663#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004664
hui su5db97432016-10-14 16:10:14 -07004665#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004666// Run RD calculation with given chroma intra prediction angle., and return
4667// the RD cost. Update the best mode info. if the RD cost is the best so far.
4668static int64_t pick_intra_angle_routine_sbuv(
4669 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4670 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4671 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004673 int this_rate;
4674 int64_t this_rd;
4675 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004676
hui su45dc5972016-12-08 17:42:50 -08004677 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4678 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004679 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4680 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004681 if (this_rd < *best_rd) {
4682 *best_rd = this_rd;
4683 *best_angle_delta = mbmi->angle_delta[1];
4684 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004685 rd_stats->rate = tokenonly_rd_stats.rate;
4686 rd_stats->dist = tokenonly_rd_stats.dist;
4687 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004688 }
hui su45dc5972016-12-08 17:42:50 -08004689 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004690}
4691
hui su45dc5972016-12-08 17:42:50 -08004692// With given chroma directional intra prediction mode, pick the best angle
4693// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004694static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004695 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004696 int64_t best_rd, int *rate,
4697 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 MACROBLOCKD *const xd = &x->e_mbd;
4699 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su45dc5972016-12-08 17:42:50 -08004700 int i, angle_delta, best_angle_delta = 0;
4701 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA_UV + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004702
hui su45dc5972016-12-08 17:42:50 -08004703 rd_stats->rate = INT_MAX;
4704 rd_stats->skip = 0;
4705 rd_stats->dist = INT64_MAX;
4706 for (i = 0; i < 2 * (MAX_ANGLE_DELTA_UV + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004707
hui su45dc5972016-12-08 17:42:50 -08004708 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4709 for (i = 0; i < 2; ++i) {
4710 best_rd_in = (best_rd == INT64_MAX)
4711 ? INT64_MAX
4712 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4713 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4714 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4715 best_rd_in, rate, rd_stats,
4716 &best_angle_delta, &best_rd);
4717 rd_cost[2 * angle_delta + i] = this_rd;
4718 if (angle_delta == 0) {
4719 if (this_rd == INT64_MAX) return 0;
4720 rd_cost[1] = this_rd;
4721 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004722 }
4723 }
hui su45dc5972016-12-08 17:42:50 -08004724 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004725
hui su45dc5972016-12-08 17:42:50 -08004726 assert(best_rd != INT64_MAX);
4727 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4728 int64_t rd_thresh;
4729 for (i = 0; i < 2; ++i) {
4730 int skip_search = 0;
4731 rd_thresh = best_rd + (best_rd >> 5);
4732 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4733 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4734 skip_search = 1;
4735 if (!skip_search) {
4736 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4737 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4738 best_rd, rate, rd_stats,
4739 &best_angle_delta, &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004740 }
4741 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004742 }
4743
4744 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004745 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004746}
4747#endif // CONFIG_EXT_INTRA
4748
Urvang Joshi52648442016-10-13 17:27:51 -07004749static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4750 int *rate, int *rate_tokenonly,
4751 int64_t *distortion, int *skippable,
4752 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004753 MACROBLOCKD *xd = &x->e_mbd;
4754 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su83c26632017-01-24 17:19:06 -08004755 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004756 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004757 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004758 int this_rate;
4759 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004760#if CONFIG_PVQ
4761 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004762 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004763#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004764#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004765 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004767#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004768
hui su83c26632017-01-24 17:19:06 -08004769#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004770 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4771#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004772#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004773 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004774#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004775 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004776#if CONFIG_EXT_INTRA
4777 const int is_directional_mode =
4778 av1_is_directional_mode(mode, mbmi->sb_type);
4779#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004780 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4781 (1 << mode)))
4782 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004783
4784 mbmi->uv_mode = mode;
4785#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004786 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004787 if (is_directional_mode) {
hui su83c26632017-01-24 17:19:06 -08004788 const int rate_overhead =
4789 cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4790 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004791 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4792 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004793 continue;
4794 } else {
hui su83c26632017-01-24 17:19:06 -08004795#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004796 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004797#if CONFIG_PVQ
4798 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004799#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004800 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004801 }
hui su83c26632017-01-24 17:19:06 -08004802#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004803 }
hui su83c26632017-01-24 17:19:06 -08004804#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004805 this_rate =
4806 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004807
4808#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004809 if (is_directional_mode) {
4810 this_rate +=
4811 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
4812 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
4813 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004814#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004815#if CONFIG_FILTER_INTRA
4816 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4817 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4818#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004819#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004820 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4821 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004822 this_rate += av1_cost_bit(
4823 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004824#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004825
Yushin Cho77bba8d2016-11-04 16:36:56 -07004826#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004827 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004828#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004829 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004830
4831 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004832 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004833 best_rd = this_rd;
4834 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004835 *rate_tokenonly = tokenonly_rd_stats.rate;
4836 *distortion = tokenonly_rd_stats.dist;
4837 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004838 }
4839 }
4840
Urvang Joshib100db72016-10-12 16:28:56 -07004841#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4843 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004844 rd_pick_palette_intra_sbuv(cpi, x,
4845 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4846 best_palette_color_map, &best_mbmi, &best_rd,
4847 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004848 }
Urvang Joshib100db72016-10-12 16:28:56 -07004849#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004850
hui su5db97432016-10-14 16:10:14 -07004851#if CONFIG_FILTER_INTRA
4852 if (mbmi->sb_type >= BLOCK_8X8) {
4853 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004854 skippable, bsize, &best_rd))
4855 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004856 }
hui su5db97432016-10-14 16:10:14 -07004857#endif // CONFIG_FILTER_INTRA
4858
hui su83c26632017-01-24 17:19:06 -08004859 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004860 // Make sure we actually chose a mode
4861 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004862 return best_rd;
4863}
4864
Urvang Joshi52648442016-10-13 17:27:51 -07004865static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4867 TX_SIZE max_tx_size, int *rate_uv,
4868 int *rate_uv_tokenonly, int64_t *dist_uv,
4869 int *skip_uv, PREDICTION_MODE *mode_uv) {
4870 // Use an estimated rd for uv_intra based on DC_PRED if the
4871 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004872 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004873#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004874#if CONFIG_CHROMA_2X2
4875 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4876 bsize, max_tx_size);
4877#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004878 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4879 if (x->skip_chroma_rd) {
4880 *rate_uv = 0;
4881 *rate_uv_tokenonly = 0;
4882 *dist_uv = 0;
4883 *skip_uv = 1;
4884 *mode_uv = DC_PRED;
4885 return;
4886 }
Jingning Han3f167252016-06-07 16:11:42 -07004887 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4888 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004889#endif // CONFIG_CHROMA_2X2
4890#else
4891 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4892 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4893#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004894 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4895}
4896
Urvang Joshi52648442016-10-13 17:27:51 -07004897static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004898#if CONFIG_REF_MV && CONFIG_EXT_INTER
4899 int is_compound,
4900#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
4901 int16_t mode_context) {
4902#if CONFIG_REF_MV
4903 int mode_cost = 0;
4904#if CONFIG_EXT_INTER
4905 int16_t mode_ctx =
4906 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
4907#else
4908 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4909#endif // CONFIG_EXT_INTER
4910 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4911
4912 assert(is_inter_mode(mode));
4913
4914#if CONFIG_EXT_INTER
4915 if (is_compound) {
clang-format55ce9e02017-02-15 22:27:12 -08004916 return cpi
4917 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004918 } else {
4919 if (mode == NEWMV || mode == NEWFROMNEARMV) {
4920#else
4921 if (mode == NEWMV) {
4922#endif // CONFIG_EXT_INTER
4923 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4924#if CONFIG_EXT_INTER
4925 if (!is_compound)
4926 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
4927#endif // CONFIG_EXT_INTER
4928 return mode_cost;
4929 } else {
4930 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4931 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4932
4933 if (is_all_zero_mv) return mode_cost;
4934
4935 if (mode == ZEROMV) {
4936 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4937 return mode_cost;
4938 } else {
4939 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4940 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4941
4942 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4943 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4944 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4945
4946 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4947 return mode_cost;
4948 }
4949 }
4950#if CONFIG_EXT_INTER
4951 }
4952#endif // CONFIG_EXT_INTER
4953#else
4954 assert(is_inter_mode(mode));
4955#if CONFIG_EXT_INTER
4956 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004957 return cpi
4958 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004959 } else {
4960#endif // CONFIG_EXT_INTER
4961 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
4962#if CONFIG_EXT_INTER
4963 }
4964#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08004965#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07004966}
4967
Sarah Parker6fdc8532016-11-16 17:47:13 -08004968#if CONFIG_EXT_INTER
4969static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4970 COMPOUND_TYPE comp_type) {
4971 switch (comp_type) {
4972 case COMPOUND_AVERAGE: return 0;
4973 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Sarah Parker2f6ce752016-12-08 15:26:46 -08004974#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08004975 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08004976#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08004977 default: assert(0); return 0;
4978 }
4979}
4980#endif // CONFIG_EXT_INTER
4981
Sarah Parkere5299862016-08-16 14:57:37 -07004982#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004983static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08004984 static const int gm_amortization_blks[TRANS_TYPES] = {
4985 4, 6, 8, 10, 10, 10, 12
4986 };
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004987 static const int gm_params_cost[TRANS_TYPES] = {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08004988 GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
4989 GM_AFFINE_BITS, GM_HORTRAPEZOID_BITS, GM_VERTRAPEZOID_BITS,
4990 GM_HOMOGRAPHY_BITS,
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004991 };
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004992 const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08004993 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
Debargha Mukherjee705544c2016-11-22 08:55:49 -08004994 if (cpi->global_motion_used[ref][0] >= gm_amortization_blks[gm->wmtype]) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004995 return 0;
4996 } else {
4997 const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
4998 cpi->gmtype_cost[gm->wmtype];
4999 return cost / gm_amortization_blks[gm->wmtype];
5000 }
Sarah Parkere5299862016-08-16 14:57:37 -07005001}
Sarah Parkere5299862016-08-16 14:57:37 -07005002#endif // CONFIG_GLOBAL_MOTION
5003
clang-format55ce9e02017-02-15 22:27:12 -08005004static int set_and_cost_bmi_mvs(
5005 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
5006 PREDICTION_MODE mode, int_mv this_mv[2],
5007 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
5008 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005009#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08005010 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005011#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00005012 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
5013 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005014 MODE_INFO *const mic = xd->mi[0];
5015 const MB_MODE_INFO *const mbmi = &mic->mbmi;
5016 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5017 int thismvcost = 0;
5018 int idx, idy;
5019 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
5020 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
5021 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005022 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00005023 (void)mi_row;
5024 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005025
5026 switch (mode) {
5027 case NEWMV:
5028#if CONFIG_EXT_INTER
5029 case NEWFROMNEARMV:
5030#endif // CONFIG_EXT_INTER
5031 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5032#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005033 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005034 lower_mv_precision(&this_mv[0].as_mv, 0);
5035#endif // CONFIG_EXT_INTER
5036
5037#if CONFIG_REF_MV
5038 for (idx = 0; idx < 1 + is_compound; ++idx) {
5039 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005040 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005041 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005042 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5043 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005044 }
5045 (void)mvjcost;
5046 (void)mvcost;
5047#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005048 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5049 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005050#if !CONFIG_EXT_INTER
5051 if (is_compound) {
5052 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005053 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5054 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005055 }
5056#endif // !CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08005057#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005058 break;
5059 case NEARMV:
5060 case NEARESTMV:
5061 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5062 if (is_compound)
5063 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5064 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005065 case ZEROMV: {
5066 int ref;
5067 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005068#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005069 this_mv[ref].as_int =
5070 gm_get_motion_vector(
5071 &cpi->common.global_motion[mbmi->ref_frame[ref]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005072 cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005073 mi_row, i)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005074 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005075 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[ref]);
5076#else
5077 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005078#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005079 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005080 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005081 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005082#if CONFIG_EXT_INTER
5083 case NEW_NEWMV:
5084 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5085 compound_seg_newmvs[1].as_int == INVALID_MV) {
5086 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5087 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5088 } else {
5089 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5090 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5091 }
Alex Converse6317c882016-09-29 14:21:37 -07005092 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005093 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005094 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005095 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005096 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5097 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
5098 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5099 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005100 break;
5101 case NEW_NEARMV:
5102 case NEW_NEARESTMV:
5103 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005104 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005105 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005106 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5107 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5109 break;
5110 case NEAR_NEWMV:
5111 case NEAREST_NEWMV:
5112 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5113 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005114 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005115 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005116 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5117 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005118 break;
5119 case NEAREST_NEARMV:
5120 case NEAR_NEARESTMV:
5121 case NEAREST_NEARESTMV:
5122 case NEAR_NEARMV:
5123 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5124 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5125 break;
5126 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005127#if CONFIG_GLOBAL_MOTION
5128 this_mv[0].as_int =
5129 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005130 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005131 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005132 .as_int;
5133 this_mv[1].as_int =
5134 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005135 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005136 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005137 .as_int;
5138 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]) +
5139 GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
5140#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005141 this_mv[0].as_int = 0;
5142 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005143#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005144 break;
5145#endif // CONFIG_EXT_INTER
5146 default: break;
5147 }
5148
5149 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5150 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5151
5152 mic->bmi[i].as_mode = mode;
5153
5154#if CONFIG_REF_MV
5155 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005156 mic->bmi[i].pred_mv[0].as_int =
5157 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5158 if (is_compound)
5159 mic->bmi[i].pred_mv[1].as_int =
5160 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005161 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005162 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5163 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005164 }
Fergus Simpson4063a682017-02-28 16:52:22 -08005165#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005166
5167 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5168 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5169 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5170
5171#if CONFIG_REF_MV
5172#if CONFIG_EXT_INTER
5173 if (is_compound)
5174 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5175 else
5176#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005177 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5178 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005179#else // CONFIG_REF_MV
5180 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
5181#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005182#if CONFIG_REF_MV && CONFIG_EXT_INTER
5183 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
5184#else
5185 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
5186#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5187}
5188
Yushin Choab44fd12017-01-09 16:06:53 -08005189static int64_t encode_inter_mb_segment_sub8x8(
5190 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5191 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5192 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005193 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005194 MACROBLOCKD *xd = &x->e_mbd;
5195 struct macroblockd_plane *const pd = &xd->plane[0];
5196 struct macroblock_plane *const p = &x->plane[0];
5197 MODE_INFO *const mi = xd->mi[0];
5198 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005199 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5200 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005201 const int width = block_size_wide[plane_bsize];
5202 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005203 int idx, idy;
5204 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005205 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005206 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005207 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005208 int64_t thisdistortion = 0, thissse = 0;
5209 int thisrate = 0;
5210 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005211 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005212 const int num_4x4_w = tx_size_wide_unit[tx_size];
5213 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005214#if !CONFIG_PVQ
5215 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5216#else
5217 (void)cpi;
5218 (void)ta;
5219 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005220 (void)tx_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08005221#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005222
5223#if CONFIG_EXT_TX && CONFIG_RECT_TX
5224 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5225 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5226 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5227#else
5228 assert(tx_size == TX_4X4);
5229#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005230
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231 assert(tx_type == DCT_DCT);
5232
Yaowu Xuf883b422016-08-30 14:01:10 -07005233 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005234
Yaowu Xuf883b422016-08-30 14:01:10 -07005235#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005237 aom_highbd_subtract_block(
5238 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5239 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005240 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005241 aom_subtract_block(height, width,
5242 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005243 8, src, p->src.stride, dst, pd->dst.stride);
5244 }
5245#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005246 aom_subtract_block(height, width,
5247 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005248 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07005249#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005250
Jingning Hanbafee8d2016-12-02 10:25:03 -08005251 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5252 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005253 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005254 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005255 const int k = i + (idy * 2 + idx);
5256 const int block = av1_raster_order_to_block_index(tx_size, k);
5257 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5258 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005259 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Yushin Cho38395482017-01-03 13:10:41 -08005260#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005261#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005262 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5263 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005264#else
Angie Chiangff6d8902016-10-21 11:02:09 -07005265 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005266 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267#endif // CONFIG_NEW_QUANT
5268 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07005269 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07005270#else
Yushin Cho38395482017-01-03 13:10:41 -08005271 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5272 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Fergus Simpson4063a682017-02-28 16:52:22 -08005273#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005274 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
5275 &dist, &ssz);
5276 thisdistortion += dist;
5277 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005278#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005279 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07005280 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005281 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005282 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5283 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005284#else
5285 thisrate += x->rate;
5286 *(ta + (k & 1)) = !x->pvq_skip[0];
5287 *(tl + (k >> 1)) = !x->pvq_skip[0];
Fergus Simpson4063a682017-02-28 16:52:22 -08005288#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005289#if CONFIG_EXT_TX
5290 if (tx_size == TX_8X4) {
5291 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5292 }
5293 if (tx_size == TX_4X8) {
5294 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5295 }
5296#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5298 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005299 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005300 if (rd >= best_yrd) return INT64_MAX;
5301 }
5302 }
5303
5304 *distortion = thisdistortion;
5305 *labelyrate = thisrate;
5306 *sse = thissse;
5307
5308 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5309}
5310
5311typedef struct {
5312 int eobs;
5313 int brate;
5314 int byrate;
5315 int64_t bdist;
5316 int64_t bsse;
5317 int64_t brdcost;
5318 int_mv mvs[2];
5319#if CONFIG_REF_MV
5320 int_mv pred_mv[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005321#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005322#if CONFIG_EXT_INTER
5323 int_mv ref_mv[2];
5324#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005325
5326#if CONFIG_CB4X4
5327 ENTROPY_CONTEXT ta[4];
5328 ENTROPY_CONTEXT tl[4];
5329#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005330 ENTROPY_CONTEXT ta[2];
5331 ENTROPY_CONTEXT tl[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005332#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005333} SEG_RDSTAT;
5334
5335typedef struct {
5336 int_mv *ref_mv[2];
5337 int_mv mvp;
5338
5339 int64_t segment_rd;
5340 int r;
5341 int64_t d;
5342 int64_t sse;
5343 int segment_yrate;
5344 PREDICTION_MODE modes[4];
5345#if CONFIG_EXT_INTER
5346 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5347#else
5348 SEG_RDSTAT rdstat[4][INTER_MODES];
5349#endif // CONFIG_EXT_INTER
5350 int mvthresh;
5351} BEST_SEG_INFO;
5352
5353static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
5354 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
5355 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
5356}
5357
5358static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5359 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5360 struct macroblock_plane *const p = &x->plane[0];
5361 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5362
5363 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005364 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005365 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5366 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005367 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368 if (has_second_ref(mbmi))
5369 pd->pre[1].buf =
5370 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005371 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005372}
5373
5374static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5375 struct buf_2d orig_pre[2]) {
5376 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5377 x->plane[0].src = orig_src;
5378 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5379 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5380}
5381
5382// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5383// TODO(aconverse): Find out if this is still productive then clean up or remove
5384static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005385 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005386#if CONFIG_REF_MV && CONFIG_EXT_INTER
5387 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
5388#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5389 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005390 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5391 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005392 int_mv zeromv[2];
5393 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5394 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005395 (void)mi_row;
5396 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005397 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5398#if CONFIG_GLOBAL_MOTION
5399 if (this_mode == ZEROMV
5400#if CONFIG_EXT_INTER
5401 || this_mode == ZERO_ZEROMV
5402#endif // CONFIG_EXT_INTER
5403 )
5404 zeromv[cur_frm].as_int =
5405 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005406 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005407 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005408 .as_int;
5409 else
5410#endif // CONFIG_GLOBAL_MOTION
5411 zeromv[cur_frm].as_int = 0;
5412 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005413#if !CONFIG_EXT_INTER
5414 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005415#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005416 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005417 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005418 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005419 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005420#if CONFIG_REF_MV
5421 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005422 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005423#else
5424 int16_t rfc = mode_context[ref_frames[0]];
Fergus Simpson4063a682017-02-28 16:52:22 -08005425#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005426#if CONFIG_REF_MV && CONFIG_EXT_INTER
5427 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
5428 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
5429 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
5430#else
5431 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5432 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5433 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
5434#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5435
5436#if !CONFIG_REF_MV
5437 (void)bsize;
5438 (void)block;
Fergus Simpson4063a682017-02-28 16:52:22 -08005439#endif // !CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005440
5441 if (this_mode == NEARMV) {
5442 if (c1 > c3) return 0;
5443 } else if (this_mode == NEARESTMV) {
5444 if (c2 > c3) return 0;
5445 } else {
5446 assert(this_mode == ZEROMV);
5447 if (ref_frames[1] <= INTRA_FRAME) {
5448 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5449 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5450 return 0;
5451 } else {
5452 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5453 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5454 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5455 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5456 return 0;
5457 }
5458 }
5459 }
5460#if CONFIG_EXT_INTER
5461 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
5462 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
5463 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005464 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5465 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005466#if CONFIG_REF_MV
5467 int16_t rfc = compound_mode_context[ref_frames[0]];
5468 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
5469 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
5470 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
5471 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
5472 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
5473#else
5474 int16_t rfc = mode_context[ref_frames[0]];
5475 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
5476 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5477 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
5478 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
5479 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Fergus Simpson4063a682017-02-28 16:52:22 -08005480#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005481
5482 if (this_mode == NEAREST_NEARMV) {
5483 if (c1 > c3) return 0;
5484 } else if (this_mode == NEAREST_NEARESTMV) {
5485 if (c2 > c3) return 0;
5486 } else if (this_mode == NEAR_NEARESTMV) {
5487 if (c4 > c3) return 0;
5488 } else if (this_mode == NEAR_NEARMV) {
5489 if (c5 > c3) return 0;
5490 } else {
5491 assert(this_mode == ZERO_ZEROMV);
5492 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5493 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
5494 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
5495 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
5496 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
5497 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
5498 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
5499 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
5500 return 0;
5501 }
5502 }
5503#endif // CONFIG_EXT_INTER
5504 return 1;
5505}
5506
Urvang Joshi52648442016-10-13 17:27:51 -07005507static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5508 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5509 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005510#if CONFIG_EXT_INTER
5511 int_mv *ref_mv_sub8x8[2],
Fergus Simpson4063a682017-02-28 16:52:22 -08005512#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
5514 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005515 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005516 const int pw = block_size_wide[bsize];
5517 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 MACROBLOCKD *xd = &x->e_mbd;
5519 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005520 // This function should only ever be called for compound modes
5521 assert(has_second_ref(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005522 const int refs[2] = { mbmi->ref_frame[0],
5523 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
5524 int_mv ref_mv[2];
5525 int ite, ref;
5526#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005527 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005528 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5529 mbmi->interp_filter[3],
5530 };
5531#else
James Zern7b9407a2016-05-18 23:48:05 -07005532 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005533#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005534 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005535 struct macroblockd_plane *const pd = &xd->plane[0];
5536#if CONFIG_GLOBAL_MOTION
5537 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5538 const int ic = block & 1;
5539 const int ir = (block - ic) >> 1;
5540 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5541 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
5542 int is_global[2];
5543 for (ref = 0; ref < 2; ++ref) {
5544 WarpedMotionParams *const wm =
5545 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5546 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5547 }
5548#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549
5550 // Do joint motion search in compound mode to get more accurate mv.
5551 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5552 int last_besterr[2] = { INT_MAX, INT_MAX };
5553 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07005554 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
5555 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005556 };
5557
5558// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005559#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005560 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5561 uint8_t *second_pred;
5562#else
5563 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005564#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005565
Jingning Han61418bb2017-01-23 17:12:48 -08005566#if CONFIG_EXT_INTER && CONFIG_CB4X4
5567 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005568#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005569
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005571#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005572 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5573 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5574 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005575#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005576 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5577
5578 if (scaled_ref_frame[ref]) {
5579 int i;
5580 // Swap out the reference frame for a version that's been scaled to
5581 // match the resolution of the current frame, allowing the existing
5582 // motion search code to be used without additional modifications.
5583 for (i = 0; i < MAX_MB_PLANE; i++)
5584 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005585 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5586 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587 }
5588
5589 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
5590 }
5591
5592// Since we have scaled the reference frames to match the size of the current
5593// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07005594#if CONFIG_AOM_HIGHBITDEPTH
5595 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5596 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005597#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005598 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5599 cm->height);
5600#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005601
5602 // Allow joint search multiple times iteratively for each reference frame
5603 // and break out of the search loop if it couldn't find a better mv.
5604 for (ite = 0; ite < 4; ite++) {
5605 struct buf_2d ref_yv12[2];
5606 int bestsme = INT_MAX;
5607 int sadpb = x->sadperbit16;
5608 MV *const best_mv = &x->best_mv.as_mv;
5609 int search_range = 3;
5610
5611 int tmp_col_min = x->mv_col_min;
5612 int tmp_col_max = x->mv_col_max;
5613 int tmp_row_min = x->mv_row_min;
5614 int tmp_row_max = x->mv_row_max;
5615 int id = ite % 2; // Even iterations search in the first reference frame,
5616 // odd iterations search in the second. The predictor
5617 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005618 const int plane = 0;
5619 ConvolveParams conv_params = get_conv_params(0, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005620
5621 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005622 ref_yv12[0] = xd->plane[plane].pre[0];
5623 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624
5625#if CONFIG_DUAL_FILTER
5626 // reload the filter types
5627 interp_filter[0] =
5628 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5629 interp_filter[1] =
5630 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005631#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005632
5633// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005634#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5636 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005637 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005638 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5639 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005640#if CONFIG_GLOBAL_MOTION
5641 is_global[!id], p_col, p_row,
5642#endif // CONFIG_GLOBAL_MOTION
5643 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005644 } else {
5645 second_pred = (uint8_t *)second_pred_alloc_16;
Angie Chiang9f45bc42017-01-13 16:27:54 -08005646 av1_build_inter_predictor(
5647 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5648 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005649#if CONFIG_GLOBAL_MOTION
5650 is_global[!id], p_col, p_row, plane, !id,
5651#endif // CONFIG_GLOBAL_MOTION
5652 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005653 }
5654#else
Angie Chiang9f45bc42017-01-13 16:27:54 -08005655 av1_build_inter_predictor(
5656 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5657 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005658#if CONFIG_GLOBAL_MOTION
5659 is_global[!id], p_col, p_row, plane, !id,
5660#endif // CONFIG_GLOBAL_MOTION
5661 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07005662#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005663
5664 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005665 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005666 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005667
5668 // Use the mv result from the single mode as mv predictor.
5669 *best_mv = frame_mv[refs[id]].as_mv;
5670
5671 best_mv->col >>= 3;
5672 best_mv->row >>= 3;
5673
5674#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005675 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08005676#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005677
5678 // Small-range full-pixel motion search.
5679 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005680 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5681 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005682 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005683 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5684 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005685
5686 x->mv_col_min = tmp_col_min;
5687 x->mv_col_max = tmp_col_max;
5688 x->mv_row_min = tmp_row_min;
5689 x->mv_row_max = tmp_row_max;
5690
5691 if (bestsme < INT_MAX) {
5692 int dis; /* TODO: use dis in distortion calculation later. */
5693 unsigned int sse;
5694 if (cpi->sf.use_upsampled_references) {
5695 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005696 struct buf_2d backup_pred = pd->pre[0];
5697 const YV12_BUFFER_CONFIG *upsampled_ref =
5698 get_upsampled_ref(cpi, refs[id]);
5699
5700 // Set pred for Y plane
5701 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5702 upsampled_ref->y_crop_width,
5703 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5704 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5705 pd->subsampling_y);
5706
Jingning Han271bb2c2016-12-14 12:34:46 -08005707// If bsize < BLOCK_8X8, adjust pred pointer for this block
5708#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005709 if (bsize < BLOCK_8X8)
5710 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005711 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5712 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005714#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005715
5716 bestsme = cpi->find_fractional_mv_step(
5717 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5718 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5719 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5720 &dis, &sse, second_pred, pw, ph, 1);
5721
5722 // Restore the reference frames.
5723 pd->pre[0] = backup_pred;
5724 } else {
5725 (void)block;
5726 bestsme = cpi->find_fractional_mv_step(
5727 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5728 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5729 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5730 &dis, &sse, second_pred, pw, ph, 0);
5731 }
5732 }
5733
5734 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005735 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005736
5737 if (bestsme < last_besterr[id]) {
5738 frame_mv[refs[id]].as_mv = *best_mv;
5739 last_besterr[id] = bestsme;
5740 } else {
5741 break;
5742 }
5743 }
5744
5745 *rate_mv = 0;
5746
5747 for (ref = 0; ref < 2; ++ref) {
5748 if (scaled_ref_frame[ref]) {
5749 // Restore the prediction frame pointers to their unscaled versions.
5750 int i;
5751 for (i = 0; i < MAX_MB_PLANE; i++)
5752 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5753 }
5754#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005755 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08005756#endif // CONFIG_REF_MV
Jingning Han61418bb2017-01-23 17:12:48 -08005757#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005758 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005759#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005760 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5761 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5762 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005763#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005765 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5766 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5767 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005768#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005769 }
5770}
5771
Yushin Cho482016d2017-01-06 14:06:13 -08005772static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005773 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005774 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5775 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5776 int mvthresh,
5777#if CONFIG_EXT_INTER
5778 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5779 int_mv compound_seg_newmvs[4][2],
5780#else
5781 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5782#endif // CONFIG_EXT_INTER
5783 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5784 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5785#if CONFIG_REF_MV
5786 int_mv tmp_ref_mv[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005787#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 MACROBLOCKD *xd = &x->e_mbd;
5789 MODE_INFO *mi = xd->mi[0];
5790 MB_MODE_INFO *mbmi = &mi->mbmi;
5791 int mode_idx;
5792 int k, br = 0, idx, idy;
5793 int64_t bd = 0, block_sse = 0;
5794 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005795 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005796 struct macroblock_plane *const p = &x->plane[0];
5797 struct macroblockd_plane *const pd = &xd->plane[0];
5798 const int label_count = 4;
5799 int64_t this_segment_rd = 0;
5800 int label_mv_thresh;
5801 int segmentyrate = 0;
5802 const BLOCK_SIZE bsize = mbmi->sb_type;
5803 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5804 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005805#if CONFIG_CB4X4
5806 ENTROPY_CONTEXT t_above[4], t_left[4];
5807#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005808 ENTROPY_CONTEXT t_above[2], t_left[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005809#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005810 int subpelmv = 1, have_ref = 0;
5811 const int has_second_rf = has_second_ref(mbmi);
5812 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5813 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005814#if CONFIG_PVQ
5815 od_rollback_buffer pre_buf;
5816
5817 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005818#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819#if CONFIG_EXT_TX && CONFIG_RECT_TX
5820 mbmi->tx_size =
5821 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5822#else
5823 mbmi->tx_size = TX_4X4;
5824#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5825
Yaowu Xuf883b422016-08-30 14:01:10 -07005826 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005827
5828 bsi->segment_rd = best_rd;
5829 bsi->ref_mv[0] = best_ref_mv;
5830 bsi->ref_mv[1] = second_best_ref_mv;
5831 bsi->mvp.as_int = best_ref_mv->as_int;
5832 bsi->mvthresh = mvthresh;
5833
5834 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5835
Sebastien Alaiwand16a8362017-03-09 14:14:40 +01005836#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005837 for (idx = 0; idx < 4; ++idx) {
5838 for (k = NEARESTMV; k <= NEWMV; ++k) {
5839 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5840 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5841
5842 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5843 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5844 }
5845 }
Sebastien Alaiwand16a8362017-03-09 14:14:40 +01005846#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005847
5848 memcpy(t_above, pd->above_context, sizeof(t_above));
5849 memcpy(t_left, pd->left_context, sizeof(t_left));
5850
5851 // 64 makes this threshold really big effectively
5852 // making it so that we very rarely check mvs on
5853 // segments. setting this to 1 would make mv thresh
5854 // roughly equal to what it is for macroblocks
5855 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5856
5857 // Segmentation method overheads
5858 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5859 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5860 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5861 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5862 int_mv mode_mv[MB_MODE_COUNT][2];
5863 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5864 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005865 int64_t new_best_rd = INT64_MAX;
5866 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005867 int ref;
5868#if CONFIG_REF_MV
5869 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5870 uint8_t ref_mv_count[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005871#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005872#if CONFIG_EXT_INTER
5873 int mv_idx;
5874 int_mv ref_mvs_sub8x8[2][2];
5875#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005876#if CONFIG_PVQ
5877 od_rollback_buffer idx_buf, post_buf;
5878 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5879 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005880#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005881
5882 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5883 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5884#if CONFIG_EXT_INTER
5885 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Yaowu Xu531d6af2017-03-07 17:48:52 -08005886 av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
5887 mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005888#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005889#if CONFIG_GLOBAL_MOTION
5890 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -08005891 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005892 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005893 mi_col, mi_row, index)
David Barkercdcac6d2016-12-01 17:04:16 +00005894 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005895#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005896 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005897#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005898 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005899#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005900 ref_mv_stack[ref], &ref_mv_count[ref],
Fergus Simpson4063a682017-02-28 16:52:22 -08005901#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005902#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005903 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005904#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005905 &frame_mv[NEARESTMV][frame],
5906 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907
5908#if CONFIG_REF_MV
5909 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5910 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5911 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5912 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
Fergus Simpson4063a682017-02-28 16:52:22 -08005913#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005914
5915#if CONFIG_EXT_INTER
5916 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5917 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005918 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5919 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005920
5921 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005922#if CONFIG_GLOBAL_MOTION
5923 frame_mv[ZERO_ZEROMV][frame].as_int =
5924 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005925 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005926 mi_col, mi_row, index)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005927 .as_int;
5928#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005929 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005930#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005931 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5932 frame_mv[NEARESTMV][frame].as_int;
5933
5934 if (ref == 0) {
5935 frame_mv[NEAREST_NEARMV][frame].as_int =
5936 frame_mv[NEARESTMV][frame].as_int;
5937 frame_mv[NEAR_NEARESTMV][frame].as_int =
5938 frame_mv[NEARMV][frame].as_int;
5939 frame_mv[NEAREST_NEWMV][frame].as_int =
5940 frame_mv[NEARESTMV][frame].as_int;
5941 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5942 frame_mv[NEAR_NEARMV][frame].as_int =
5943 frame_mv[NEARMV][frame].as_int;
5944 } else if (ref == 1) {
5945 frame_mv[NEAREST_NEARMV][frame].as_int =
5946 frame_mv[NEARMV][frame].as_int;
5947 frame_mv[NEAR_NEARESTMV][frame].as_int =
5948 frame_mv[NEARESTMV][frame].as_int;
5949 frame_mv[NEW_NEARESTMV][frame].as_int =
5950 frame_mv[NEARESTMV][frame].as_int;
5951 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5952 frame_mv[NEAR_NEARMV][frame].as_int =
5953 frame_mv[NEARMV][frame].as_int;
5954 }
5955 }
5956#endif // CONFIG_EXT_INTER
5957 }
5958
5959// search for the best motion vector on this segment
5960#if CONFIG_EXT_INTER
5961 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
5962 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
5963 ++this_mode)
5964#else
5965 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5966#endif // CONFIG_EXT_INTER
5967 {
5968 const struct buf_2d orig_src = x->plane[0].src;
5969 struct buf_2d orig_pre[2];
5970 // This flag controls if the motion estimation will kick off. When it
5971 // is set to a non-zero value, the encoder will force motion estimation.
5972 int run_mv_search = 0;
5973
5974 mode_idx = INTER_OFFSET(this_mode);
5975#if CONFIG_EXT_INTER
5976 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
5977
5978 for (ref = 0; ref < 1 + has_second_rf; ++ref)
5979 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
5980#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005981 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005982 if (!(inter_mode_mask & (1 << this_mode))) continue;
5983
5984#if CONFIG_REF_MV
5985 run_mv_search = 2;
5986#if !CONFIG_EXT_INTER
5987 if (filter_idx > 0 && this_mode == NEWMV) {
5988 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07005989 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005990
5991 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005992 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005993 ref_rdstat->mvs[0].as_int &&
5994 ref_rdstat->mvs[0].as_int != INVALID_MV)
5995 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5996 --run_mv_search;
5997
Urvang Joshi454280d2016-10-14 16:51:44 -07005998 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07005999 ref_rdstat->mvs[1].as_int &&
6000 ref_rdstat->mvs[1].as_int != INVALID_MV)
6001 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
6002 --run_mv_search;
6003 } else {
6004 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
6005 ref_rdstat->mvs[0].as_int != INVALID_MV) {
6006 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006007 seg_mvs[index][mbmi->ref_frame[0]].as_int =
6008 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009 }
6010 }
6011
6012 if (run_mv_search != 0 && filter_idx > 1) {
6013 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07006014 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015 run_mv_search = 2;
6016
6017 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006018 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006019 ref_rdstat->mvs[0].as_int &&
6020 ref_rdstat->mvs[0].as_int != INVALID_MV)
6021 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
6022 --run_mv_search;
6023
Urvang Joshi454280d2016-10-14 16:51:44 -07006024 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006025 ref_rdstat->mvs[1].as_int &&
6026 ref_rdstat->mvs[1].as_int != INVALID_MV)
6027 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
6028 --run_mv_search;
6029 } else {
6030 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
6031 ref_rdstat->mvs[0].as_int != INVALID_MV) {
6032 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006033 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006034 ref_rdstat->mvs[0].as_int;
6035 }
6036 }
6037 }
6038 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006039#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040#endif // CONFIG_REF_MV
6041
Sarah Parkere5299862016-08-16 14:57:37 -07006042#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00006043 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07006044 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00006045 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07006046#endif // CONFIG_GLOBAL_MOTION
6047
6048 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006050 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006051#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006052 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00006053 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07006054 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006055
6056 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07006057 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
6058 sizeof(bsi->rdstat[index][mode_idx].ta));
6059 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
6060 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006061#if CONFIG_PVQ
6062 od_encode_rollback(&x->daala_enc, &idx_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006063#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006064
6065 // motion search for newmv (single predictor case only)
6066 if (!has_second_rf &&
6067#if CONFIG_EXT_INTER
6068 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07006069 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006070#else
6071 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006072 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07006073 run_mv_search)
6074#endif // CONFIG_EXT_INTER
6075 ) {
6076 int step_param = 0;
6077 int bestsme = INT_MAX;
6078 int sadpb = x->sadperbit4;
6079 MV mvp_full;
6080 int max_mv;
6081 int cost_list[5];
6082 int tmp_col_min = x->mv_col_min;
6083 int tmp_col_max = x->mv_col_max;
6084 int tmp_row_min = x->mv_row_min;
6085 int tmp_row_max = x->mv_row_max;
6086
6087 /* Is the best so far sufficiently good that we cant justify doing
6088 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07006089 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090
6091 if (cpi->oxcf.mode != BEST) {
6092#if CONFIG_EXT_INTER
6093 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
6094#else
6095// use previous block's result as next block's MV predictor.
6096#if !CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006097 if (index > 0) {
6098 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
6099 if (index == 2)
6100 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006101 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006102#endif // !CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006103#endif // CONFIG_EXT_INTER
6104 }
Urvang Joshi454280d2016-10-14 16:51:44 -07006105 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
6106 : AOMMAX(abs(bsi->mvp.as_mv.row),
6107 abs(bsi->mvp.as_mv.col)) >>
6108 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006109
6110 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6111 // Take wtd average of the step_params based on the last frame's
6112 // max mv magnitude and the best ref mvs of the current block for
6113 // the given reference.
6114 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006115 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006116 } else {
6117 step_param = cpi->mv_step_param;
6118 }
6119
6120#if CONFIG_REF_MV
6121 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
6122 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
6123#else
6124 mvp_full.row = bsi->mvp.as_mv.row >> 3;
6125 mvp_full.col = bsi->mvp.as_mv.col >> 3;
Fergus Simpson4063a682017-02-28 16:52:22 -08006126#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006127
6128 if (cpi->sf.adaptive_motion_search) {
6129 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
6130 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07006131 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006132 }
6133
6134 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07006135 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006136
Yaowu Xuf883b422016-08-30 14:01:10 -07006137 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006138
6139 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6140
6141#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006142 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08006143#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006144 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 cpi, x, bsize, &mvp_full, step_param, sadpb,
6146 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6147 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6148
6149 x->mv_col_min = tmp_col_min;
6150 x->mv_col_max = tmp_col_max;
6151 x->mv_row_min = tmp_row_min;
6152 x->mv_row_max = tmp_row_max;
6153
6154 if (bestsme < INT_MAX) {
6155 int distortion;
6156 if (cpi->sf.use_upsampled_references) {
6157 int best_mv_var;
6158 const int try_second =
6159 x->second_best_mv.as_int != INVALID_MV &&
6160 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006161 const int pw = block_size_wide[bsize];
6162 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006163 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006164 struct buf_2d backup_pred = pd->pre[0];
6165 const YV12_BUFFER_CONFIG *upsampled_ref =
6166 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6167
6168 // Set pred for Y plane
6169 setup_pred_plane(
6170 &pd->pre[0], upsampled_ref->y_buffer,
6171 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6172 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6173 pd->subsampling_x, pd->subsampling_y);
6174
6175 // adjust pred pointer for this block
6176 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006177 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006178 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006179 << 3];
6180
6181 best_mv_var = cpi->find_fractional_mv_step(
6182 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6183 x->errorperbit, &cpi->fn_ptr[bsize],
6184 cpi->sf.mv.subpel_force_stop,
6185 cpi->sf.mv.subpel_iters_per_step,
6186 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6187 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
6188 1);
6189
6190 if (try_second) {
6191 int this_var;
6192 MV best_mv = x->best_mv.as_mv;
6193 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07006194 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6195 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6196 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6197 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198
6199 x->best_mv = x->second_best_mv;
6200 if (x->best_mv.as_mv.row * 8 <= maxr &&
6201 x->best_mv.as_mv.row * 8 >= minr &&
6202 x->best_mv.as_mv.col * 8 <= maxc &&
6203 x->best_mv.as_mv.col * 8 >= minc) {
6204 this_var = cpi->find_fractional_mv_step(
6205 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6206 x->errorperbit, &cpi->fn_ptr[bsize],
6207 cpi->sf.mv.subpel_force_stop,
6208 cpi->sf.mv.subpel_iters_per_step,
6209 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6210 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
6211 NULL, pw, ph, 1);
6212 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6213 x->best_mv.as_mv = best_mv;
6214 }
6215 }
6216
6217 // Restore the reference frames.
6218 pd->pre[0] = backup_pred;
6219 } else {
6220 cpi->find_fractional_mv_step(
6221 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6222 x->errorperbit, &cpi->fn_ptr[bsize],
6223 cpi->sf.mv.subpel_force_stop,
6224 cpi->sf.mv.subpel_iters_per_step,
6225 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6226 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
6227 }
6228
6229// save motion search result for use in compound prediction
6230#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006231 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006232#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006233 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006234#endif // CONFIG_EXT_INTER
6235 }
6236
6237 if (cpi->sf.adaptive_motion_search)
6238 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6239
6240#if CONFIG_EXT_INTER
6241 mode_mv[this_mode][0] = x->best_mv;
6242#else
6243 mode_mv[NEWMV][0] = x->best_mv;
6244#endif // CONFIG_EXT_INTER
6245
6246 // restore src pointers
6247 mi_buf_restore(x, orig_src, orig_pre);
6248 }
6249
6250 if (has_second_rf) {
6251#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006252 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6253 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006254#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006255 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6256 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006257#endif // CONFIG_EXT_INTER
6258 continue;
6259 }
6260
6261#if CONFIG_DUAL_FILTER
6262 (void)run_mv_search;
Fergus Simpson4063a682017-02-28 16:52:22 -08006263#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
6265 if (has_second_rf &&
6266#if CONFIG_EXT_INTER
6267 this_mode == NEW_NEWMV &&
6268#else
6269 this_mode == NEWMV &&
6270#endif // CONFIG_EXT_INTER
6271#if CONFIG_DUAL_FILTER
6272 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6273#else
6274 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
Fergus Simpson4063a682017-02-28 16:52:22 -08006275#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006276 {
6277 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006278 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6280 int rate_mv;
6281 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6282 mi_col,
6283#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006284 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006285#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006286 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006287#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006288 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006289#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006290 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006291 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006292 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6294#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006295 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006296 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006297 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6299#endif // CONFIG_EXT_INTER
6300 }
6301 // restore src pointers
6302 mi_buf_restore(x, orig_src, orig_pre);
6303 }
6304
Urvang Joshi454280d2016-10-14 16:51:44 -07006305 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6306 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006307#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006308 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006309#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006310 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006311#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006312 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313
6314 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006315 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316 mode_mv[this_mode][ref].as_int;
6317 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006318 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006319 mode_mv[this_mode][ref].as_int;
6320 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006321 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006322 mode_mv[this_mode][ref].as_int;
6323#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006324 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6325 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006326 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006327 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6328 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006329 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006330 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6331 mi->bmi[index].pred_mv[ref].as_int;
Fergus Simpson4063a682017-02-28 16:52:22 -08006332#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006333#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006334 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006335 bsi->ref_mv[ref]->as_int;
6336 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006337 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006338 bsi->ref_mv[ref]->as_int;
6339 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006340 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006341 bsi->ref_mv[ref]->as_int;
6342#endif // CONFIG_EXT_INTER
6343 }
6344
6345 // Trap vectors that reach beyond the UMV borders
6346 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
6347 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
6348 continue;
6349
6350 if (filter_idx > 0) {
6351 BEST_SEG_INFO *ref_bsi = bsi_buf;
6352 subpelmv = 0;
6353 have_ref = 1;
6354
6355 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6356 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6357#if CONFIG_EXT_INTER
6358 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006359 have_ref &=
6360 ((mode_mv[this_mode][ref].as_int ==
6361 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6362 (bsi->ref_mv[ref]->as_int ==
6363 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364 else
6365#endif // CONFIG_EXT_INTER
6366 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006367 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006368 }
6369
Urvang Joshi454280d2016-10-14 16:51:44 -07006370 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006371
6372 if (filter_idx > 1 && !subpelmv && !have_ref) {
6373 ref_bsi = bsi_buf + 1;
6374 have_ref = 1;
6375 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6376#if CONFIG_EXT_INTER
6377 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006378 have_ref &=
6379 ((mode_mv[this_mode][ref].as_int ==
6380 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6381 (bsi->ref_mv[ref]->as_int ==
6382 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383 else
6384#endif // CONFIG_EXT_INTER
6385 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006386 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006387
Urvang Joshi454280d2016-10-14 16:51:44 -07006388 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006389 }
6390
6391 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006392 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006393#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006394 bsi->rdstat[index][mode_idx].byrate =
6395 ref_bsi->rdstat[index][mode_idx].byrate;
6396 bsi->rdstat[index][mode_idx].bdist =
6397 ref_bsi->rdstat[index][mode_idx].bdist;
6398 bsi->rdstat[index][mode_idx].bsse =
6399 ref_bsi->rdstat[index][mode_idx].bsse;
6400 bsi->rdstat[index][mode_idx].brate +=
6401 ref_bsi->rdstat[index][mode_idx].byrate;
6402 bsi->rdstat[index][mode_idx].eobs =
6403 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006404
Urvang Joshi454280d2016-10-14 16:51:44 -07006405 bsi->rdstat[index][mode_idx].brdcost =
6406 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6407 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006408
Urvang Joshi454280d2016-10-14 16:51:44 -07006409 memcpy(bsi->rdstat[index][mode_idx].ta,
6410 ref_bsi->rdstat[index][mode_idx].ta,
6411 sizeof(bsi->rdstat[index][mode_idx].ta));
6412 memcpy(bsi->rdstat[index][mode_idx].tl,
6413 ref_bsi->rdstat[index][mode_idx].tl,
6414 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006415#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006416 memcpy(&bsi->rdstat[index][mode_idx],
6417 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Fergus Simpson4063a682017-02-28 16:52:22 -08006418#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006419 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006420 bsi->rdstat[index + 1][mode_idx].eobs =
6421 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006422 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006423 bsi->rdstat[index + 2][mode_idx].eobs =
6424 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006425
Urvang Joshi454280d2016-10-14 16:51:44 -07006426 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006427#if CONFIG_REF_MV
6428 // If the NEWMV mode is using the same motion vector as the
6429 // NEARESTMV mode, skip the rest rate-distortion calculations
6430 // and use the inferred motion vector modes.
6431 if (this_mode == NEWMV) {
6432 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006433 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006434 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006435 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006436 bsi->ref_mv[1]->as_int)
6437 continue;
6438 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006439 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006440 bsi->ref_mv[0]->as_int)
6441 continue;
6442 }
6443 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006444#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006445 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006446 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006447#if CONFIG_PVQ
6448 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006449#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006450 }
6451 continue;
6452 }
6453 }
6454
Yushin Choab44fd12017-01-09 16:06:53 -08006455 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006456 cpi, x, bsi->segment_rd - this_segment_rd, index,
6457 &bsi->rdstat[index][mode_idx].byrate,
6458 &bsi->rdstat[index][mode_idx].bdist,
6459 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6460 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006461
Urvang Joshi454280d2016-10-14 16:51:44 -07006462 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6463 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6464 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6465 bsi->rdstat[index][mode_idx].brate +=
6466 bsi->rdstat[index][mode_idx].byrate;
6467 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006468 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006469 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006470 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006471 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006472 }
6473
Urvang Joshi454280d2016-10-14 16:51:44 -07006474 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006475#if CONFIG_REF_MV
6476 // If the NEWMV mode is using the same motion vector as the
6477 // NEARESTMV mode, skip the rest rate-distortion calculations
6478 // and use the inferred motion vector modes.
6479 if (this_mode == NEWMV) {
6480 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006481 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006482 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006483 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006484 bsi->ref_mv[1]->as_int)
6485 continue;
6486 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006487 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006488 bsi->ref_mv[0]->as_int)
6489 continue;
6490 }
6491 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006492#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006493 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006494 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006495
6496#if CONFIG_PVQ
6497 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006498#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006499 }
6500 } /*for each 4x4 mode*/
6501
Urvang Joshi454280d2016-10-14 16:51:44 -07006502 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006503 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);
Fergus Simpson4063a682017-02-28 16:52:22 -08006514#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006515 return INT64_MAX;
6516 }
6517
6518 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006519 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6520 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006521#if CONFIG_PVQ
6522 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006523#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006524
6525#if CONFIG_EXT_INTER
6526 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006527 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006528 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006529 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006530#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006531 set_and_cost_bmi_mvs(
6532 cpi, x, xd, index, mode_selected, mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006533#if CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006534 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006535#else
David Barker45390c12017-02-20 14:44:40 +00006536 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006537#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006538 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006539
Urvang Joshi454280d2016-10-14 16:51:44 -07006540 br += bsi->rdstat[index][mode_idx].brate;
6541 bd += bsi->rdstat[index][mode_idx].bdist;
6542 block_sse += bsi->rdstat[index][mode_idx].bsse;
6543 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6544 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545
6546 if (this_segment_rd > bsi->segment_rd) {
6547 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006548 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006549#if CONFIG_EXT_INTER
6550 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6551#else
6552 for (midx = 0; midx < INTER_MODES; ++midx)
6553#endif // CONFIG_EXT_INTER
6554 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6555 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006556#if CONFIG_PVQ
6557 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006558#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006559 return INT64_MAX;
6560 }
6561 }
6562 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006563#if CONFIG_PVQ
6564 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006565#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006566
6567 bsi->r = br;
6568 bsi->d = bd;
6569 bsi->segment_yrate = segmentyrate;
6570 bsi->segment_rd = this_segment_rd;
6571 bsi->sse = block_sse;
6572
6573 // update the coding decisions
6574 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6575
Yushin Cho7a428ba2017-01-12 16:28:49 -08006576#if CONFIG_DAALA_DIST
6577 {
6578 const int src_stride = p->src.stride;
6579 const int dst_stride = pd->dst.stride;
6580 uint8_t *src = p->src.buf;
6581 uint8_t pred[8 * 8];
6582 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
6583 int use_activity_masking = 0;
6584 int qm = OD_HVS_QM;
6585#if CONFIG_PVQ
6586 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08006587#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006588
6589 for (idy = 0; idy < 2; idy += num_4x4_blocks_high)
6590 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6591 int i = idy * 2 + idx;
6592 int j, m;
6593 uint8_t *dst_init = &pd->dst.buf[(idy * dst_stride + idx) * 4];
6594
6595 av1_build_inter_predictor_sub8x8(xd, 0, i, idy, idx, mi_row, mi_col);
6596 // Save predicted pixels for use later.
6597 for (j = 0; j < num_4x4_blocks_high * 4; j++)
6598 for (m = 0; m < num_4x4_blocks_wide * 4; m++)
6599 pred[(idy * 4 + j) * 8 + idx * 4 + m] =
6600 dst_init[j * dst_stride + m];
6601
6602 // Do xform and quant to get decoded pixels.
6603 {
6604 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6605 const int txb_height = max_block_high(xd, plane_bsize, 0);
6606 int idx_, idy_;
6607
6608 for (idy_ = 0; idy_ < txb_height; idy_++) {
6609 for (idx_ = 0; idx_ < txb_width; idx_++) {
6610 int block;
6611 int coeff_ctx = 0;
6612 const tran_low_t *dqcoeff;
6613 uint16_t eob;
6614 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6615 INV_TXFM_PARAM inv_txfm_param;
6616 uint8_t *dst = dst_init + (idy_ * dst_stride + idx_) * 4;
6617
6618 block = i + (idy_ * 2 + idx_);
6619
6620 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6621 eob = p->eobs[block];
6622
6623 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
6624 BLOCK_8X8, TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
6625
6626 inv_txfm_param.tx_type =
6627 get_tx_type(plane_type, xd, block, TX_4X4);
6628 inv_txfm_param.tx_size = TX_4X4;
6629 inv_txfm_param.eob = eob;
6630 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
6631
6632#if CONFIG_PVQ
6633 {
6634 int i2, j2;
6635
6636 for (j2 = 0; j2 < 4; j2++)
6637 for (i2 = 0; i2 < 4; i2++) dst[j2 * dst_stride + i2] = 0;
6638 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006639#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006640 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
6641 }
6642 }
6643 }
6644 }
6645
6646 // Daala-defined distortion computed for 1) predicted pixels and
6647 // 2) decoded pixels of the block of 8x8 pixels
6648 bsi->sse = av1_daala_dist(src, src_stride, pred, 8, TX_8X8, qm,
6649 use_activity_masking, x->qindex)
6650 << 4;
6651
6652 bsi->d = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, TX_8X8,
6653 qm, use_activity_masking, x->qindex)
6654 << 4;
6655 }
6656#endif // CONFIG_DAALA_DIST
6657
Yaowu Xuc27fc142016-08-22 16:08:15 -07006658 if (bsi->segment_rd > best_rd) return INT64_MAX;
6659 /* set it to the best */
6660 for (idx = 0; idx < 4; idx++) {
6661 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6662 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6663 if (has_second_ref(mbmi))
6664 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
6665#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006666 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006667 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006668 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08006669#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006670#if CONFIG_EXT_INTER
6671 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6672 if (has_second_rf)
6673 mi->bmi[idx].ref_mv[1].as_int =
6674 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6675#endif // CONFIG_EXT_INTER
6676 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6677 mi->bmi[idx].as_mode = bsi->modes[idx];
6678 }
6679
6680 /*
6681 * used to set mbmi->mv.as_int
6682 */
6683 *returntotrate = bsi->r;
6684 *returndistortion = bsi->d;
6685 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006686 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006687 *psse = bsi->sse;
6688 mbmi->mode = bsi->modes[3];
6689
6690 return bsi->segment_rd;
6691}
6692
Yaowu Xuf883b422016-08-30 14:01:10 -07006693static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006694 const MACROBLOCKD *xd, int segment_id,
6695 unsigned int *ref_costs_single,
6696 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006697 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006698 int seg_ref_active =
6699 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6700 if (seg_ref_active) {
6701 memset(ref_costs_single, 0,
6702 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6703 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6704 *comp_mode_p = 128;
6705 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006706 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6707 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006708
6709 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006710 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006711 *comp_mode_p = comp_inter_p;
6712 } else {
6713 *comp_mode_p = 128;
6714 }
6715
Yaowu Xuf883b422016-08-30 14:01:10 -07006716 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006717
6718 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006719 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6720 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006721#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006722 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6723 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6724 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006725#endif // CONFIG_EXT_REFS
6726
Yaowu Xuf883b422016-08-30 14:01:10 -07006727 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006728
6729 ref_costs_single[LAST_FRAME] =
6730#if CONFIG_EXT_REFS
6731 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6732 ref_costs_single[BWDREF_FRAME] =
6733#endif // CONFIG_EXT_REFS
6734 ref_costs_single[GOLDEN_FRAME] =
6735 ref_costs_single[ALTREF_FRAME] = base_cost;
6736
6737#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006738 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6739 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6740 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6741 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6742 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6743 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006744
Yaowu Xuf883b422016-08-30 14:01:10 -07006745 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6746 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6747 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6748 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006749
Yaowu Xuf883b422016-08-30 14:01:10 -07006750 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6751 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006752
Yaowu Xuf883b422016-08-30 14:01:10 -07006753 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6754 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006755
Yaowu Xuf883b422016-08-30 14:01:10 -07006756 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6757 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006759 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6760 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6761 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006762
Yaowu Xuf883b422016-08-30 14:01:10 -07006763 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6764 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006765#endif // CONFIG_EXT_REFS
6766 } else {
6767 ref_costs_single[LAST_FRAME] = 512;
6768#if CONFIG_EXT_REFS
6769 ref_costs_single[LAST2_FRAME] = 512;
6770 ref_costs_single[LAST3_FRAME] = 512;
6771 ref_costs_single[BWDREF_FRAME] = 512;
6772#endif // CONFIG_EXT_REFS
6773 ref_costs_single[GOLDEN_FRAME] = 512;
6774 ref_costs_single[ALTREF_FRAME] = 512;
6775 }
6776
6777 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006778 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006779#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006780 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6781 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6782 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006783#endif // CONFIG_EXT_REFS
6784
Yaowu Xuf883b422016-08-30 14:01:10 -07006785 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006786
6787 ref_costs_comp[LAST_FRAME] =
6788#if CONFIG_EXT_REFS
6789 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6790#endif // CONFIG_EXT_REFS
6791 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6792
6793#if CONFIG_EXT_REFS
6794 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6795#endif // CONFIG_EXT_REFS
6796
6797#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006798 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6799 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6800 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6801 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006802
Yaowu Xuf883b422016-08-30 14:01:10 -07006803 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6804 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006805
Yaowu Xuf883b422016-08-30 14:01:10 -07006806 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6807 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006808
6809 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6810 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006811 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6812 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006813#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006814 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6815 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006816#endif // CONFIG_EXT_REFS
6817 } else {
6818 ref_costs_comp[LAST_FRAME] = 512;
6819#if CONFIG_EXT_REFS
6820 ref_costs_comp[LAST2_FRAME] = 512;
6821 ref_costs_comp[LAST3_FRAME] = 512;
6822 ref_costs_comp[BWDREF_FRAME] = 512;
6823 ref_costs_comp[ALTREF_FRAME] = 512;
6824#endif // CONFIG_EXT_REFS
6825 ref_costs_comp[GOLDEN_FRAME] = 512;
6826 }
6827 }
6828}
6829
6830static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6831 int mode_index,
6832 int64_t comp_pred_diff[REFERENCE_MODES],
6833 int skippable) {
6834 MACROBLOCKD *const xd = &x->e_mbd;
6835
6836 // Take a snapshot of the coding context so it can be
6837 // restored if we decide to encode this way
6838 ctx->skip = x->skip;
6839 ctx->skippable = skippable;
6840 ctx->best_mode_index = mode_index;
6841 ctx->mic = *xd->mi[0];
6842 ctx->mbmi_ext = *x->mbmi_ext;
6843 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6844 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6845 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6846}
6847
clang-format55ce9e02017-02-15 22:27:12 -08006848static void setup_buffer_inter(
6849 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6850 BLOCK_SIZE block_size, int mi_row, int mi_col,
6851 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6852 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6853 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006854 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006855 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6856 MACROBLOCKD *const xd = &x->e_mbd;
6857 MODE_INFO *const mi = xd->mi[0];
6858 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6859 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6860 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6861
6862 assert(yv12 != NULL);
6863
6864 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6865 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006866 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006867
6868 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006869 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006870 cm, xd, mi, ref_frame,
6871#if CONFIG_REF_MV
6872 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6873#if CONFIG_EXT_INTER
6874 mbmi_ext->compound_mode_context,
6875#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08006876#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006877 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6878
6879 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006880 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6881 &frame_nearest_mv[ref_frame],
6882 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006883
Jingning Han271bb2c2016-12-14 12:34:46 -08006884// Further refinement that is encode side only to test the top few candidates
6885// in full and choose the best as the centre point for subsequent searches.
6886// The current implementation doesn't support scaling.
6887#if CONFIG_CB4X4
6888 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6889 block_size);
6890#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006891 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6892 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6893 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006894#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006895}
6896
Urvang Joshi52648442016-10-13 17:27:51 -07006897static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6898 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006899#if CONFIG_EXT_INTER
6900 int ref_idx, int mv_idx,
6901#endif // CONFIG_EXT_INTER
6902 int *rate_mv) {
6903 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006904 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006905 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6906 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6907 int bestsme = INT_MAX;
6908 int step_param;
6909 int sadpb = x->sadperbit16;
6910 MV mvp_full;
6911#if CONFIG_EXT_INTER
6912 int ref = mbmi->ref_frame[ref_idx];
6913 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
6914#else
6915 int ref = mbmi->ref_frame[0];
6916 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6917 int ref_idx = 0;
6918#endif // CONFIG_EXT_INTER
6919
6920 int tmp_col_min = x->mv_col_min;
6921 int tmp_col_max = x->mv_col_max;
6922 int tmp_row_min = x->mv_row_min;
6923 int tmp_row_max = x->mv_row_max;
6924 int cost_list[5];
6925
6926 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006927 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006928
6929 MV pred_mv[3];
6930 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6931 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6932 pred_mv[2] = x->pred_mv[ref];
6933
Yaowu Xuc27fc142016-08-22 16:08:15 -07006934 if (scaled_ref_frame) {
6935 int i;
6936 // Swap out the reference frame for a version that's been scaled to
6937 // match the resolution of the current frame, allowing the existing
6938 // motion search code to be used without additional modifications.
6939 for (i = 0; i < MAX_MB_PLANE; i++)
6940 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6941
Yaowu Xuf883b422016-08-30 14:01:10 -07006942 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006943 }
6944
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006945 av1_set_mv_search_range(x, &ref_mv);
6946
6947#if CONFIG_REF_MV
6948 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08006949#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006950
Yaowu Xuc27fc142016-08-22 16:08:15 -07006951 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006952 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006953 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6954 // Take wtd average of the step_params based on the last frame's
6955 // max mv magnitude and that based on the best ref mvs of the current
6956 // block for the given reference.
6957 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006958 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006959 2;
6960 } else {
6961 step_param = cpi->mv_step_param;
6962 }
6963
6964 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6965 int boffset =
6966 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006967 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6968 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006969 }
6970
6971 if (cpi->sf.adaptive_motion_search) {
6972 int bwl = b_width_log2_lookup[bsize];
6973 int bhl = b_height_log2_lookup[bsize];
6974 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6975
6976 if (tlevel < 5) step_param += 2;
6977
6978 // prev_mv_sad is not setup for dynamically scaled frames.
6979 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6980 int i;
6981 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6982 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6983 x->pred_mv[ref].row = 0;
6984 x->pred_mv[ref].col = 0;
6985 x->best_mv.as_int = INVALID_MV;
6986
6987 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006988 int j;
6989 for (j = 0; j < MAX_MB_PLANE; ++j)
6990 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006991 }
6992 return;
6993 }
6994 }
6995 }
6996 }
6997
Yaowu Xuf883b422016-08-30 14:01:10 -07006998 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006999
Yue Chene9638cc2016-10-10 12:37:54 -07007000#if CONFIG_MOTION_VAR
7001 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
7002 mvp_full = mbmi->mv[0].as_mv;
7003 else
7004#endif // CONFIG_MOTION_VAR
7005 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007006
7007 mvp_full.col >>= 3;
7008 mvp_full.row >>= 3;
7009
7010 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
7011
Yue Chene9638cc2016-10-10 12:37:54 -07007012#if CONFIG_MOTION_VAR
7013 switch (mbmi->motion_mode) {
7014 case SIMPLE_TRANSLATION:
7015#endif // CONFIG_MOTION_VAR
7016 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
7017 sadpb, cond_cost_list(cpi, cost_list),
7018 &ref_mv, INT_MAX, 1);
7019#if CONFIG_MOTION_VAR
7020 break;
7021 case OBMC_CAUSAL:
7022 bestsme = av1_obmc_full_pixel_diamond(
7023 cpi, x, &mvp_full, step_param, sadpb,
7024 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7025 &(x->best_mv.as_mv), 0);
7026 break;
7027 default: assert("Invalid motion mode!\n");
7028 }
7029#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007030
7031 x->mv_col_min = tmp_col_min;
7032 x->mv_col_max = tmp_col_max;
7033 x->mv_row_min = tmp_row_min;
7034 x->mv_row_max = tmp_row_max;
7035
7036 if (bestsme < INT_MAX) {
7037 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07007038#if CONFIG_MOTION_VAR
7039 switch (mbmi->motion_mode) {
7040 case SIMPLE_TRANSLATION:
7041#endif // CONFIG_MOTION_VAR
7042 if (cpi->sf.use_upsampled_references) {
7043 int best_mv_var;
7044 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
7045 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007046 const int pw = block_size_wide[bsize];
7047 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07007048 // Use up-sampled reference frames.
7049 struct macroblockd_plane *const pd = &xd->plane[0];
7050 struct buf_2d backup_pred = pd->pre[ref_idx];
7051 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007052
Yue Chene9638cc2016-10-10 12:37:54 -07007053 // Set pred for Y plane
7054 setup_pred_plane(
7055 &pd->pre[ref_idx], upsampled_ref->y_buffer,
7056 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
7057 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
7058 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007059
Yue Chene9638cc2016-10-10 12:37:54 -07007060 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007061 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7062 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7063 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7064 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
7065 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007066
Yue Chene9638cc2016-10-10 12:37:54 -07007067 if (try_second) {
7068 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
7069 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
7070 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
7071 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
7072 int this_var;
7073 MV best_mv = x->best_mv.as_mv;
7074
7075 x->best_mv = x->second_best_mv;
7076 if (x->best_mv.as_mv.row * 8 <= maxr &&
7077 x->best_mv.as_mv.row * 8 >= minr &&
7078 x->best_mv.as_mv.col * 8 <= maxc &&
7079 x->best_mv.as_mv.col * 8 >= minc) {
7080 this_var = cpi->find_fractional_mv_step(
7081 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7082 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7083 cpi->sf.mv.subpel_iters_per_step,
7084 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
7085 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
7086 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
7087 x->best_mv.as_mv = best_mv;
7088 }
7089 }
7090
7091 // Restore the reference frames.
7092 pd->pre[ref_idx] = backup_pred;
7093 } else {
7094 cpi->find_fractional_mv_step(
7095 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7096 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7097 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7098 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
7099 0);
7100 }
7101#if CONFIG_MOTION_VAR
7102 break;
7103 case OBMC_CAUSAL:
7104 av1_find_best_obmc_sub_pixel_tree_up(
7105 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
7106 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7107 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7108 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
7109 cpi->sf.use_upsampled_references);
7110 break;
7111 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07007112 }
Yue Chene9638cc2016-10-10 12:37:54 -07007113#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007114 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007115 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
7116 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007117
Yue Chene9638cc2016-10-10 12:37:54 -07007118#if CONFIG_MOTION_VAR
7119 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
7120#else
7121 if (cpi->sf.adaptive_motion_search)
7122#endif // CONFIG_MOTION_VAR
7123 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007124
7125 if (scaled_ref_frame) {
7126 int i;
7127 for (i = 0; i < MAX_MB_PLANE; i++)
7128 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7129 }
7130}
7131
David Barkerac37fa32016-12-02 12:30:21 +00007132static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007133 int i;
7134 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007135 xd->plane[i].dst.buf = dst.plane[i];
7136 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007137 }
7138}
7139
Yaowu Xuc27fc142016-08-22 16:08:15 -07007140#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07007141static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007142 const uint8_t *mask, int mask_stride,
7143 BLOCK_SIZE bsize, int mi_row, int mi_col,
7144 int_mv *tmp_mv, int *rate_mv, int ref_idx,
7145 int mv_idx) {
7146 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007147 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007148 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7149 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7150 int bestsme = INT_MAX;
7151 int step_param;
7152 int sadpb = x->sadperbit16;
7153 MV mvp_full;
7154 int ref = mbmi->ref_frame[ref_idx];
7155 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
7156
7157 int tmp_col_min = x->mv_col_min;
7158 int tmp_col_max = x->mv_col_max;
7159 int tmp_row_min = x->mv_row_min;
7160 int tmp_row_max = x->mv_row_max;
7161
7162 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007163 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007164 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007165
7166 MV pred_mv[3];
7167 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7168 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7169 pred_mv[2] = x->pred_mv[ref];
7170
7171#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007172 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08007173#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07007174
7175 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007176 // Swap out the reference frame for a version that's been scaled to
7177 // match the resolution of the current frame, allowing the existing
7178 // motion search code to be used without additional modifications.
7179 for (i = 0; i < MAX_MB_PLANE; i++)
7180 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7181
Yaowu Xuf883b422016-08-30 14:01:10 -07007182 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007183 }
7184
Yaowu Xuf883b422016-08-30 14:01:10 -07007185 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007186
7187 // Work out the size of the first step in the mv step search.
7188 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7189 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7190 // Take wtd average of the step_params based on the last frame's
7191 // max mv magnitude and that based on the best ref mvs of the current
7192 // block for the given reference.
7193 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007194 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007195 2;
7196 } else {
7197 step_param = cpi->mv_step_param;
7198 }
7199
7200 // TODO(debargha): is show_frame needed here?
7201 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7202 int boffset =
7203 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007204 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7205 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007206 }
7207
7208 if (cpi->sf.adaptive_motion_search) {
7209 int bwl = b_width_log2_lookup[bsize];
7210 int bhl = b_height_log2_lookup[bsize];
7211 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7212
7213 if (tlevel < 5) step_param += 2;
7214
7215 // prev_mv_sad is not setup for dynamically scaled frames.
7216 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007217 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7218 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7219 x->pred_mv[ref].row = 0;
7220 x->pred_mv[ref].col = 0;
7221 tmp_mv->as_int = INVALID_MV;
7222
7223 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007224 int j;
7225 for (j = 0; j < MAX_MB_PLANE; ++j)
7226 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007227 }
7228 return;
7229 }
7230 }
7231 }
7232 }
7233
7234 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7235
7236 mvp_full.col >>= 3;
7237 mvp_full.row >>= 3;
7238
Yaowu Xuf883b422016-08-30 14:01:10 -07007239 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007240 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7241 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7242 &tmp_mv->as_mv, ref_idx);
7243
7244 x->mv_col_min = tmp_col_min;
7245 x->mv_col_max = tmp_col_max;
7246 x->mv_row_min = tmp_row_min;
7247 x->mv_row_max = tmp_row_max;
7248
7249 if (bestsme < INT_MAX) {
7250 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007251 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007252 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7253 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7254 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7255 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7256 cpi->sf.use_upsampled_references);
7257 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007258 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7259 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007260
7261 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7262 x->pred_mv[ref] = tmp_mv->as_mv;
7263
7264 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007265 for (i = 0; i < MAX_MB_PLANE; i++)
7266 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7267 }
7268}
7269
Sarah Parker6fdc8532016-11-16 17:47:13 -08007270static void do_masked_motion_search_indexed(
7271 const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007272 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
7273 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int mv_idx[2],
7274 int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007275 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7276 MACROBLOCKD *xd = &x->e_mbd;
7277 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7278 BLOCK_SIZE sb_type = mbmi->sb_type;
7279 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007280 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007281
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007282 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007283
7284 if (which == 0 || which == 2)
7285 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7286 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
7287
7288 if (which == 1 || which == 2) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007289// get the negative mask
7290#if CONFIG_COMPOUND_SEGMENT
7291 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7292 const int h = block_size_high[bsize];
7293 mask = av1_get_compound_type_mask_inverse(
7294 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7295#else
7296 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
Fergus Simpson4063a682017-02-28 16:52:22 -08007297#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007298 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7299 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
7300 }
7301}
7302#endif // CONFIG_EXT_INTER
7303
7304// In some situations we want to discount tha pparent cost of a new motion
7305// vector. Where there is a subtle motion field and especially where there is
7306// low spatial complexity then it can be hard to cover the cost of a new motion
7307// vector in a single block, even if that motion vector reduces distortion.
7308// However, once established that vector may be usable through the nearest and
7309// near mv modes to reduce distortion in subsequent blocks and also improve
7310// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007311static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007312 int_mv this_mv,
7313 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7314 int ref_frame) {
7315 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7316 (this_mv.as_int != 0) &&
7317 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7318 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7319 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7320 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7321}
7322
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007323#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7324#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007325
7326// TODO(jingning): this mv clamping function should be block size dependent.
7327static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7328 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7329 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7330 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7331 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7332}
7333
7334#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007335static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007336 const BLOCK_SIZE bsize, const uint8_t *pred0,
7337 int stride0, const uint8_t *pred1, int stride1) {
7338 const struct macroblock_plane *const p = &x->plane[0];
7339 const uint8_t *src = p->src.buf;
7340 int src_stride = p->src.stride;
7341 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007342 const int bw = block_size_wide[bsize];
7343 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007344 uint32_t esq[2][4], var;
7345 int64_t tl, br;
7346
Yaowu Xuf883b422016-08-30 14:01:10 -07007347#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007348 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7349 pred0 = CONVERT_TO_BYTEPTR(pred0);
7350 pred1 = CONVERT_TO_BYTEPTR(pred1);
7351 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007352#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007353
7354 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7355 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7356 stride0, &esq[0][1]);
7357 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7358 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7359 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7360 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7361 &esq[0][3]);
7362 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7363 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7364 stride1, &esq[1][1]);
7365 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7366 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7367 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7368 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7369 &esq[1][3]);
7370 (void)var;
7371
7372 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7373 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7374 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7375 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7376 return (tl + br > 0);
7377}
7378#endif // CONFIG_EXT_INTER
7379
7380#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007381static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007382 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007383 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007384 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7385 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007386 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007387 const MACROBLOCKD *xd = &x->e_mbd;
7388 int bsl = mi_width_log2_lookup[bsize];
7389 int pred_filter_search =
7390 cpi->sf.cb_pred_filter_search
7391 ? (((mi_row + mi_col) >> bsl) +
7392 get_chessboard_index(cm->current_video_frame)) &
7393 0x1
7394 : 0;
7395 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7396 const int is_comp_pred = has_second_ref(mbmi);
7397 const int this_mode = mbmi->mode;
7398 int refs[2] = { mbmi->ref_frame[0],
7399 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007400 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007401 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007402 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7403 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7404
7405#if CONFIG_EXT_INTER
7406 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
7407 this_mode != NEW_NEWMV) ||
7408 (af == lf))
7409#else
7410 if ((this_mode != NEWMV) || (af == lf))
7411#endif // CONFIG_EXT_INTER
7412 best_filter = af;
7413 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007414 if (is_comp_pred) {
7415 if (cpi->sf.adaptive_mode_search) {
7416#if CONFIG_EXT_INTER
7417 switch (this_mode) {
7418 case NEAREST_NEARESTMV:
7419 if (single_filter[NEARESTMV][refs[0]] ==
7420 single_filter[NEARESTMV][refs[1]])
7421 best_filter = single_filter[NEARESTMV][refs[0]];
7422 break;
7423 case NEAREST_NEARMV:
7424 if (single_filter[NEARESTMV][refs[0]] ==
7425 single_filter[NEARMV][refs[1]])
7426 best_filter = single_filter[NEARESTMV][refs[0]];
7427 break;
7428 case NEAR_NEARESTMV:
7429 if (single_filter[NEARMV][refs[0]] ==
7430 single_filter[NEARESTMV][refs[1]])
7431 best_filter = single_filter[NEARMV][refs[0]];
7432 break;
7433 case NEAR_NEARMV:
7434 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7435 best_filter = single_filter[NEARMV][refs[0]];
7436 break;
7437 case ZERO_ZEROMV:
7438 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7439 best_filter = single_filter[ZEROMV][refs[0]];
7440 break;
7441 case NEW_NEWMV:
7442 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7443 best_filter = single_filter[NEWMV][refs[0]];
7444 break;
7445 case NEAREST_NEWMV:
7446 if (single_filter[NEARESTMV][refs[0]] ==
7447 single_filter[NEWMV][refs[1]])
7448 best_filter = single_filter[NEARESTMV][refs[0]];
7449 break;
7450 case NEAR_NEWMV:
7451 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7452 best_filter = single_filter[NEARMV][refs[0]];
7453 break;
7454 case NEW_NEARESTMV:
7455 if (single_filter[NEWMV][refs[0]] ==
7456 single_filter[NEARESTMV][refs[1]])
7457 best_filter = single_filter[NEWMV][refs[0]];
7458 break;
7459 case NEW_NEARMV:
7460 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7461 best_filter = single_filter[NEWMV][refs[0]];
7462 break;
7463 default:
7464 if (single_filter[this_mode][refs[0]] ==
7465 single_filter[this_mode][refs[1]])
7466 best_filter = single_filter[this_mode][refs[0]];
7467 break;
7468 }
7469#else
7470 if (single_filter[this_mode][refs[0]] ==
7471 single_filter[this_mode][refs[1]])
7472 best_filter = single_filter[this_mode][refs[0]];
7473#endif // CONFIG_EXT_INTER
7474 }
7475 }
Angie Chiang75c22092016-10-25 12:19:16 -07007476 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7477 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007478 }
7479 return best_filter;
7480}
Fergus Simpson4063a682017-02-28 16:52:22 -08007481#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482
7483#if CONFIG_EXT_INTER
7484// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07007485static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007486 const BLOCK_SIZE bsize, const uint8_t *const p0,
7487 const uint8_t *const p1, int *const best_wedge_sign,
7488 int *const best_wedge_index) {
7489 const MACROBLOCKD *const xd = &x->e_mbd;
7490 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007491 const int bw = block_size_wide[bsize];
7492 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007493 const int N = bw * bh;
7494 int rate;
7495 int64_t dist;
7496 int64_t rd, best_rd = INT64_MAX;
7497 int wedge_index;
7498 int wedge_sign;
7499 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7500 const uint8_t *mask;
7501 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007502#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007503 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7504 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7505#else
7506 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007507#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007508
7509 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7510 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7511 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7512 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7513
7514 int64_t sign_limit;
7515
Yaowu Xuf883b422016-08-30 14:01:10 -07007516#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007517 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007518 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007519 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007520 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007521 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007522 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007523 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7524 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007525#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007526 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007527 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7528 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7529 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007530 }
7531
Yaowu Xuf883b422016-08-30 14:01:10 -07007532 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7533 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007534 (1 << WEDGE_WEIGHT_BITS) / 2;
7535
Jingning Han61418bb2017-01-23 17:12:48 -08007536 if (N < 64)
7537 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7538 else
7539 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007540
7541 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007542 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007543
7544 // TODO(jingning): Make sse2 functions support N = 16 case
7545 if (N < 64)
7546 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7547 else
7548 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007549
Yaowu Xuf883b422016-08-30 14:01:10 -07007550 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007551 if (N < 64)
7552 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7553 else
7554 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007555 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7556
7557 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7558 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7559
7560 if (rd < best_rd) {
7561 *best_wedge_index = wedge_index;
7562 *best_wedge_sign = wedge_sign;
7563 best_rd = rd;
7564 }
7565 }
7566
7567 return best_rd;
7568}
7569
7570// Choose the best wedge index the specified sign
7571static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007572 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007573 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7574 const int wedge_sign, int *const best_wedge_index) {
7575 const MACROBLOCKD *const xd = &x->e_mbd;
7576 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007577 const int bw = block_size_wide[bsize];
7578 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007579 const int N = bw * bh;
7580 int rate;
7581 int64_t dist;
7582 int64_t rd, best_rd = INT64_MAX;
7583 int wedge_index;
7584 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7585 const uint8_t *mask;
7586 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007587#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007588 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7589 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7590#else
7591 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007592#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007593
7594 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7595 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7596
Yaowu Xuf883b422016-08-30 14:01:10 -07007597#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007598 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007599 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007600 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007601 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007602 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7603 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007604#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007605 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007606 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7607 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007608 }
7609
7610 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007611 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007612 if (N < 64)
7613 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7614 else
7615 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007616 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7617
7618 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7619 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7620
7621 if (rd < best_rd) {
7622 *best_wedge_index = wedge_index;
7623 best_rd = rd;
7624 }
7625 }
7626
7627 return best_rd;
7628}
7629
Yaowu Xuf883b422016-08-30 14:01:10 -07007630static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007631 const MACROBLOCK *const x,
7632 const BLOCK_SIZE bsize,
7633 const uint8_t *const p0,
7634 const uint8_t *const p1) {
7635 const MACROBLOCKD *const xd = &x->e_mbd;
7636 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007637 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007638
7639 int64_t rd;
7640 int wedge_index = -1;
7641 int wedge_sign = 0;
7642
Sarah Parker42d96102017-01-31 21:05:27 -08007643 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007644
7645 if (cpi->sf.fast_wedge_sign_estimate) {
7646 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7647 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7648 } else {
7649 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7650 }
7651
Sarah Parker6fdc8532016-11-16 17:47:13 -08007652 mbmi->interinter_compound_data.wedge_sign = wedge_sign;
7653 mbmi->interinter_compound_data.wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007654 return rd;
7655}
7656
Sarah Parker569edda2016-12-14 14:57:38 -08007657#if CONFIG_COMPOUND_SEGMENT
7658static int64_t pick_interinter_seg_mask(const AV1_COMP *const cpi,
7659 const MACROBLOCK *const x,
7660 const BLOCK_SIZE bsize,
7661 const uint8_t *const p0,
7662 const uint8_t *const p1) {
7663 const MACROBLOCKD *const xd = &x->e_mbd;
7664 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7665 const struct buf_2d *const src = &x->plane[0].src;
7666 const int bw = block_size_wide[bsize];
7667 const int bh = block_size_high[bsize];
7668 const int N = bw * bh;
7669 int rate;
7670 uint64_t sse;
7671 int64_t dist;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007672 int rd0;
7673 SEG_MASK_TYPE cur_mask_type;
7674 int64_t best_rd = INT64_MAX;
7675 SEG_MASK_TYPE best_mask_type = 0;
Sarah Parker569edda2016-12-14 14:57:38 -08007676#if CONFIG_AOM_HIGHBITDEPTH
7677 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7678 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7679#else
7680 const int bd_round = 0;
7681#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker409c0bb2017-01-04 11:29:07 -08007682 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Sarah Parker569edda2016-12-14 14:57:38 -08007683 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7684 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7685 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7686
7687#if CONFIG_AOM_HIGHBITDEPTH
7688 if (hbd) {
7689 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7690 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7691 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7692 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7693 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7694 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7695 } else // NOLINT
7696#endif // CONFIG_AOM_HIGHBITDEPTH
7697 {
7698 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7699 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7700 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7701 }
7702
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007703 // try each mask type and its inverse
7704 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007705// build mask and inverse
7706#if CONFIG_AOM_HIGHBITDEPTH
7707 if (hbd)
7708 build_compound_seg_mask_highbd(
7709 comp_data->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7710 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7711 else
7712#endif // CONFIG_AOM_HIGHBITDEPTH
7713 build_compound_seg_mask(comp_data->seg_mask, cur_mask_type, p0, bw, p1,
7714 bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007715
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007716 // compute rd for mask
7717 sse = av1_wedge_sse_from_residuals(r1, d10, comp_data->seg_mask, N);
7718 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007719
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007720 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7721 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007722
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007723 if (rd0 < best_rd) {
7724 best_mask_type = cur_mask_type;
7725 best_rd = rd0;
7726 }
7727 }
Sarah Parker569edda2016-12-14 14:57:38 -08007728
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007729 // make final mask
7730 comp_data->mask_type = best_mask_type;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007731#if CONFIG_AOM_HIGHBITDEPTH
7732 if (hbd)
7733 build_compound_seg_mask_highbd(
7734 comp_data->seg_mask, comp_data->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7735 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7736 else
7737#endif // CONFIG_AOM_HIGHBITDEPTH
7738 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, p0, bw,
7739 p1, bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007740
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007741 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007742}
7743#endif // CONFIG_COMPOUND_SEGMENT
7744
Yaowu Xuf883b422016-08-30 14:01:10 -07007745static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007746 const MACROBLOCK *const x,
7747 const BLOCK_SIZE bsize,
7748 const uint8_t *const p0,
7749 const uint8_t *const p1) {
7750 const MACROBLOCKD *const xd = &x->e_mbd;
7751 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7752
7753 int64_t rd;
7754 int wedge_index = -1;
7755
7756 assert(is_interintra_wedge_used(bsize));
7757
7758 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7759
7760 mbmi->interintra_wedge_sign = 0;
7761 mbmi->interintra_wedge_index = wedge_index;
7762 return rd;
7763}
Sarah Parker6fdc8532016-11-16 17:47:13 -08007764
7765static int interinter_compound_motion_search(const AV1_COMP *const cpi,
7766 MACROBLOCK *x,
7767 const BLOCK_SIZE bsize,
7768 const int this_mode, int mi_row,
7769 int mi_col) {
7770 const MACROBLOCKD *const xd = &x->e_mbd;
7771 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7772 int_mv tmp_mv[2];
7773 int rate_mvs[2], tmp_rate_mv = 0;
7774 if (this_mode == NEW_NEWMV) {
7775 int mv_idxs[2] = { 0, 0 };
7776 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7777 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7778 mv_idxs, 2);
7779 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7780 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7781 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7782 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7783 int mv_idxs[2] = { 0, 0 };
7784 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7785 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7786 mv_idxs, 0);
7787 tmp_rate_mv = rate_mvs[0];
7788 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7789 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7790 int mv_idxs[2] = { 0, 0 };
7791 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7792 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7793 mv_idxs, 1);
7794 tmp_rate_mv = rate_mvs[1];
7795 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7796 }
7797 return tmp_rate_mv;
7798}
7799
Sarah Parker569edda2016-12-14 14:57:38 -08007800#if CONFIG_COMPOUND_SEGMENT
7801// TODO(sarahparker) this and build_and_cost_compound_wedge can probably
7802// be combined in a refactor
7803static int64_t build_and_cost_compound_seg(
7804 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7805 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7806 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7807 int *strides, int mi_row, int mi_col) {
7808 MACROBLOCKD *xd = &x->e_mbd;
7809 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7810 int rate_sum;
7811 int64_t dist_sum;
7812 int64_t best_rd_cur = INT64_MAX;
7813 int64_t rd = INT64_MAX;
7814 int tmp_skip_txfm_sb;
7815 int64_t tmp_skip_sse_sb;
7816
7817 best_rd_cur = pick_interinter_seg_mask(cpi, x, bsize, *preds0, *preds1);
7818 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7819
Sarah Parker2e604882017-01-17 17:31:25 -08007820 if (have_newmv_in_inter_mode(this_mode) &&
7821 use_masked_motion_search(COMPOUND_SEG)) {
Sarah Parker569edda2016-12-14 14:57:38 -08007822 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7823 mi_row, mi_col);
7824 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
7825 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7826 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7827 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7828 if (rd < best_rd_cur) {
7829 best_rd_cur = rd;
7830 } else {
7831 mbmi->mv[0].as_int = cur_mv[0].as_int;
7832 mbmi->mv[1].as_int = cur_mv[1].as_int;
7833 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007834 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7835#if CONFIG_SUPERTX
7836 0, 0,
7837#endif // CONFIG_SUPERTX
7838 preds0, strides, preds1,
7839 strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007840 }
7841 av1_subtract_plane(x, bsize, 0);
7842 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7843 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7844 if (rd != INT64_MAX)
7845 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7846 best_rd_cur = rd;
7847
7848 } else {
David Barker426a9972017-01-27 11:03:11 +00007849 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7850#if CONFIG_SUPERTX
7851 0, 0,
7852#endif // CONFIG_SUPERTX
7853 preds0, strides, preds1, strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007854 av1_subtract_plane(x, bsize, 0);
7855 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7856 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7857 if (rd != INT64_MAX)
7858 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7859 best_rd_cur = rd;
7860 }
7861 return best_rd_cur;
7862}
7863#endif // CONFIG_COMPOUND_SEGMENT
7864
Sarah Parker6fdc8532016-11-16 17:47:13 -08007865static int64_t build_and_cost_compound_wedge(
7866 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7867 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
David Barkerac37fa32016-12-02 12:30:21 +00007868 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7869 int *strides, int mi_row, int mi_col) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007870 MACROBLOCKD *xd = &x->e_mbd;
7871 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7872 int rate_sum;
7873 int64_t dist_sum;
7874 int64_t best_rd_cur = INT64_MAX;
7875 int64_t rd = INT64_MAX;
7876 int tmp_skip_txfm_sb;
7877 int64_t tmp_skip_sse_sb;
7878
7879 best_rd_cur = pick_interinter_wedge(cpi, x, bsize, *preds0, *preds1);
7880 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7881
Sarah Parker2e604882017-01-17 17:31:25 -08007882 if (have_newmv_in_inter_mode(this_mode) &&
7883 use_masked_motion_search(COMPOUND_WEDGE)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007884 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7885 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00007886 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007887 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7888 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7889 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007890 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007891 mbmi->mv[0].as_int = cur_mv[0].as_int;
7892 mbmi->mv[1].as_int = cur_mv[1].as_int;
7893 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007894 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7895#if CONFIG_SUPERTX
7896 0, 0,
7897#endif // CONFIG_SUPERTX
7898 preds0, strides, preds1,
7899 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007900 }
7901 av1_subtract_plane(x, bsize, 0);
7902 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7903 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7904 if (rd != INT64_MAX)
7905 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7906 best_rd_cur = rd;
7907
7908 } else {
David Barker426a9972017-01-27 11:03:11 +00007909 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7910#if CONFIG_SUPERTX
7911 0, 0,
7912#endif // CONFIG_SUPERTX
7913 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007914 av1_subtract_plane(x, bsize, 0);
7915 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7916 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7917 if (rd != INT64_MAX)
7918 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7919 best_rd_cur = rd;
7920 }
7921 return best_rd_cur;
7922}
Yaowu Xuc27fc142016-08-22 16:08:15 -07007923#endif // CONFIG_EXT_INTER
7924
Fergus Simpson073c6f32017-02-17 12:13:48 -08007925typedef struct {
7926#if CONFIG_MOTION_VAR
7927 // Inter prediction buffers and respective strides
7928 uint8_t *above_pred_buf[MAX_MB_PLANE];
7929 int above_pred_stride[MAX_MB_PLANE];
7930 uint8_t *left_pred_buf[MAX_MB_PLANE];
7931 int left_pred_stride[MAX_MB_PLANE];
7932#endif // CONFIG_MOTION_VAR
7933#if CONFIG_EXT_INTER
7934 // Pointer to array of motion vectors to use for each ref and their rates
7935 // Should point to first of 2 arrays in 2D array
7936 int_mv (*single_newmvs)[TOTAL_REFS_PER_FRAME];
7937 int (*single_newmvs_rate)[TOTAL_REFS_PER_FRAME];
7938 // Pointers costs of compound inter-intra and inter-inter predictions
7939 int *compmode_interintra_cost;
7940 int *compmode_interinter_cost;
7941 // Pointer to array of predicted rate-distortion
7942 // Should point to first of 2 arrays in 2D array
7943 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
7944#else // CONFIG_EXT_INTER
7945 // The result motion vector for each ref from the single prediction mode
7946 // it is a local variable of handle_inter_mode if CONFIG_EXT_INTER
7947 int_mv *single_newmv;
7948#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007949 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007950} HandleInterModeArgs;
7951
Fergus Simpson45509632017-02-22 15:30:50 -08007952static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7953 const BLOCK_SIZE bsize,
7954 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
7955 const int mi_row, const int mi_col,
7956 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007957 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007958 const MACROBLOCKD *const xd = &x->e_mbd;
7959 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7960 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7961 const int is_comp_pred = has_second_ref(mbmi);
7962 const PREDICTION_MODE this_mode = mbmi->mode;
7963#if CONFIG_EXT_INTER
7964 const int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
7965 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7966#endif // CONFIG_EXT_INTER
7967 int_mv *const frame_mv = mode_mv[this_mode];
7968 const int refs[2] = { mbmi->ref_frame[0],
7969 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7970 int i;
7971
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007972 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007973
7974 if (is_comp_pred) {
7975#if CONFIG_EXT_INTER
7976 for (i = 0; i < 2; ++i) {
7977 single_newmv[refs[i]].as_int =
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007978 args->single_newmvs[mv_idx][refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007979 }
7980
7981 if (this_mode == NEW_NEWMV) {
7982 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7983 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7984
7985 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7986 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
7987 single_newmv, rate_mv, 0);
7988 } else {
7989 *rate_mv = 0;
7990 for (i = 0; i < 2; ++i) {
7991#if CONFIG_REF_MV
7992 av1_set_mvcost(x, mbmi->ref_frame[i], i, mbmi->ref_mv_idx);
7993#endif // CONFIG_REF_MV
7994 *rate_mv += av1_mv_bit_cost(
7995 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7996 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7997 }
7998 }
7999 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
8000 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8001 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
8002 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
8003 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8004 } else {
8005 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8006 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
8007 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
8008 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8009 }
8010#else
8011 // Initialize mv using single prediction mode result.
8012 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8013 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8014
8015 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
8016 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, single_newmv,
8017 rate_mv, 0);
8018 } else {
8019 *rate_mv = 0;
8020 for (i = 0; i < 2; ++i) {
8021#if CONFIG_REF_MV
8022 av1_set_mvcost(x, mbmi->ref_frame[i], i, mbmi->ref_mv_idx);
8023#endif // CONFIG_REF_MV
8024 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
8025 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
8026 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8027 }
8028 }
8029#endif // CONFIG_EXT_INTER
8030 } else {
8031#if CONFIG_EXT_INTER
8032 if (is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008033 x->best_mv = args->single_newmvs[mv_idx][refs[0]];
8034 *rate_mv = args->single_newmvs_rate[mv_idx][refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08008035 } else {
8036 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx, rate_mv);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008037 args->single_newmvs[mv_idx][refs[0]] = x->best_mv;
8038 args->single_newmvs_rate[mv_idx][refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08008039 }
8040#else
8041 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
8042 single_newmv[refs[0]] = x->best_mv;
8043#endif // CONFIG_EXT_INTER
8044
8045 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
8046
8047 frame_mv[refs[0]] = x->best_mv;
8048 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
8049
8050 // Estimate the rate implications of a new mv but discount this
8051 // under certain circumstances where we want to help initiate a weak
8052 // motion field, where the distortion gain for a single block may not
8053 // be enough to overcome the cost of a new mv.
8054 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
8055 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
8056 }
8057 }
8058
8059 return 0;
8060}
8061
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008062int64_t interpolation_filter_search(
8063 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
8064 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
8065 BUFFER_SET *const orig_dst,
8066 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
8067 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
8068 int64_t *const skip_sse_sb) {
8069 const AV1_COMMON *cm = &cpi->common;
8070 MACROBLOCKD *const xd = &x->e_mbd;
8071 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8072 int i;
8073 int tmp_rate;
8074 int64_t tmp_dist;
8075
8076 (void)single_filter;
8077
8078 InterpFilter assign_filter = SWITCHABLE;
8079
8080 if (cm->interp_filter == SWITCHABLE) {
8081#if !CONFIG_DUAL_FILTER
8082 assign_filter =
8083 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
8084#endif // !CONFIG_DUAL_FILTER
8085 } else {
8086 assign_filter = cm->interp_filter;
8087 }
8088
8089#if CONFIG_DUAL_FILTER
8090 mbmi->interp_filter[0] =
8091 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8092 mbmi->interp_filter[1] =
8093 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8094 mbmi->interp_filter[2] =
8095 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8096 mbmi->interp_filter[3] =
8097 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8098#else
8099 mbmi->interp_filter =
8100 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8101#endif // CONFIG_DUAL_FILTER
8102 *switchable_rate = av1_get_switchable_rate(cpi, xd);
8103 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8104 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
8105 skip_txfm_sb, skip_sse_sb);
8106 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
8107
8108 if (assign_filter == SWITCHABLE) {
8109 // do interp_filter search
8110 if (av1_is_interp_needed(xd)) {
8111#if CONFIG_DUAL_FILTER
8112 const int filter_set_size = DUAL_FILTER_SET_SIZE;
8113#else
8114 const int filter_set_size = SWITCHABLE_FILTERS;
8115#endif // CONFIG_DUAL_FILTER
8116 int best_in_temp = 0;
8117#if CONFIG_DUAL_FILTER
8118 InterpFilter best_filter[4];
8119 av1_copy(best_filter, mbmi->interp_filter);
8120#else
8121 InterpFilter best_filter = mbmi->interp_filter;
8122#endif // CONFIG_DUAL_FILTER
8123 restore_dst_buf(xd, *tmp_dst);
8124 // EIGHTTAP_REGULAR mode is calculated beforehand
8125 for (i = 1; i < filter_set_size; ++i) {
8126 int tmp_skip_sb = 0;
8127 int64_t tmp_skip_sse = INT64_MAX;
8128 int tmp_rs;
8129 int64_t tmp_rd;
8130#if CONFIG_DUAL_FILTER
8131 mbmi->interp_filter[0] = filter_sets[i][0];
8132 mbmi->interp_filter[1] = filter_sets[i][1];
8133 mbmi->interp_filter[2] = filter_sets[i][0];
8134 mbmi->interp_filter[3] = filter_sets[i][1];
8135#else
8136 mbmi->interp_filter = (InterpFilter)i;
8137#endif // CONFIG_DUAL_FILTER
8138 tmp_rs = av1_get_switchable_rate(cpi, xd);
8139 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8140 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8141 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
8142 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
8143
8144 if (tmp_rd < *rd) {
8145 *rd = tmp_rd;
8146 *switchable_rate = av1_get_switchable_rate(cpi, xd);
8147#if CONFIG_DUAL_FILTER
8148 av1_copy(best_filter, mbmi->interp_filter);
8149#else
8150 best_filter = mbmi->interp_filter;
8151#endif // CONFIG_DUAL_FILTER
8152 *skip_txfm_sb = tmp_skip_sb;
8153 *skip_sse_sb = tmp_skip_sse;
8154 best_in_temp = !best_in_temp;
8155 if (best_in_temp) {
8156 restore_dst_buf(xd, *orig_dst);
8157 } else {
8158 restore_dst_buf(xd, *tmp_dst);
8159 }
8160 }
8161 }
8162 if (best_in_temp) {
8163 restore_dst_buf(xd, *tmp_dst);
8164 } else {
8165 restore_dst_buf(xd, *orig_dst);
8166 }
8167#if CONFIG_DUAL_FILTER
8168 av1_copy(mbmi->interp_filter, best_filter);
8169#else
8170 mbmi->interp_filter = best_filter;
8171#endif // CONFIG_DUAL_FILTER
8172 } else {
8173#if CONFIG_DUAL_FILTER
8174 for (i = 0; i < 4; ++i)
8175 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
8176#else
8177 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
8178#endif // CONFIG_DUAL_FILTER
8179 }
8180 }
8181
8182 return 0;
8183}
8184
Yaowu Xuc27fc142016-08-22 16:08:15 -07008185static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08008186 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
8187 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008188 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008189 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008190 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008191 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008192 MODE_INFO *mi = xd->mi[0];
8193 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008194 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8195 const int is_comp_pred = has_second_ref(mbmi);
8196 const int this_mode = mbmi->mode;
8197 int_mv *frame_mv = mode_mv[this_mode];
8198 int i;
8199 int refs[2] = { mbmi->ref_frame[0],
8200 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8201 int_mv cur_mv[2];
8202 int rate_mv = 0;
8203#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008204 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008205 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008206 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
8207 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
8208 const unsigned int *const interintra_mode_cost =
8209 cpi->interintra_mode_cost[size_group_lookup[bsize]];
8210 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
8211#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008212 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008213#endif // CONFIG_REF_MV
8214#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008215 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008216#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008217#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008218 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8219#else
8220 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008221#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008222 uint8_t *tmp_buf;
8223
Yue Chencb60b182016-10-13 15:18:22 -07008224#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07008225 MOTION_MODE motion_mode, last_motion_mode_allowed;
Angie Chiang76159122016-11-09 12:13:22 -08008226 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
8227 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008228#if CONFIG_VAR_TX
8229 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
8230#endif // CONFIG_VAR_TX
Angie Chiang75c22092016-10-25 12:19:16 -07008231 int64_t best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08008232 MB_MODE_INFO base_mbmi, best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008233#if CONFIG_EXT_INTER
8234 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008235 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008236#if CONFIG_MOTION_VAR
8237 int rate_mv_bmc;
8238#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008239#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008240#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yue Chen69f18e12016-09-08 14:48:15 -07008241#if CONFIG_WARPED_MOTION
Debargha Mukherjeee6eb3b52017-02-26 08:50:56 -08008242 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
Yue Chen69f18e12016-09-08 14:48:15 -07008243#endif // CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008244 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008245 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008246 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008247
8248 int skip_txfm_sb = 0;
8249 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008250 int16_t mode_ctx;
Angie Chiang76159122016-11-09 12:13:22 -08008251#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8252 av1_invalid_rd_stats(&best_rd_stats);
Fergus Simpson4063a682017-02-28 16:52:22 -08008253#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008254
8255#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008256 *args->compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008257 mbmi->use_wedge_interintra = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008258 *args->compmode_interinter_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008259 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008260
8261 // is_comp_interintra_pred implies !is_comp_pred
8262 assert(!is_comp_interintra_pred || (!is_comp_pred));
8263 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8264 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8265#endif // CONFIG_EXT_INTER
8266
8267#if CONFIG_REF_MV
8268#if CONFIG_EXT_INTER
8269 if (is_comp_pred)
8270 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8271 else
8272#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008273 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8274 mbmi->ref_frame, bsize, -1);
Yaowu Xub0d0d002016-11-22 09:26:43 -08008275#else // CONFIG_REF_MV
8276 mode_ctx = mbmi_ext->mode_context[refs[0]];
8277#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07008278
Yaowu Xuf883b422016-08-30 14:01:10 -07008279#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008280 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8281 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8282 else
Yaowu Xuf883b422016-08-30 14:01:10 -07008283#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008284 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008285 // Make sure that we didn't leave the plane destination buffers set
8286 // to tmp_buf at the end of the last iteration
8287 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008288
Yue Chen69f18e12016-09-08 14:48:15 -07008289#if CONFIG_WARPED_MOTION
8290 mbmi->num_proj_ref[0] = 0;
8291 mbmi->num_proj_ref[1] = 0;
8292#endif // CONFIG_WARPED_MOTION
8293
Yaowu Xuc27fc142016-08-22 16:08:15 -07008294 if (is_comp_pred) {
8295 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8296 frame_mv[refs[1]].as_int == INVALID_MV)
8297 return INT64_MAX;
8298 }
8299
Yue Chene9638cc2016-10-10 12:37:54 -07008300 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008301 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08008302 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008303 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008304 if (ret_val != 0)
8305 return ret_val;
8306 else
8307 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008308 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008309 for (i = 0; i < is_comp_pred + 1; ++i) {
8310 cur_mv[i] = frame_mv[refs[i]];
8311// Clip "next_nearest" so that it does not extend to far out of image
8312#if CONFIG_EXT_INTER
8313 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
8314#else
8315 if (this_mode != NEWMV)
8316#endif // CONFIG_EXT_INTER
8317 clamp_mv2(&cur_mv[i].as_mv, xd);
8318
8319 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8320 mbmi->mv[i].as_int = cur_mv[i].as_int;
8321 }
8322
8323#if CONFIG_REF_MV
8324#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008325 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008326#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008327 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008328#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008329 {
8330#if !CONFIG_EXT_INTER
8331 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008332#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008333 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8334 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8335 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8336
8337 for (i = 0; i < 2; ++i) {
8338 clamp_mv2(&cur_mv[i].as_mv, xd);
8339 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8340 mbmi->mv[i].as_int = cur_mv[i].as_int;
8341 }
8342 }
8343 }
8344
8345#if CONFIG_EXT_INTER
8346 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8347 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
8348 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8349
8350 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8351 clamp_mv2(&cur_mv[0].as_mv, xd);
8352 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8353 mbmi->mv[0].as_int = cur_mv[0].as_int;
8354 }
8355
8356 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
8357 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8358
8359 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8360 clamp_mv2(&cur_mv[1].as_mv, xd);
8361 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8362 mbmi->mv[1].as_int = cur_mv[1].as_int;
8363 }
8364 }
8365
8366 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8367 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
8368 this_mode == NEAR_NEARMV) {
8369 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
8370
8371 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8372 clamp_mv2(&cur_mv[0].as_mv, xd);
8373 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8374 mbmi->mv[0].as_int = cur_mv[0].as_int;
8375 }
8376
8377 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
8378 this_mode == NEAR_NEARMV) {
8379 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
8380
8381 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8382 clamp_mv2(&cur_mv[1].as_mv, xd);
8383 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8384 mbmi->mv[1].as_int = cur_mv[1].as_int;
8385 }
8386 }
8387#else
8388 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008389 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008390 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8391 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8392 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8393 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8394
8395 for (i = 0; i < 2; ++i) {
8396 clamp_mv2(&cur_mv[i].as_mv, xd);
8397 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8398 mbmi->mv[i].as_int = cur_mv[i].as_int;
8399 }
8400 }
8401 }
8402#endif // CONFIG_EXT_INTER
8403#endif // CONFIG_REF_MV
8404
8405 // do first prediction into the destination buffer. Do the next
8406 // prediction into a temporary buffer. Then keep track of which one
8407 // of these currently holds the best predictor, and use the other
8408 // one for future predictions. In the end, copy from tmp_buf to
8409 // dst if necessary.
8410 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008411 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8412 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008413 }
8414 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008415 orig_dst.plane[i] = xd->plane[i].dst.buf;
8416 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008417 }
8418
8419 // We don't include the cost of the second reference here, because there
8420 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8421 // words if you present them in that order, the second one is always known
8422 // if the first is known.
8423 //
8424 // Under some circumstances we discount the cost of new mv mode to encourage
8425 // initiation of a motion field.
8426 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8427 refs[0])) {
8428#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008429 rd_stats->rate +=
8430 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
8431 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008432#else
Angie Chiang76159122016-11-09 12:13:22 -08008433 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8434 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008435#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8436 } else {
8437#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008438 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008439#else
Angie Chiang76159122016-11-09 12:13:22 -08008440 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008441#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8442 }
8443
Angie Chiang76159122016-11-09 12:13:22 -08008444 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008445#if CONFIG_EXT_INTER
8446 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8447#else
8448 mbmi->mode != NEARESTMV
8449#endif // CONFIG_EXT_INTER
8450 )
8451 return INT64_MAX;
8452
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008453 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008454 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8455 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008456 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008457
Yaowu Xuc27fc142016-08-22 16:08:15 -07008458#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008459#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008460 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008461 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008462 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008463#if CONFIG_MOTION_VAR
8464 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008465#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008466#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467
Sarah Parker6fdc8532016-11-16 17:47:13 -08008468 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008469 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008470 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008471 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8472 INTERINTER_COMPOUND_DATA best_compound_data;
8473 int_mv best_mv[2];
8474 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008475 int tmp_skip_txfm_sb;
8476 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08008477 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008478 uint8_t pred0[2 * MAX_SB_SQUARE];
8479 uint8_t pred1[2 * MAX_SB_SQUARE];
8480 uint8_t *preds0[1] = { pred0 };
8481 uint8_t *preds1[1] = { pred1 };
8482 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008483 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008484 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008485 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008486
Sarah Parker6fdc8532016-11-16 17:47:13 -08008487 best_mv[0].as_int = cur_mv[0].as_int;
8488 best_mv[1].as_int = cur_mv[1].as_int;
8489 memset(&best_compound_data, 0, sizeof(INTERINTER_COMPOUND_DATA));
Sarah Parker6fddd182016-11-10 20:57:20 -08008490 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8491 av1_compound_type_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008492
Sarah Parker42d96102017-01-31 21:05:27 -08008493 if (masked_compound_used) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008494 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008495 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008496 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008497 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008498 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008499 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008500
Sarah Parker6fdc8532016-11-16 17:47:13 -08008501 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008502 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008503 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008504 best_rd_cur = INT64_MAX;
8505 mbmi->interinter_compound_data.type = cur_type;
8506 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
8507 bsize, mbmi->interinter_compound_data.type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008508 (masked_compound_used
8509 ? compound_type_cost[mbmi->interinter_compound_data.type]
8510 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008511
Sarah Parker6fdc8532016-11-16 17:47:13 -08008512 switch (cur_type) {
8513 case COMPOUND_AVERAGE:
David Barkerac37fa32016-12-02 12:30:21 +00008514 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008515 av1_subtract_plane(x, bsize, 0);
8516 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8517 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8518 INT64_MAX);
8519 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008520 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008521 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008522 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008523 break;
8524 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008525 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8526 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008527 best_rd_cur = build_and_cost_compound_wedge(
David Barkerac37fa32016-12-02 12:30:21 +00008528 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8529 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008530 }
8531 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008532#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008533 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008534 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8535 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker569edda2016-12-14 14:57:38 -08008536 best_rd_cur = build_and_cost_compound_seg(
8537 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8538 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008539 }
8540 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008541#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008542 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008543 }
Sarah Parker2e604882017-01-17 17:31:25 -08008544
8545 if (best_rd_cur < best_rd_compound) {
8546 best_rd_compound = best_rd_cur;
8547 memcpy(&best_compound_data, &mbmi->interinter_compound_data,
8548 sizeof(best_compound_data));
8549 if (have_newmv_in_inter_mode(this_mode)) {
8550 if (use_masked_motion_search(cur_type)) {
8551 best_tmp_rate_mv = tmp_rate_mv;
8552 best_mv[0].as_int = mbmi->mv[0].as_int;
8553 best_mv[1].as_int = mbmi->mv[1].as_int;
8554 } else {
8555 best_mv[0].as_int = cur_mv[0].as_int;
8556 best_mv[1].as_int = cur_mv[1].as_int;
8557 }
8558 }
8559 }
8560 // reset to original mvs for next iteration
8561 mbmi->mv[0].as_int = cur_mv[0].as_int;
8562 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008563 }
Sarah Parker6fdc8532016-11-16 17:47:13 -08008564 memcpy(&mbmi->interinter_compound_data, &best_compound_data,
8565 sizeof(INTERINTER_COMPOUND_DATA));
8566 if (have_newmv_in_inter_mode(this_mode)) {
8567 mbmi->mv[0].as_int = best_mv[0].as_int;
8568 mbmi->mv[1].as_int = best_mv[1].as_int;
8569 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8570 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2e604882017-01-17 17:31:25 -08008571 if (use_masked_motion_search(mbmi->interinter_compound_data.type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008572 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8573 rate_mv = best_tmp_rate_mv;
8574 }
8575 }
8576
8577 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008578 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008579 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008580 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008581
8582 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008583
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008584 *args->compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008585 compound_type_cost[mbmi->interinter_compound_data.type] +
8586 av1_cost_literal(get_interinter_compound_type_bits(
8587 bsize, mbmi->interinter_compound_data.type));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008588 }
8589
8590 if (is_comp_interintra_pred) {
8591 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8592 int64_t best_interintra_rd = INT64_MAX;
8593 int rmode, rate_sum;
8594 int64_t dist_sum;
8595 int j;
8596 int64_t best_interintra_rd_nowedge = INT64_MAX;
8597 int64_t best_interintra_rd_wedge = INT64_MAX;
8598 int rwedge;
8599 int_mv tmp_mv;
8600 int tmp_rate_mv = 0;
8601 int tmp_skip_txfm_sb;
8602 int64_t tmp_skip_sse_sb;
8603 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8604 uint8_t *intrapred;
8605
Yaowu Xuf883b422016-08-30 14:01:10 -07008606#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008607 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8608 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8609 else
Yaowu Xuf883b422016-08-30 14:01:10 -07008610#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008611 intrapred = intrapred_;
8612
Emil Keyder01770b32017-01-20 18:03:11 -05008613 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008614 for (j = 0; j < MAX_MB_PLANE; j++) {
8615 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8616 xd->plane[j].dst.stride = bw;
8617 }
David Barkerac37fa32016-12-02 12:30:21 +00008618 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
8619 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008620 mbmi->ref_frame[1] = INTRA_FRAME;
8621 mbmi->use_wedge_interintra = 0;
8622
8623 for (j = 0; j < INTERINTRA_MODES; ++j) {
8624 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8625 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008626 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8627 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008628 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008629 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8630 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8631 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
8632 if (rd < best_interintra_rd) {
8633 best_interintra_rd = rd;
8634 best_interintra_mode = mbmi->interintra_mode;
8635 }
8636 }
8637 mbmi->interintra_mode = best_interintra_mode;
8638 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008639 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8640 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008641 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8642 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008643 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8644 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8645 if (rd != INT64_MAX)
8646 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
8647 best_interintra_rd = rd;
8648
8649 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008650 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008651 return INT64_MAX;
8652 }
8653 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008654 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008655 if (rd != INT64_MAX)
8656 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
8657 dist_sum);
8658 best_interintra_rd_nowedge = rd;
8659
8660 // Disbale wedge search if source variance is small
8661 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8662 mbmi->use_wedge_interintra = 1;
8663
Yaowu Xuf883b422016-08-30 14:01:10 -07008664 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8665 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008666
8667 best_interintra_rd_wedge =
8668 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8669
8670 best_interintra_rd_wedge +=
8671 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
8672 // Refine motion vector.
8673 if (have_newmv_in_inter_mode(this_mode)) {
8674 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008675 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008676 mbmi->interintra_wedge_index, 1, bsize);
8677 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
8678 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
8679 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00008680 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008681 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8682 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8683 rd = RDCOST(x->rdmult, x->rddiv,
8684 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8685 if (rd < best_interintra_rd_wedge) {
8686 best_interintra_rd_wedge = rd;
8687 } else {
8688 tmp_mv.as_int = cur_mv[0].as_int;
8689 tmp_rate_mv = rate_mv;
8690 }
8691 } else {
8692 tmp_mv.as_int = cur_mv[0].as_int;
8693 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008694 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008695 }
8696 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008697 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008698 rd =
8699 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8700 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8701 if (rd != INT64_MAX)
8702 rd = RDCOST(x->rdmult, x->rddiv,
8703 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8704 best_interintra_rd_wedge = rd;
8705 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8706 mbmi->use_wedge_interintra = 1;
8707 best_interintra_rd = best_interintra_rd_wedge;
8708 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008709 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008710 rate_mv = tmp_rate_mv;
8711 } else {
8712 mbmi->use_wedge_interintra = 0;
8713 best_interintra_rd = best_interintra_rd_nowedge;
8714 mbmi->mv[0].as_int = cur_mv[0].as_int;
8715 }
8716 } else {
8717 mbmi->use_wedge_interintra = 0;
8718 best_interintra_rd = best_interintra_rd_nowedge;
8719 }
8720 }
8721
8722 pred_exists = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008723 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008724 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008725 *args->compmode_interintra_cost +=
Fergus Simpson073c6f32017-02-17 12:13:48 -08008726 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008727 if (is_interintra_wedge_used(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008728 *args->compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008729 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8730 if (mbmi->use_wedge_interintra) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008731 *args->compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008732 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008733 }
8734 }
8735 } else if (is_interintra_allowed(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008736 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008737 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008738 }
8739
Angie Chiang75c22092016-10-25 12:19:16 -07008740 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008741 int tmp_rate;
8742 int64_t tmp_dist;
David Barkerac37fa32016-12-02 12:30:21 +00008743 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008744 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8745 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8746 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
8747 }
Angie Chiang75c22092016-10-25 12:19:16 -07008748#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008749
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008750 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008751#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008752 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008753#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008754 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008755#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008756
8757#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008758 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759 if (is_comp_pred) {
8760 const int mode0 = compound_ref0_mode(this_mode);
8761 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008762 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8763 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008764 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008765 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008766 return INT64_MAX;
8767 }
8768 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008769 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008770 }
8771 }
8772#endif // CONFIG_EXT_INTER
8773
8774 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8775 // if current pred_error modeled rd is substantially more than the best
8776 // so far, do not bother doing full rd
8777 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008778 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008779 return INT64_MAX;
8780 }
8781 }
8782
Angie Chiang76159122016-11-09 12:13:22 -08008783 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008784#if CONFIG_WARPED_MOTION
8785 aom_clear_system_state();
8786 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
Debargha Mukherjee8b613212017-01-25 13:50:16 -08008787#if CONFIG_EXT_INTER
8788 best_bmc_mbmi.num_proj_ref[0] = mbmi->num_proj_ref[0];
8789#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008790#endif // CONFIG_WARPED_MOTION
8791#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08008792 rate2_nocoeff = rd_stats->rate;
Sarah Parker19234cc2017-03-10 16:43:25 -08008793 last_motion_mode_allowed = motion_mode_allowed(
8794#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8795 0, xd->global_motion,
8796#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8797 mi);
Yue Chend326f762016-11-29 12:11:32 -08008798 base_mbmi = *mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008799#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008800
Yue Chencb60b182016-10-13 15:18:22 -07008801#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008802 best_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08008803 for (motion_mode = SIMPLE_TRANSLATION;
Yue Chen69f18e12016-09-08 14:48:15 -07008804 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8805 int64_t tmp_rd = INT64_MAX;
Yue Chend326f762016-11-29 12:11:32 -08008806 int tmp_rate;
Yue Chen69f18e12016-09-08 14:48:15 -07008807 int64_t tmp_dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008808#if CONFIG_EXT_INTER
Yue Chend326f762016-11-29 12:11:32 -08008809 int tmp_rate2 =
8810 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008811#else
8812 int tmp_rate2 = rate2_nocoeff;
8813#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008814
Yue Chend326f762016-11-29 12:11:32 -08008815 *mbmi = base_mbmi;
8816 mbmi->motion_mode = motion_mode;
Yue Chencb60b182016-10-13 15:18:22 -07008817#if CONFIG_MOTION_VAR
Yue Chencb60b182016-10-13 15:18:22 -07008818 if (mbmi->motion_mode == OBMC_CAUSAL) {
Sarah Parker19234cc2017-03-10 16:43:25 -08008819 assert_motion_mode_valid(OBMC_CAUSAL,
8820#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8821 0, cm->global_motion,
8822#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8823 mi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824#if CONFIG_EXT_INTER
8825 *mbmi = best_bmc_mbmi;
Yue Chencb60b182016-10-13 15:18:22 -07008826 mbmi->motion_mode = OBMC_CAUSAL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008827#endif // CONFIG_EXT_INTER
8828 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008829 int tmp_rate_mv = 0;
8830
Yue Chene9638cc2016-10-10 12:37:54 -07008831 single_motion_search(cpi, x, bsize, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008832#if CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07008833 0, mv_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008834#endif // CONFIG_EXT_INTER
Yue Chene9638cc2016-10-10 12:37:54 -07008835 &tmp_rate_mv);
8836 mbmi->mv[0].as_int = x->best_mv.as_int;
8837 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8838 refs[0])) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008839 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840 }
8841#if CONFIG_EXT_INTER
8842 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8843#else
8844 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8845#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008846#if CONFIG_DUAL_FILTER
8847 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
Yue Chend326f762016-11-29 12:11:32 -08008848 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008849 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
Yue Chend326f762016-11-29 12:11:32 -08008850 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
Angie Chiang1733f6b2017-01-05 09:52:20 -08008851#endif // CONFIG_DUAL_FILTER
David Barkerac37fa32016-12-02 12:30:21 +00008852 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008853#if CONFIG_EXT_INTER
8854 } else {
David Barkerac37fa32016-12-02 12:30:21 +00008855 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008856#endif // CONFIG_EXT_INTER
8857 }
Fergus Simpson073c6f32017-02-17 12:13:48 -08008858 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008859 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
8860 args->left_pred_buf, args->left_pred_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008861 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8862 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8863 }
Yue Chencb60b182016-10-13 15:18:22 -07008864#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008865
8866#if CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07008867 if (mbmi->motion_mode == WARPED_CAUSAL) {
Sarah Parker19234cc2017-03-10 16:43:25 -08008868 assert_motion_mode_valid(WARPED_CAUSAL,
8869#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8870 0, xd->global_motion,
8871#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8872 mi);
Yue Chen69f18e12016-09-08 14:48:15 -07008873#if CONFIG_EXT_INTER
8874 *mbmi = best_bmc_mbmi;
8875 mbmi->motion_mode = WARPED_CAUSAL;
8876#endif // CONFIG_EXT_INTER
8877 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8878#if CONFIG_DUAL_FILTER
8879 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8880 ? EIGHTTAP_REGULAR
8881 : cm->interp_filter;
8882 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8883 ? EIGHTTAP_REGULAR
8884 : cm->interp_filter;
8885#else
8886 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8887 : cm->interp_filter;
8888#endif // CONFIG_DUAL_FILTER
8889
8890 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
Debargha Mukherjee246d2732017-02-27 14:09:18 -08008891 &mbmi->wm_params[0], mi_row, mi_col) == 0) {
Yue Chen69f18e12016-09-08 14:48:15 -07008892 int plane;
Yue Chen69f18e12016-09-08 14:48:15 -07008893 for (plane = 0; plane < 3; ++plane) {
8894 const struct macroblockd_plane *pd = &xd->plane[plane];
8895
8896 av1_warp_plane(&mbmi->wm_params[0],
8897#if CONFIG_AOM_HIGHBITDEPTH
8898 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
8899#endif // CONFIG_AOM_HIGHBITDEPTH
8900 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
8901 pd->pre[0].stride, pd->dst.buf,
8902 (mi_col * MI_SIZE) >> pd->subsampling_x,
8903 (mi_row * MI_SIZE) >> pd->subsampling_y,
Jingning Hanff6ee6a2016-12-07 09:55:21 -08008904 (xd->n8_w * MI_SIZE) >> pd->subsampling_x,
8905 (xd->n8_h * MI_SIZE) >> pd->subsampling_y,
8906 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
8907 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07008908 }
8909
8910 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8911 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8912 } else {
8913 continue;
8914 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008915 }
8916#endif // CONFIG_WARPED_MOTION
8917 x->skip = 0;
8918
Yue Chen8a78a2b2016-11-17 18:23:38 -08008919 rd_stats->dist = 0;
8920 rd_stats->sse = 0;
8921 rd_stats->skip = 1;
Angie Chiang76159122016-11-09 12:13:22 -08008922 rd_stats->rate = tmp_rate2;
Yue Chen69f18e12016-09-08 14:48:15 -07008923 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8924#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8925 if (last_motion_mode_allowed == WARPED_CAUSAL)
8926#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8927 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8928#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8929 else
8930 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8931#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8932 }
8933#if CONFIG_WARPED_MOTION
8934 if (mbmi->motion_mode == WARPED_CAUSAL) {
8935 rd_stats->rate -= rs;
8936 }
8937#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07008938#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008939 if (!skip_txfm_sb) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008940 int64_t rdcosty = INT64_MAX;
Angie Chiangb5dda482016-11-02 16:19:58 -07008941 int is_cost_valid_uv = 0;
Angie Chiang76159122016-11-09 12:13:22 -08008942
Yaowu Xu1e761992016-11-09 15:01:47 -08008943 // cost and distortion
Yaowu Xu1e761992016-11-09 15:01:47 -08008944 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008945#if CONFIG_VAR_TX
Yaowu Xu1e761992016-11-09 15:01:47 -08008946 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
Angie Chiang76159122016-11-09 12:13:22 -08008947 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008948 } else {
8949 int idx, idy;
Angie Chiang76159122016-11-09 12:13:22 -08008950 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008951 for (idy = 0; idy < xd->n8_h; ++idy)
8952 for (idx = 0; idx < xd->n8_w; ++idx)
8953 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang3aab6502016-11-10 17:48:16 -08008954 memset(x->blk_skip[0], rd_stats_y->skip,
Yaowu Xu1e761992016-11-09 15:01:47 -08008955 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8956 }
Angie Chiang0e9a2e92016-11-08 09:45:40 -08008957#else
Yaowu Xu1e761992016-11-09 15:01:47 -08008958 /* clang-format off */
Angie Chiang76159122016-11-09 12:13:22 -08008959 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
Yaowu Xu1e761992016-11-09 15:01:47 -08008960/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07008961#endif // CONFIG_VAR_TX
8962
Angie Chiang76159122016-11-09 12:13:22 -08008963 if (rd_stats_y->rate == INT_MAX) {
8964 av1_invalid_rd_stats(rd_stats);
Yue Chencb60b182016-10-13 15:18:22 -07008965#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8966 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008967 continue;
8968 } else {
Yue Chencb60b182016-10-13 15:18:22 -07008969#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +00008970 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008971 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07008972#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008973 }
Yue Chencb60b182016-10-13 15:18:22 -07008974#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008975 }
8976
Angie Chiang76159122016-11-09 12:13:22 -08008977 av1_merge_rd_stats(rd_stats, rd_stats_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008978
Angie Chiang76159122016-11-09 12:13:22 -08008979 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8980 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08008981/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07008982#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07008983 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08008984 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08008985#else
8986 is_cost_valid_uv =
Angie Chiang76159122016-11-09 12:13:22 -08008987 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
Angie Chiang284d7772016-11-08 11:06:45 -08008988#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07008989 if (!is_cost_valid_uv) {
Yue Chencb60b182016-10-13 15:18:22 -07008990#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008991 continue;
8992#else
David Barkerac37fa32016-12-02 12:30:21 +00008993 restore_dst_buf(xd, orig_dst);
Debargha Mukherjee0e119122016-11-04 12:10:23 -07008994 return INT64_MAX;
Yue Chencb60b182016-10-13 15:18:22 -07008995#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008996 }
Yaowu Xuc1c6f6a2016-11-08 11:24:01 -08008997 /* clang-format on */
Angie Chiang76159122016-11-09 12:13:22 -08008998 av1_merge_rd_stats(rd_stats, rd_stats_uv);
Angie Chiang3963d632016-11-10 18:41:40 -08008999#if CONFIG_RD_DEBUG
9000 // record transform block coefficient cost
Fergus Simpson45509632017-02-22 15:30:50 -08009001 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
Angie Chiang3963d632016-11-10 18:41:40 -08009002 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
9003 // here because we already collect the coefficient cost. Move this part to
9004 // other place when we need to compare non-coefficient cost.
9005 mbmi->rd_stats = *rd_stats;
Fergus Simpson4063a682017-02-28 16:52:22 -08009006#endif // CONFIG_RD_DEBUG
Yue Chencb60b182016-10-13 15:18:22 -07009007#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009008 if (rd_stats->skip) {
9009 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
9010 rd_stats_y->rate = 0;
9011 rd_stats_uv->rate = 0;
9012 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009013 mbmi->skip = 0;
9014 // here mbmi->skip temporarily plays a role as what this_skip2 does
9015 } else if (!xd->lossless[mbmi->segment_id] &&
9016 (RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009017 rd_stats_y->rate + rd_stats_uv->rate +
Yaowu Xuf883b422016-08-30 14:01:10 -07009018 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Angie Chiang76159122016-11-09 12:13:22 -08009019 rd_stats->dist) >=
Yaowu Xuc27fc142016-08-22 16:08:15 -07009020 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009021 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
9022 rd_stats->sse))) {
9023 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
9024 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9025 rd_stats->dist = rd_stats->sse;
9026 rd_stats_y->rate = 0;
9027 rd_stats_uv->rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009028 mbmi->skip = 1;
9029 } else {
Angie Chiang76159122016-11-09 12:13:22 -08009030 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009031 mbmi->skip = 0;
9032 }
9033 *disable_skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009034#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009035 } else {
9036 x->skip = 1;
9037 *disable_skip = 1;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07009038 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009039
9040// The cost of skip bit needs to be added.
Yue Chencb60b182016-10-13 15:18:22 -07009041#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009042 mbmi->skip = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009043#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009044 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009045
Angie Chiang76159122016-11-09 12:13:22 -08009046 rd_stats->dist = skip_sse_sb;
9047 rd_stats->sse = skip_sse_sb;
9048 rd_stats_y->rate = 0;
9049 rd_stats_uv->rate = 0;
9050 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009051 }
Yue Chen19e7aa82016-11-30 14:05:39 -08009052
Sarah Parkere5299862016-08-16 14:57:37 -07009053#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08009054 if (this_mode == ZEROMV
9055#if CONFIG_EXT_INTER
9056 || this_mode == ZERO_ZEROMV
9057#endif // CONFIG_EXT_INTER
9058 ) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08009059 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
Angie Chiang76159122016-11-09 12:13:22 -08009060 if (is_comp_pred)
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08009061 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
Yue Chen19e7aa82016-11-30 14:05:39 -08009062 if (is_nontrans_global_motion(xd)) {
9063 rd_stats->rate -= rs;
9064#if CONFIG_DUAL_FILTER
9065 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
9066 ? EIGHTTAP_REGULAR
9067 : cm->interp_filter;
9068 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
9069 ? EIGHTTAP_REGULAR
9070 : cm->interp_filter;
9071#else
9072 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
9073 ? EIGHTTAP_REGULAR
9074 : cm->interp_filter;
9075#endif // CONFIG_DUAL_FILTER
9076 }
Sarah Parkere5299862016-08-16 14:57:37 -07009077 }
9078#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009079
Yue Chencb60b182016-10-13 15:18:22 -07009080#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009081 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yue Chencb60b182016-10-13 15:18:22 -07009082 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009083 best_mbmi = *mbmi;
9084 best_rd = tmp_rd;
Angie Chiang76159122016-11-09 12:13:22 -08009085 best_rd_stats = *rd_stats;
9086 best_rd_stats_y = *rd_stats_y;
9087 best_rd_stats_uv = *rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009088#if CONFIG_VAR_TX
9089 for (i = 0; i < MAX_MB_PLANE; ++i)
9090 memcpy(best_blk_skip[i], x->blk_skip[i],
9091 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9092#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009093 best_xskip = x->skip;
9094 best_disable_skip = *disable_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009095 }
9096 }
9097
9098 if (best_rd == INT64_MAX) {
Angie Chiang76159122016-11-09 12:13:22 -08009099 av1_invalid_rd_stats(rd_stats);
David Barkerac37fa32016-12-02 12:30:21 +00009100 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009101 return INT64_MAX;
9102 }
9103 *mbmi = best_mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08009104 *rd_stats = best_rd_stats;
9105 *rd_stats_y = best_rd_stats_y;
9106 *rd_stats_uv = best_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009107#if CONFIG_VAR_TX
9108 for (i = 0; i < MAX_MB_PLANE; ++i)
9109 memcpy(x->blk_skip[i], best_blk_skip[i],
9110 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9111#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009112 x->skip = best_xskip;
9113 *disable_skip = best_disable_skip;
Yue Chencb60b182016-10-13 15:18:22 -07009114#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009115
David Barkerac37fa32016-12-02 12:30:21 +00009116 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009117 return 0; // The rate-distortion cost will be re-calculated by caller.
9118}
9119
Urvang Joshi52648442016-10-13 17:27:51 -07009120void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
9121 RD_COST *rd_cost, BLOCK_SIZE bsize,
9122 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9123 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009124 MACROBLOCKD *const xd = &x->e_mbd;
9125 struct macroblockd_plane *const pd = xd->plane;
9126 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9127 int y_skip = 0, uv_skip = 0;
9128 int64_t dist_y = 0, dist_uv = 0;
9129 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009130 const int unify_bsize = CONFIG_CB4X4;
9131
Yaowu Xuc27fc142016-08-22 16:08:15 -07009132 ctx->skip = 0;
9133 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009134 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009135
Jingning Han271bb2c2016-12-14 12:34:46 -08009136 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009137 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9138 &y_skip, bsize, best_rd) >= best_rd) {
9139 rd_cost->rate = INT_MAX;
9140 return;
9141 }
9142 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009143 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07009144 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009145 rd_cost->rate = INT_MAX;
9146 return;
9147 }
9148 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009149 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9150 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009151
9152#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009153#if !CONFIG_CHROMA_2X2
Jingning Han8efdbc82017-02-19 14:40:03 -08009154 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08009155#endif // !CONFIG_CHROMA_2X2
Jingning Han8efdbc82017-02-19 14:40:03 -08009156 if (!x->skip_chroma_rd)
9157 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9158 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009159#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009160 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009161 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009162#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009163
9164 if (y_skip && uv_skip) {
9165 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07009166 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009167 rd_cost->dist = dist_y + dist_uv;
9168 } else {
9169 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07009170 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009171 rd_cost->dist = dist_y + dist_uv;
9172 }
9173
9174 ctx->mic = *xd->mi[0];
9175 ctx->mbmi_ext = *x->mbmi_ext;
9176 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9177}
9178
Yaowu Xuc27fc142016-08-22 16:08:15 -07009179// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009180int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009181 return (cpi->oxcf.pass == 2) &&
9182 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9183 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9184}
9185
9186// Checks to see if a super block is on a horizontal image edge.
9187// In most cases this is the "real" edge unless there are formatting
9188// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009189int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009190 int top_edge = 0;
9191 int bottom_edge = cpi->common.mi_rows;
9192 int is_active_h_edge = 0;
9193
9194 // For two pass account for any formatting bars detected.
9195 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009196 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009197
9198 // The inactive region is specified in MBs not mi units.
9199 // The image edge is in the following MB row.
9200 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9201
9202 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009203 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009204 }
9205
9206 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9207 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9208 is_active_h_edge = 1;
9209 }
9210 return is_active_h_edge;
9211}
9212
9213// Checks to see if a super block is on a vertical image edge.
9214// In most cases this is the "real" edge unless there are formatting
9215// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009216int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009217 int left_edge = 0;
9218 int right_edge = cpi->common.mi_cols;
9219 int is_active_v_edge = 0;
9220
9221 // For two pass account for any formatting bars detected.
9222 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009223 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009224
9225 // The inactive region is specified in MBs not mi units.
9226 // The image edge is in the following MB row.
9227 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9228
9229 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009230 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009231 }
9232
9233 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9234 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9235 is_active_v_edge = 1;
9236 }
9237 return is_active_v_edge;
9238}
9239
9240// Checks to see if a super block is at the edge of the active image.
9241// In most cases this is the "real" edge unless there are formatting
9242// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009243int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009244 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9245 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009246}
9247
Urvang Joshib100db72016-10-12 16:28:56 -07009248#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009249static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009250 MACROBLOCKD *const xd = &x->e_mbd;
9251 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9252 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9253 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009254 int src_stride = x->plane[1].src.stride;
9255 const uint8_t *const src_u = x->plane[1].src.buf;
9256 const uint8_t *const src_v = x->plane[2].src.buf;
9257 float *const data = x->palette_buffer->kmeans_data_buf;
9258 float centroids[2 * PALETTE_MAX_SIZE];
9259 uint8_t *const color_map = xd->plane[1].color_index_map;
9260 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07009261#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009262 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9263 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07009264#endif // CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009265 int plane_block_width, plane_block_height, rows, cols;
9266 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9267 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009268 (void)cpi;
9269
9270 for (r = 0; r < rows; ++r) {
9271 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009272#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009273 if (cpi->common.use_highbitdepth) {
9274 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9275 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9276 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009277#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009278 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9279 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07009280#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009281 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009282#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009283 }
9284 }
9285
9286 for (r = 1; r < 3; ++r) {
9287 for (c = 0; c < pmi->palette_size[1]; ++c) {
9288 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9289 }
9290 }
9291
Yaowu Xuf883b422016-08-30 14:01:10 -07009292 av1_calc_indices(data, centroids, color_map, rows * cols,
9293 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009294 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9295 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009296}
Urvang Joshib100db72016-10-12 16:28:56 -07009297#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009298
hui su5db97432016-10-14 16:10:14 -07009299#if CONFIG_FILTER_INTRA
9300static void pick_filter_intra_interframe(
9301 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009302 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9303 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9304 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009305#if CONFIG_EXT_INTRA
9306 int8_t *uv_angle_delta,
9307#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009308#if CONFIG_PALETTE
9309 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9310#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009311 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9312 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9313 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9314#if CONFIG_SUPERTX
9315 int *returnrate_nocoef,
9316#endif // CONFIG_SUPERTX
9317 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009318 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009319 MACROBLOCKD *const xd = &x->e_mbd;
9320 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009321#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009322 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009323#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009324 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9325 int dc_mode_index;
9326 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009327 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9328 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009329 TX_SIZE uv_tx;
9330
9331 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009332 if (av1_mode_order[i].mode == DC_PRED &&
9333 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009334 break;
9335 dc_mode_index = i;
9336 assert(i < MAX_MODES);
9337
9338 // TODO(huisu): use skip_mask for further speedup.
9339 (void)skip_mask;
9340 mbmi->mode = DC_PRED;
9341 mbmi->uv_mode = DC_PRED;
9342 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009343 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009344 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9345 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009346 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009347 return;
hui su5db97432016-10-14 16:10:14 -07009348 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009349 if (rate_y == INT_MAX) return;
9350
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009351 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9352 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009353 if (rate_uv_intra[uv_tx] == INT_MAX) {
9354 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9355 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9356 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009357#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009358 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009359#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009360 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9361#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009362 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009363#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009364 }
9365
9366 rate_uv = rate_uv_tokenonly[uv_tx];
9367 distortion_uv = dist_uv[uv_tx];
9368 skippable = skippable && skip_uv[uv_tx];
9369 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009370#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009371 if (cm->allow_screen_content_tools) {
9372 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9373 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9374 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9375 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9376 }
Urvang Joshib100db72016-10-12 16:28:56 -07009377#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009378#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009379 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009380#endif // CONFIG_EXT_INTRA
9381 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9382 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9383 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9384 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9385 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009386 }
9387
9388 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9389 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009390#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009391 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009392 rate2 += av1_cost_bit(
9393 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009394#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009395
9396 if (!xd->lossless[mbmi->segment_id]) {
9397 // super_block_yrd above includes the cost of the tx_size in the
9398 // tokenonly rate, but for intra blocks, tx_size is always coded
9399 // (prediction granularity), so we account for it in the full rate,
9400 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009401 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009402 }
9403
hui su5db97432016-10-14 16:10:14 -07009404 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9405 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9406 rate2 += write_uniform_cost(
9407 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9408#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009409 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
9410 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
9411 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009412 }
hui su5db97432016-10-14 16:10:14 -07009413#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009415 rate2 +=
9416 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9417 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9418 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9419 rate2 +=
9420 write_uniform_cost(FILTER_INTRA_MODES,
9421 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009422 }
9423 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009424 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9425 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009426
9427 rate2 += ref_costs_single[INTRA_FRAME];
9428
9429 if (skippable) {
9430 rate2 -= (rate_y + rate_uv);
9431 rate_y = 0;
9432 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009433 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009434 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009435 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009436 }
9437 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009438
9439 if (this_rd < *best_intra_rd) {
9440 *best_intra_rd = this_rd;
9441 *best_intra_mode = mbmi->mode;
9442 }
9443 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009444 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009445
9446 if (this_rd < *best_rd) {
9447 *best_mode_index = dc_mode_index;
9448 mbmi->mv[0].as_int = 0;
9449 rd_cost->rate = rate2;
9450#if CONFIG_SUPERTX
9451 if (x->skip)
9452 *returnrate_nocoef = rate2;
9453 else
9454 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009455 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9456 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9457 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009458#endif // CONFIG_SUPERTX
9459 rd_cost->dist = distortion2;
9460 rd_cost->rdcost = this_rd;
9461 *best_rd = this_rd;
9462 *best_mbmode = *mbmi;
9463 *best_skip2 = 0;
9464 *best_mode_skippable = skippable;
9465 }
9466}
hui su5db97432016-10-14 16:10:14 -07009467#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009468
Yue Chencb60b182016-10-13 15:18:22 -07009469#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009470static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9471 const MACROBLOCKD *xd, int mi_row,
9472 int mi_col, const uint8_t *above,
9473 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009474 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009475#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009476
Urvang Joshi52648442016-10-13 17:27:51 -07009477void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009478 MACROBLOCK *x, int mi_row, int mi_col,
9479 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009480#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009481 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009482#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009483 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9484 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009485 const AV1_COMMON *const cm = &cpi->common;
9486 const RD_OPT *const rd_opt = &cpi->rd;
9487 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009488 MACROBLOCKD *const xd = &x->e_mbd;
9489 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009490#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009491 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009492#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009493 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9494 const struct segmentation *const seg = &cm->seg;
9495 PREDICTION_MODE this_mode;
9496 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9497 unsigned char segment_id = mbmi->segment_id;
9498 int comp_pred, i, k;
9499 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9500 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
9501#if CONFIG_EXT_INTER
9502 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
9503 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
9504 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9505#else
9506 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9507#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009508 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9509 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009510 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009511#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009512 AOM_LAST2_FLAG,
9513 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009514#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009515 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009516#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009517 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009518#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009519 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009520 };
9521 int64_t best_rd = best_rd_so_far;
9522 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9523 int64_t best_pred_diff[REFERENCE_MODES];
9524 int64_t best_pred_rd[REFERENCE_MODES];
9525 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009526#if CONFIG_REF_MV
9527 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9528 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Fergus Simpson4063a682017-02-28 16:52:22 -08009529#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009530 int best_mode_skippable = 0;
9531 int midx, best_mode_index = -1;
9532 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9533 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009534 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009535 int64_t best_intra_rd = INT64_MAX;
9536 unsigned int best_pred_sse = UINT_MAX;
9537 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009538 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9539 int64_t dist_uvs[TX_SIZES_ALL];
9540 int skip_uvs[TX_SIZES_ALL];
9541 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009542#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009543 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009544#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009545#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009546 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009547 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009548 uint8_t directional_mode_skip_mask[INTRA_MODES];
9549#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009550#if CONFIG_FILTER_INTRA
9551 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009552 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009553#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009554 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009555 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9556 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9557 int best_skip2 = 0;
9558 uint8_t ref_frame_skip_mask[2] = { 0 };
9559#if CONFIG_EXT_INTER
9560 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9561 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9562 int64_t best_single_inter_rd = INT64_MAX;
9563#else
9564 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9565#endif // CONFIG_EXT_INTER
9566 int mode_skip_start = sf->mode_skip_start + 1;
9567 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9568 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9569 int64_t mode_threshold[MAX_MODES];
9570 int *mode_map = tile_data->mode_map[bsize];
9571 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009572#if CONFIG_PVQ
9573 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009574#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009575
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009576 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009577#if CONFIG_MOTION_VAR
9578 { NULL },
9579 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9580 { NULL },
9581 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9582#endif // CONFIG_MOTION_VAR
9583#if CONFIG_EXT_INTER
9584 NULL,
9585 NULL,
9586 NULL,
9587 NULL,
9588 NULL,
9589#else // CONFIG_EXT_INTER
9590 NULL,
9591#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009592 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009593 };
9594
Urvang Joshib100db72016-10-12 16:28:56 -07009595#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009596 const int rows = block_size_high[bsize];
9597 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009598#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9599#if CONFIG_PALETTE
9600 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009601 const MODE_INFO *above_mi = xd->above_mi;
9602 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009603#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009604#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009605#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009606 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9607 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9608#else
9609 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9610 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07009611#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009612 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9613 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009614 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9615 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9616 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9617 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009618
Yaowu Xuf883b422016-08-30 14:01:10 -07009619#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009620 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9621 int len = sizeof(uint16_t);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009622 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9623 args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9624 args.above_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009625 CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009626 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9627 args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9628 args.left_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009629 CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009630 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009631#endif // CONFIG_AOM_HIGHBITDEPTH
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009632 args.above_pred_buf[0] = tmp_buf1;
9633 args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
9634 args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9635 args.left_pred_buf[0] = tmp_buf2;
9636 args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
9637 args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07009638#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009639 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009640#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009641#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009642
Yaowu Xuf883b422016-08-30 14:01:10 -07009643 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009644
Urvang Joshib100db72016-10-12 16:28:56 -07009645#if CONFIG_PALETTE
9646 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009647 if (cm->allow_screen_content_tools) {
9648 if (above_mi)
9649 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9650 if (left_mi)
9651 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9652 }
Urvang Joshib100db72016-10-12 16:28:56 -07009653#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009654
9655#if CONFIG_EXT_INTRA
9656 memset(directional_mode_skip_mask, 0,
9657 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
9658#endif // CONFIG_EXT_INTRA
9659
9660 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9661 &comp_mode_p);
9662
9663 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009664 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009665 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9666 for (i = 0; i < MB_MODE_COUNT; ++i) {
9667 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009668 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009669 }
9670 }
9671
9672 rd_cost->rate = INT_MAX;
9673#if CONFIG_SUPERTX
9674 *returnrate_nocoef = INT_MAX;
9675#endif // CONFIG_SUPERTX
9676
9677 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9678 x->pred_mv_sad[ref_frame] = INT_MAX;
9679 x->mbmi_ext->mode_context[ref_frame] = 0;
9680#if CONFIG_REF_MV && CONFIG_EXT_INTER
9681 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9682#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9683 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9684 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9685 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9686 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9687 }
9688 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009689#if CONFIG_GLOBAL_MOTION
9690 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009691 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009692 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9693 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009694 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009695#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009696 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009697#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009698#if CONFIG_EXT_INTER
9699 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9700 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009701#if CONFIG_GLOBAL_MOTION
9702 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009703 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009704 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9705 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009706 .as_int;
9707#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009708 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009709#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009710#endif // CONFIG_EXT_INTER
9711 }
9712
9713#if CONFIG_REF_MV
9714 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9715 MODE_INFO *const mi = xd->mi[0];
9716 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9717 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009718 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9719 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009720#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009721 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009722#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009723 candidates, mi_row, mi_col, NULL, NULL,
9724 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009725 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9726 MV_REFERENCE_FRAME rf[2];
9727 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009728 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9729 frame_mv[ZEROMV][rf[0]].as_int ||
9730 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9731 frame_mv[ZEROMV][rf[0]].as_int ||
9732 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9733 frame_mv[ZEROMV][rf[1]].as_int ||
9734 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009735 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9736 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009737 }
9738#endif // CONFIG_REF_MV
9739
Yue Chencb60b182016-10-13 15:18:22 -07009740#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009741 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
9742 if (check_num_overlappable_neighbors(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009743 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9744 args.above_pred_buf, dst_width1,
9745 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009746 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009747 args.left_pred_buf, dst_width2,
9748 dst_height2, args.left_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009749 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
9750 x->mask_buf = mask2d_buf;
9751 x->wsrc_buf = weighted_src_buf;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009752 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9753 args.above_pred_stride[0], args.left_pred_buf[0],
9754 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009755 }
Yue Chencb60b182016-10-13 15:18:22 -07009756#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009757
9758 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9759 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9760// Skip checking missing references in both single and compound reference
9761// modes. Note that a mode will be skipped iff both reference frames
9762// are masked out.
9763#if CONFIG_EXT_REFS
9764 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9765 ref_frame_skip_mask[0] |= (1 << ref_frame);
9766 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9767 } else {
9768#endif // CONFIG_EXT_REFS
9769 ref_frame_skip_mask[0] |= (1 << ref_frame);
9770 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9771#if CONFIG_EXT_REFS
9772 }
9773#endif // CONFIG_EXT_REFS
9774 } else {
9775 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9776 // Skip fixed mv modes for poor references
9777 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9778 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9779 break;
9780 }
9781 }
9782 }
9783 // If the segment reference frame feature is enabled....
9784 // then do nothing if the current ref frame is not allowed..
9785 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9786 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9787 ref_frame_skip_mask[0] |= (1 << ref_frame);
9788 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9789 }
9790 }
9791
9792 // Disable this drop out case if the ref frame
9793 // segment level feature is enabled for this segment. This is to
9794 // prevent the possibility that we end up unable to pick any mode.
9795 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9796 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9797 // unless ARNR filtering is enabled in which case we want
9798 // an unfiltered alternative. We allow near/nearest as well
9799 // because they may result in zero-zero MVs but be cheaper.
9800 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009801 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009802 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9803#if CONFIG_EXT_REFS
9804 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9805 (1 << BWDREF_FRAME) |
9806#endif // CONFIG_EXT_REFS
9807 (1 << GOLDEN_FRAME);
9808 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9809 // TODO(zoeliu): To further explore whether following needs to be done for
9810 // BWDREF_FRAME as well.
9811 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009812#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009813 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009814 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009815 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009816 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009817#else
9818 zeromv.as_int = 0;
9819#endif // CONFIG_GLOBAL_MOTION
9820 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009821 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009822 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009823 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9824#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009825 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009826 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009827 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009828 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009829 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009830 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009831 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009832 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9833#endif // CONFIG_EXT_INTER
9834 }
9835 }
9836
9837 if (cpi->rc.is_src_frame_alt_ref) {
9838 if (sf->alt_ref_search_fp) {
9839 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9840 mode_skip_mask[ALTREF_FRAME] = 0;
9841 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9842 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9843 }
9844 }
9845
9846 if (sf->alt_ref_search_fp)
9847 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9848 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9849 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9850
9851 if (sf->adaptive_mode_search) {
9852 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9853 cpi->rc.frames_since_golden >= 3)
9854 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
9855 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9856 }
9857
9858 if (bsize > sf->max_intra_bsize) {
9859 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9860 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9861 }
9862
9863 mode_skip_mask[INTRA_FRAME] |=
9864 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9865
9866 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9867 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9868 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9869
9870 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9871 while (midx > 4) {
9872 uint8_t end_pos = 0;
9873 for (i = 5; i < midx; ++i) {
9874 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9875 uint8_t tmp = mode_map[i];
9876 mode_map[i] = mode_map[i - 1];
9877 mode_map[i - 1] = tmp;
9878 end_pos = i;
9879 }
9880 }
9881 midx = end_pos;
9882 }
9883
9884 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9885 x->use_default_intra_tx_type = 1;
9886 else
9887 x->use_default_intra_tx_type = 0;
9888
9889 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9890 x->use_default_inter_tx_type = 1;
9891 else
9892 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009893#if CONFIG_PVQ
9894 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009895#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009896#if CONFIG_EXT_INTER
9897 for (i = 0; i < MB_MODE_COUNT; ++i)
9898 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9899 modelled_rd[i][ref_frame] = INT64_MAX;
9900#endif // CONFIG_EXT_INTER
9901
9902 for (midx = 0; midx < MAX_MODES; ++midx) {
9903 int mode_index;
9904 int mode_excluded = 0;
9905 int64_t this_rd = INT64_MAX;
9906 int disable_skip = 0;
9907 int compmode_cost = 0;
9908#if CONFIG_EXT_INTER
9909 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009910 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009911#endif // CONFIG_EXT_INTER
9912 int rate2 = 0, rate_y = 0, rate_uv = 0;
9913 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9914 int skippable = 0;
9915 int this_skip2 = 0;
9916 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009917#if CONFIG_REF_MV
9918 uint8_t ref_frame_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08009919#endif // CONFIG_REF_MV
Yushin Cho77bba8d2016-11-04 16:36:56 -07009920#if CONFIG_PVQ
9921 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009922#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009923 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009924 this_mode = av1_mode_order[mode_index].mode;
9925 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9926 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009927#if CONFIG_REF_MV
9928 mbmi->ref_mv_idx = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08009929#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009930
9931#if CONFIG_EXT_INTER
9932 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9933 // Mode must by compatible
9934 assert(is_interintra_allowed_mode(this_mode));
9935
David Barkerac37fa32016-12-02 12:30:21 +00009936#if !USE_RECT_INTERINTRA
David Barker561eb722017-01-19 11:19:24 +00009937 // Note: If the subsampling is unequal, any block size we pick will
9938 // result in either a rectangular luma block or a rectangular chroma
9939 // block. So in this case, we can't use any interintra modes.
David Barkerac37fa32016-12-02 12:30:21 +00009940 if (xd->plane[1].subsampling_x != xd->plane[1].subsampling_y ||
9941 xd->plane[2].subsampling_x != xd->plane[2].subsampling_y)
9942 continue;
Fergus Simpson4063a682017-02-28 16:52:22 -08009943#endif // !USE_RECT_INTERINTRA
David Barkerac37fa32016-12-02 12:30:21 +00009944
Yaowu Xuc27fc142016-08-22 16:08:15 -07009945 if (!is_interintra_allowed_bsize(bsize)) continue;
9946 }
9947
9948 if (is_inter_compound_mode(this_mode)) {
9949 frame_mv[this_mode][ref_frame].as_int =
9950 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9951 frame_mv[this_mode][second_ref_frame].as_int =
9952 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
9953 }
9954#endif // CONFIG_EXT_INTER
9955
9956 // Look at the reference frame of the best mode so far and set the
9957 // skip mask to look at a subset of the remaining modes.
9958 if (midx == mode_skip_start && best_mode_index >= 0) {
9959 switch (best_mbmode.ref_frame[0]) {
9960 case INTRA_FRAME: break;
9961 case LAST_FRAME:
9962 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9963 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9964 break;
9965#if CONFIG_EXT_REFS
9966 case LAST2_FRAME:
9967 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9968 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9969 break;
9970 case LAST3_FRAME:
9971 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9972 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9973 break;
9974#endif // CONFIG_EXT_REFS
9975 case GOLDEN_FRAME:
9976 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9977 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9978 break;
9979#if CONFIG_EXT_REFS
9980 case BWDREF_FRAME:
9981 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9982 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9983 break;
9984#endif // CONFIG_EXT_REFS
9985 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9986#if CONFIG_EXT_REFS
9987 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9988#endif // CONFIG_EXT_REFS
9989 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009990 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009991 case TOTAL_REFS_PER_FRAME:
9992 assert(0 && "Invalid Reference frame");
9993 break;
9994 }
9995 }
9996
9997 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009998 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009999 continue;
10000
10001 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
10002
10003 // Test best rd so far against threshold for trying this mode.
10004 if (best_mode_skippable && sf->schedule_mode_search)
10005 mode_threshold[mode_index] <<= 1;
10006
10007 if (best_rd < mode_threshold[mode_index]) continue;
10008
10009 comp_pred = second_ref_frame > INTRA_FRAME;
10010 if (comp_pred) {
10011 if (!cpi->allow_comp_inter_inter) continue;
10012
10013 // Skip compound inter modes if ARF is not available.
10014 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10015
10016 // Do not allow compound prediction if the segment level reference frame
10017 // feature is in use as in this case there can only be one reference.
10018 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10019
10020 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10021 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10022 continue;
10023
10024 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10025 } else {
10026 if (ref_frame != INTRA_FRAME)
10027 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10028 }
10029
10030 if (ref_frame == INTRA_FRAME) {
10031 if (sf->adaptive_mode_search)
10032 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10033 continue;
10034
10035 if (this_mode != DC_PRED) {
10036 // Disable intra modes other than DC_PRED for blocks with low variance
10037 // Threshold for intra skipping based on source variance
10038 // TODO(debargha): Specialize the threshold for super block sizes
10039 const unsigned int skip_intra_var_thresh = 64;
10040 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10041 x->source_variance < skip_intra_var_thresh)
10042 continue;
10043 // Only search the oblique modes if the best so far is
10044 // one of the neighboring directional modes
10045 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10046 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10047 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10048 continue;
10049 }
10050 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10051 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10052 }
10053 }
Sarah Parkere5299862016-08-16 14:57:37 -070010054#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010055 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010056 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010057 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010058#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010059 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010060#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010061 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10062 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
10063#if CONFIG_REF_MV && CONFIG_EXT_INTER
10064 mbmi_ext->compound_mode_context,
10065#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010066 frame_mv, this_mode, ref_frames, bsize, -1,
10067 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010068 continue;
10069 }
10070
10071 mbmi->mode = this_mode;
10072 mbmi->uv_mode = DC_PRED;
10073 mbmi->ref_frame[0] = ref_frame;
10074 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010075#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010076 pmi->palette_size[0] = 0;
10077 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010078#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010079#if CONFIG_FILTER_INTRA
10080 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10081 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10082#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010083 // Evaluate all sub-pel filters irrespective of whether we can use
10084 // them for this frame.
10085#if CONFIG_DUAL_FILTER
10086 for (i = 0; i < 4; ++i) {
10087 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10088 ? EIGHTTAP_REGULAR
10089 : cm->interp_filter;
10090 }
10091#else
10092 mbmi->interp_filter =
10093 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080010094#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010095 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010096 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010097
10098 x->skip = 0;
10099 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10100
10101 // Select prediction reference frames.
10102 for (i = 0; i < MAX_MB_PLANE; i++) {
10103 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10104 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10105 }
10106
10107#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010108 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010109#endif // CONFIG_EXT_INTER
10110
10111 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010112 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010113 TX_SIZE uv_tx;
10114 struct macroblockd_plane *const pd = &xd->plane[1];
10115#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010116 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010117 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010118 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010119 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010120 if (!angle_stats_ready) {
10121 const int src_stride = x->plane[0].src.stride;
10122 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -070010123#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010124 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
10125 highbd_angle_estimation(src, src_stride, rows, cols,
10126 directional_mode_skip_mask);
10127 else
Fergus Simpson4063a682017-02-28 16:52:22 -080010128#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010129 angle_estimation(src, src_stride, rows, cols,
10130 directional_mode_skip_mask);
10131 angle_stats_ready = 1;
10132 }
10133 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010134 rd_stats_y.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -080010135 this_rd = rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y,
10136 bsize, intra_mode_cost[mbmi->mode],
10137 best_rd, &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010138 } else {
10139 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010140 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010141 }
10142#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010143 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010144#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010145 rate_y = rd_stats_y.rate;
10146 distortion_y = rd_stats_y.dist;
10147 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010148
10149 if (rate_y == INT_MAX) continue;
10150
hui su5db97432016-10-14 16:10:14 -070010151#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010152 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010153#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010154
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010155 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10156 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010157 if (rate_uv_intra[uv_tx] == INT_MAX) {
10158 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010159 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10160 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010161#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010162 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010163#endif // CONFIG_PALETTE
10164
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010166 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10167#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010168#if CONFIG_FILTER_INTRA
10169 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10170#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010171 }
10172
10173 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010174 distortion_uv = dist_uvs[uv_tx];
10175 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010176 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010177#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010178 if (cm->allow_screen_content_tools) {
10179 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10180 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10181 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10182 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10183 }
Urvang Joshib100db72016-10-12 16:28:56 -070010184#endif // CONFIG_PALETTE
10185
Yaowu Xuc27fc142016-08-22 16:08:15 -070010186#if CONFIG_EXT_INTRA
10187 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010188#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010189#if CONFIG_FILTER_INTRA
10190 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10191 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10192 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10193 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10194 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10195 }
10196#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010197
Jingning Han36fe3202017-02-20 22:31:49 -080010198#if CONFIG_CB4X4
10199 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10200 if (!x->skip_chroma_rd)
10201 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10202#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010203 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10204 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010205#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010206
Urvang Joshib100db72016-10-12 16:28:56 -070010207#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010208 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -070010209 rate2 += av1_cost_bit(
10210 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -070010211#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010212
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010213 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010214 // super_block_yrd above includes the cost of the tx_size in the
10215 // tokenonly rate, but for intra blocks, tx_size is always coded
10216 // (prediction granularity), so we account for it in the full rate,
10217 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010218 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010219 }
10220#if CONFIG_EXT_INTRA
10221 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010222 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -080010223#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010224 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -070010225 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -080010226 p_angle = mode_to_angle_map[mbmi->mode] +
10227 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -070010228 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010229 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010230#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -080010231 rate2 += write_uniform_cost(2 * max_angle_delta + 1,
10232 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010233 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010234 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su45dc5972016-12-08 17:42:50 -080010235 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
10236 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010237 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010238#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010239#if CONFIG_FILTER_INTRA
10240 if (mbmi->mode == DC_PRED) {
10241 rate2 +=
10242 av1_cost_bit(cm->fc->filter_intra_probs[0],
10243 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10244 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10245 rate2 += write_uniform_cost(
10246 FILTER_INTRA_MODES,
10247 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10248 }
10249 }
10250 if (mbmi->uv_mode == DC_PRED) {
10251 rate2 +=
10252 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10253 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10254 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10255 rate2 += write_uniform_cost(
10256 FILTER_INTRA_MODES,
10257 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10258 }
10259#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010260 if (this_mode != DC_PRED && this_mode != TM_PRED)
10261 rate2 += intra_cost_penalty;
10262 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010263 } else {
10264#if CONFIG_REF_MV
10265 int_mv backup_ref_mv[2];
10266
Jingning Hanc41a5492017-02-24 11:18:52 -080010267#if !SUB8X8_COMP_REF
10268 if (bsize < BLOCK_8X8 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010269#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010270
Yaowu Xuc27fc142016-08-22 16:08:15 -070010271 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10272 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Fergus Simpson4063a682017-02-28 16:52:22 -080010273#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010274#if CONFIG_EXT_INTER
10275 if (second_ref_frame == INTRA_FRAME) {
10276 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010277 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010278// TODO(debargha|geza.lore):
10279// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010280#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010281 mbmi->angle_delta[0] = 0;
10282 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010283#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010284 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010285#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010286#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010287#if CONFIG_FILTER_INTRA
10288 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10289 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10290#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010291 }
10292#endif // CONFIG_EXT_INTER
10293#if CONFIG_REF_MV
10294 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010295 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010296
10297 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
10298 int ref;
10299 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10300 int_mv this_mv =
10301 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10302 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010303 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10304 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010305 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10306 }
10307 }
Fergus Simpson4063a682017-02-28 16:52:22 -080010308#endif // CONFIG_REF_MV
Angie Chiang76159122016-11-09 12:13:22 -080010309 {
10310 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10311 av1_init_rd_stats(&rd_stats);
10312 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010313
10314// Point to variables that are maintained between loop iterations
10315#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010316 args.single_newmvs = single_newmvs;
10317 args.single_newmvs_rate = single_newmvs_rate;
10318 args.compmode_interintra_cost = &compmode_interintra_cost;
10319 args.compmode_interinter_cost = &compmode_interinter_cost;
10320 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010321#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010322 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010323#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010324 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10325 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010326 mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010327// Prevent pointers from escaping local scope
Yaowu Xuc27fc142016-08-22 16:08:15 -070010328#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010329 args.compmode_interintra_cost = NULL;
10330 args.compmode_interinter_cost = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010331#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010332
10333 rate2 = rd_stats.rate;
10334 skippable = rd_stats.skip;
10335 distortion2 = rd_stats.dist;
10336 total_sse = rd_stats.sse;
10337 rate_y = rd_stats_y.rate;
10338 rate_uv = rd_stats_uv.rate;
10339 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010340
10341#if CONFIG_REF_MV
Yue Chen6e601e92016-12-05 18:19:00 -080010342// TODO(jingning): This needs some refactoring to improve code quality
10343// and reduce redundant steps.
10344#if CONFIG_EXT_INTER
10345 if (((mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) &&
10346 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10347 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10348 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10349#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010350 if ((mbmi->mode == NEARMV &&
10351 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10352 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Yue Chen6e601e92016-12-05 18:19:00 -080010353#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010354 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10355 MB_MODE_INFO backup_mbmi = *mbmi;
10356 int backup_skip = x->skip;
10357 int64_t tmp_ref_rd = this_rd;
10358 int ref_idx;
10359
Yue Chen6e601e92016-12-05 18:19:00 -080010360// TODO(jingning): This should be deprecated shortly.
10361#if CONFIG_EXT_INTER
10362 int idx_offset =
10363 (mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) ? 1 : 0;
10364#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010365 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010366#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010367 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010368 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010369
10370 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010371 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010372 // Dummy
10373 int_mv backup_fmv[2];
10374 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10375 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10376
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010377 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010378
10379 if (this_rd < INT64_MAX) {
10380 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10381 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10382 tmp_ref_rd =
10383 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010384 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010385 distortion2);
10386 else
10387 tmp_ref_rd =
10388 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010389 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010390 rate_y - rate_uv,
10391 total_sse);
10392 }
10393#if CONFIG_VAR_TX
10394 for (i = 0; i < MAX_MB_PLANE; ++i)
10395 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10396 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010397#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010398
10399 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10400 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010401 int dummy_disable_skip = 0;
10402 int ref;
10403 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010404 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010405#if CONFIG_EXT_INTER
10406 int tmp_compmode_interintra_cost = 0;
10407 int tmp_compmode_interinter_cost = 0;
10408#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010409
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010410 av1_invalid_rd_stats(&tmp_rd_stats);
10411
Yaowu Xuc27fc142016-08-22 16:08:15 -070010412 mbmi->ref_mv_idx = 1 + ref_idx;
10413
10414 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10415 int_mv this_mv =
10416 (ref == 0)
10417 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10418 .this_mv
10419 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10420 .comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010421 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10422 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010423 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10424 }
10425
10426 cur_mv =
10427 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10428 .this_mv;
10429 clamp_mv2(&cur_mv.as_mv, xd);
10430
10431 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010432#if CONFIG_EXT_INTER
10433 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
10434 { { 0 } } };
10435 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
10436 { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010437#else
10438 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Fergus Simpson4063a682017-02-28 16:52:22 -080010439#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010440
10441 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010442 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010443
10444// Point to variables that are not maintained between iterations
10445#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010446 args.single_newmvs = dummy_single_newmvs;
10447 args.single_newmvs_rate = dummy_single_newmvs_rate;
10448 args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
10449 args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
10450 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010451#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010452 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010453#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010454 tmp_alt_rd = handle_inter_mode(
10455 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10456 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010457// Prevent pointers from escaping local scope
10458#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010459 args.single_newmvs = NULL;
10460 args.single_newmvs_rate = NULL;
10461 args.compmode_interintra_cost = NULL;
10462 args.compmode_interinter_cost = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010463#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010464 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010465#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010466 }
10467
10468 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10469 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010470 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10471 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010472 tmp_rd_stats.rate +=
10473 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10474 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010475 }
10476
10477 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10478 mbmi->ref_mv_idx + idx_offset + 1 &&
10479 ref_idx < ref_set - 1) {
10480 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010481 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10482 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010483 tmp_rd_stats.rate +=
10484 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10485 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010486 }
10487
10488 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010489#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010490 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10491 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010492#else
Angie Chiang76159122016-11-09 12:13:22 -080010493 if (RDCOST(x->rdmult, x->rddiv,
10494 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10495 tmp_rd_stats.dist) <
10496 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010497 tmp_alt_rd =
10498 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010499 tmp_rd_stats.rate +
10500 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10501 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010502 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010503 tmp_alt_rd =
10504 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010505 tmp_rd_stats.rate +
10506 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10507 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10508 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010509#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010510 }
10511
10512 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010513 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010514 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010515 distortion2 = tmp_rd_stats.dist;
10516 skippable = tmp_rd_stats.skip;
10517 rate_y = tmp_rd_stats_y.rate;
10518 rate_uv = tmp_rd_stats_uv.rate;
10519 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010520 this_rd = tmp_alt_rd;
10521 tmp_ref_rd = tmp_alt_rd;
10522 backup_mbmi = *mbmi;
10523 backup_skip = x->skip;
10524#if CONFIG_VAR_TX
10525 for (i = 0; i < MAX_MB_PLANE; ++i)
10526 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10527 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010528#endif // CONFIG_VAR_TX
Yue Chen6e601e92016-12-05 18:19:00 -080010529#if CONFIG_EXT_INTER
10530 compmode_interintra_cost = tmp_compmode_interintra_cost;
10531 compmode_interinter_cost = tmp_compmode_interinter_cost;
Fergus Simpson4063a682017-02-28 16:52:22 -080010532#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010533 } else {
10534 *mbmi = backup_mbmi;
10535 x->skip = backup_skip;
10536 }
10537 }
10538
10539 frame_mv[NEARMV][ref_frame] = backup_mv;
10540 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10541 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10542#if CONFIG_VAR_TX
10543 for (i = 0; i < MAX_MB_PLANE; ++i)
10544 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10545 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010546#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010547 }
10548 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10549 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
10550#endif // CONFIG_REF_MV
10551
10552 if (this_rd == INT64_MAX) continue;
10553
Jingning Hanc41a5492017-02-24 11:18:52 -080010554#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010555 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010556#else
10557 if (mbmi->sb_type >= BLOCK_8X8)
10558 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010559#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010560
10561 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10562 }
10563
10564#if CONFIG_EXT_INTER
10565 rate2 += compmode_interintra_cost;
10566 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010567#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10568 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10569#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010570 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010571#endif // CONFIG_EXT_INTER
10572
10573 // Estimate the reference frame signaling cost and add it
10574 // to the rolling cost variable.
10575 if (comp_pred) {
10576 rate2 += ref_costs_comp[ref_frame];
10577#if CONFIG_EXT_REFS
10578 rate2 += ref_costs_comp[second_ref_frame];
10579#endif // CONFIG_EXT_REFS
10580 } else {
10581 rate2 += ref_costs_single[ref_frame];
10582 }
10583
Yue Chen69f18e12016-09-08 14:48:15 -070010584#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010585 if (ref_frame == INTRA_FRAME) {
10586#else
10587 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010588#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010589 if (skippable) {
10590 // Back out the coefficient coding costs
10591 rate2 -= (rate_y + rate_uv);
10592 rate_y = 0;
10593 rate_uv = 0;
10594 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010595 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010596 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010597#if CONFIG_REF_MV
10598 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10599 distortion2) <
10600 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
10601#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010602 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10603 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Fergus Simpson4063a682017-02-28 16:52:22 -080010604#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010605 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010606 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010607 } else {
10608 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010609 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010610 distortion2 = total_sse;
10611 assert(total_sse >= 0);
10612 rate2 -= (rate_y + rate_uv);
10613 this_skip2 = 1;
10614 rate_y = 0;
10615 rate_uv = 0;
10616 }
10617 } else {
10618 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010619 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010620 }
10621
10622 // Calculate the final RD estimate for this mode.
10623 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010624#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010625 } else {
10626 this_skip2 = mbmi->skip;
10627 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10628 if (this_skip2) {
10629 rate_y = 0;
10630 rate_uv = 0;
10631 }
Yue Chen69f18e12016-09-08 14:48:15 -070010632#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010633 }
10634
Yaowu Xuc27fc142016-08-22 16:08:15 -070010635 if (ref_frame == INTRA_FRAME) {
10636 // Keep record of best intra rd
10637 if (this_rd < best_intra_rd) {
10638 best_intra_rd = this_rd;
10639 best_intra_mode = mbmi->mode;
10640 }
10641#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -050010642 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010643 if (this_rd < best_single_inter_rd) {
10644 best_single_inter_rd = this_rd;
10645 best_single_inter_ref = mbmi->ref_frame[0];
10646 }
10647#endif // CONFIG_EXT_INTER
10648 }
10649
10650 if (!disable_skip && ref_frame == INTRA_FRAME) {
10651 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010652 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010653 }
10654
10655 // Did this mode help.. i.e. is it the new best mode
10656 if (this_rd < best_rd || x->skip) {
10657 if (!mode_excluded) {
10658 // Note index of best mode so far
10659 best_mode_index = mode_index;
10660
10661 if (ref_frame == INTRA_FRAME) {
10662 /* required for left and above block mv */
10663 mbmi->mv[0].as_int = 0;
10664 } else {
10665 best_pred_sse = x->pred_sse[ref_frame];
10666 }
10667
10668 rd_cost->rate = rate2;
10669#if CONFIG_SUPERTX
10670 if (x->skip)
10671 *returnrate_nocoef = rate2;
10672 else
10673 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010674 *returnrate_nocoef -= av1_cost_bit(
10675 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10676 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10677 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010678#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010679 const MOTION_MODE motion_allowed = motion_mode_allowed(
10680#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10681 0, xd->global_motion,
10682#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10683 mi);
Yue Chen69f18e12016-09-08 14:48:15 -070010684#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010685 if (motion_allowed == WARPED_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010686#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010687 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010688#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010689 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010690 *returnrate_nocoef -=
10691 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
10692#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010693#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010694#endif // CONFIG_SUPERTX
10695 rd_cost->dist = distortion2;
10696 rd_cost->rdcost = this_rd;
10697 best_rd = this_rd;
10698 best_mbmode = *mbmi;
10699 best_skip2 = this_skip2;
10700 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010701 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10702 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010703 best_rate_uv = rate_uv;
10704
10705#if CONFIG_VAR_TX
10706 for (i = 0; i < MAX_MB_PLANE; ++i)
10707 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10708 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010709#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010710 }
10711 }
10712
10713 /* keep record of best compound/single-only prediction */
10714 if (!disable_skip && ref_frame != INTRA_FRAME) {
10715 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10716
10717 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10718 single_rate = rate2 - compmode_cost;
10719 hybrid_rate = rate2;
10720 } else {
10721 single_rate = rate2;
10722 hybrid_rate = rate2 + compmode_cost;
10723 }
10724
10725 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10726 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10727
10728 if (!comp_pred) {
10729 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10730 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10731 } else {
10732 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10733 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10734 }
10735 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10736 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10737 }
10738
Yaowu Xuc27fc142016-08-22 16:08:15 -070010739 if (x->skip && !comp_pred) break;
10740 }
10741
10742 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10743 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10744 is_inter_mode(best_mbmode.mode)) ||
10745 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10746 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010747 int skip_blk = 0;
10748 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010749
10750 x->use_default_inter_tx_type = 0;
10751 x->use_default_intra_tx_type = 0;
10752
10753 *mbmi = best_mbmode;
10754
10755 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10756
10757 // Select prediction reference frames.
10758 for (i = 0; i < MAX_MB_PLANE; i++) {
10759 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10760 if (has_second_ref(mbmi))
10761 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10762 }
10763
10764 if (is_inter_mode(mbmi->mode)) {
Yue Chen69f18e12016-09-08 14:48:15 -070010765#if CONFIG_WARPED_MOTION
10766 if (mbmi->motion_mode == WARPED_CAUSAL) {
Sarah Parker19234cc2017-03-10 16:43:25 -080010767 assert_motion_mode_valid(WARPED_CAUSAL,
10768#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10769 0, xd->global_motion,
10770#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10771 xd->mi[0]);
Yue Chen69f18e12016-09-08 14:48:15 -070010772 assert(!has_second_ref(mbmi));
10773
Fergus Simpsonf80a0582017-03-08 10:09:50 -080010774 int plane;
Yue Chen69f18e12016-09-08 14:48:15 -070010775 for (plane = 0; plane < 3; ++plane) {
10776 const struct macroblockd_plane *pd = &xd->plane[plane];
10777
10778 av1_warp_plane(&mbmi->wm_params[0],
10779#if CONFIG_AOM_HIGHBITDEPTH
10780 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
10781#endif // CONFIG_AOM_HIGHBITDEPTH
10782 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
10783 pd->pre[0].stride, pd->dst.buf,
10784 ((mi_col * MI_SIZE) >> pd->subsampling_x),
10785 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010786 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
10787 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
10788 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
10789 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -070010790 }
10791 } else {
10792#endif // CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +000010793 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Yue Chen69f18e12016-09-08 14:48:15 -070010794#if CONFIG_WARPED_MOTION
10795 }
10796#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010797#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010798 if (mbmi->motion_mode == OBMC_CAUSAL) {
10799 assert_motion_mode_valid(OBMC_CAUSAL,
10800#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10801 0, cm->global_motion,
10802#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10803 xd->mi[0]);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010804 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010805 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10806 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010807 }
Yue Chencb60b182016-10-13 15:18:22 -070010808#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010809 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010810#if CONFIG_VAR_TX
10811 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010812 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010813 } else {
10814 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010815 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010816 for (idy = 0; idy < xd->n8_h; ++idy)
10817 for (idx = 0; idx < xd->n8_w; ++idx)
10818 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010819 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010820 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10821 }
10822
Angie Chiangb5dda482016-11-02 16:19:58 -070010823 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010824#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010825 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010826 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010827#endif // CONFIG_VAR_TX
10828 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010829 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010830 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010831 }
10832
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010833 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10834 (rd_stats_y.dist + rd_stats_uv.dist)) >
10835 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010836 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010837 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10838 rd_stats_uv.rate = 0;
10839 rd_stats_y.dist = rd_stats_y.sse;
10840 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010841 } else {
10842 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010843 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010844 }
10845
10846 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010847 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10848 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010849#if CONFIG_VAR_TX
10850 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080010851#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010852 best_mbmode.tx_type = mbmi->tx_type;
10853 best_mbmode.tx_size = mbmi->tx_size;
10854#if CONFIG_VAR_TX
10855 for (idy = 0; idy < xd->n8_h; ++idy)
10856 for (idx = 0; idx < xd->n8_w; ++idx)
10857 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
10858
10859 for (i = 0; i < MAX_MB_PLANE; ++i)
10860 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10861 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070010862
10863 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080010864#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010865 rd_cost->rate +=
10866 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
10867 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010868 rd_cost->rdcost =
10869 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
10870 best_skip2 = skip_blk;
10871 }
10872 }
10873
Urvang Joshib100db72016-10-12 16:28:56 -070010874#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010875 // Only try palette mode when the best mode so far is an intra mode.
10876 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010877 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010878#if CONFIG_SUPERTX
10879 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010880#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080010881 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10882 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010883 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010884 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010885 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010886 uint8_t *const best_palette_color_map =
10887 x->palette_buffer->best_palette_color_map;
10888 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010889 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010890
10891 mbmi->mode = DC_PRED;
10892 mbmi->uv_mode = DC_PRED;
10893 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010894 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010895 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010896 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10897 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10898 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010899 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10900 memcpy(color_map, best_palette_color_map,
10901 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010902 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10903 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010904 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10905 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010906 if (rate_uv_intra[uv_tx] == INT_MAX) {
10907 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010908 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10909 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010910 pmi_uv[uv_tx] = *pmi;
10911#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010912 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10913#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010914#if CONFIG_FILTER_INTRA
10915 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10916#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010917 }
10918 mbmi->uv_mode = mode_uv[uv_tx];
10919 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080010920 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010921 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10922 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10923 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080010924 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010925#if CONFIG_EXT_INTRA
10926 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010927#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010928#if CONFIG_FILTER_INTRA
10929 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10930 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10931 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10932 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10933 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10934 }
10935#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010936 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
10937 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
10938 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010939 rate2 += ref_costs_single[INTRA_FRAME];
10940
10941 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010942 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010943#if CONFIG_SUPERTX
10944 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080010945#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010946 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010947 } else {
10948#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010949 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080010950#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010951 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010952 }
10953 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10954 if (this_rd < best_rd) {
10955 best_mode_index = 3;
10956 mbmi->mv[0].as_int = 0;
10957 rd_cost->rate = rate2;
10958#if CONFIG_SUPERTX
10959 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010960#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010961 rd_cost->dist = distortion2;
10962 rd_cost->rdcost = this_rd;
10963 best_rd = this_rd;
10964 best_mbmode = *mbmi;
10965 best_skip2 = 0;
10966 best_mode_skippable = skippable;
10967 }
10968 }
10969PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070010970#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010971
hui su5db97432016-10-14 16:10:14 -070010972#if CONFIG_FILTER_INTRA
10973 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070010974 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070010975 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070010976#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080010977 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070010978#endif // CONFIG_PALETTE
10979 !dc_skipped && best_mode_index >= 0 &&
10980 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070010981 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080010982 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
10983 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070010984#if CONFIG_EXT_INTRA
10985 uv_angle_delta,
10986#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070010987#if CONFIG_PALETTE
10988 pmi_uv, palette_ctx,
10989#endif // CONFIG_PALETTE
10990 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010991 &best_mode_index, &best_skip2, &best_mode_skippable,
10992#if CONFIG_SUPERTX
10993 returnrate_nocoef,
10994#endif // CONFIG_SUPERTX
10995 best_pred_rd, &best_mbmode, rd_cost);
10996 }
hui su5db97432016-10-14 16:10:14 -070010997#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010998
10999 // The inter modes' rate costs are not calculated precisely in some cases.
11000 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11001 // ZEROMV. Here, checks are added for those cases, and the mode decisions
11002 // are corrected.
11003 if (best_mbmode.mode == NEWMV
11004#if CONFIG_EXT_INTER
11005 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
11006#endif // CONFIG_EXT_INTER
11007 ) {
11008 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11009 best_mbmode.ref_frame[1] };
11010 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011011 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011012#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -070011013 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011014#endif // CONFIG_REF_MV
11015#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011016 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11017 cm->allow_high_precision_mv, bsize,
11018 mi_col, mi_row, 0)
11019 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011020 zeromv[1].as_int = comp_pred_mode
11021 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11022 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011023 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011024 .as_int
11025 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011026#else
11027 zeromv[0].as_int = 0;
11028 zeromv[1].as_int = 0;
11029#endif // CONFIG_GLOBAL_MOTION
11030#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011031 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011032 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011033 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011034 : INT_MAX;
11035
11036 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11037 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11038 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11039 best_mbmode.mode = NEARMV;
11040 best_mbmode.ref_mv_idx = i;
11041 }
11042 }
11043
11044 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11045 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011046 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011047 best_mbmode.mode = ZEROMV;
11048 } else {
11049 int_mv nearestmv[2];
11050 int_mv nearmv[2];
11051
11052#if CONFIG_EXT_INTER
11053 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11054 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11055 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11056 } else {
11057 nearmv[0] = frame_mv[NEARMV][refs[0]];
11058 nearmv[1] = frame_mv[NEARMV][refs[1]];
11059 }
11060#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011061 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011062 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011063 : INT_MAX;
11064
11065 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11066 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11067 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11068
11069 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11070 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11071 best_mbmode.mode = NEARMV;
11072 best_mbmode.ref_mv_idx = i;
11073 }
11074 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011075#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011076 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11077 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11078 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11079 } else {
11080 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11081 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11082 }
11083
11084 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
11085 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
11086#if CONFIG_EXT_INTER
11087 best_mbmode.mode = NEAREST_NEARESTMV;
11088 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
11089 nearmv[1].as_int == best_mbmode.mv[1].as_int)
11090 best_mbmode.mode = NEAREST_NEARMV;
11091 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11092 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
11093 best_mbmode.mode = NEAR_NEARESTMV;
11094 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11095 nearmv[1].as_int == best_mbmode.mv[1].as_int)
11096 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011097 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11098 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011099 best_mbmode.mode = ZERO_ZEROMV;
11100#else
11101 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011102 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11103 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011104 best_mbmode.mode = ZEROMV;
11105#endif // CONFIG_EXT_INTER
11106 }
11107#else
11108#if CONFIG_EXT_INTER
11109 if (!comp_pred_mode) {
11110#endif // CONFIG_EXT_INTER
11111 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
11112 ((comp_pred_mode &&
11113 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
11114 !comp_pred_mode))
11115 best_mbmode.mode = NEARESTMV;
11116 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
11117 ((comp_pred_mode &&
11118 frame_mv[NEARMV][refs[1]].as_int ==
11119 best_mbmode.mv[1].as_int) ||
11120 !comp_pred_mode))
11121 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011122 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11123 ((comp_pred_mode &&
11124 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -070011125 !comp_pred_mode))
11126 best_mbmode.mode = ZEROMV;
11127#if CONFIG_EXT_INTER
11128 } else {
Sarah Parkerc2d38712017-01-24 15:15:41 -080011129 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11130 best_mbmode.ref_frame[1] };
11131 int_mv zeromv[2];
11132#if CONFIG_GLOBAL_MOTION
11133 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011134 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011135 bsize, mi_col, mi_row, 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -080011136 .as_int;
Sarah Parkerae7c4582017-02-28 16:30:30 -080011137 zeromv[1].as_int = comp_pred_mode
11138 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11139 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011140 bsize, mi_col, mi_row, 0)
Sarah Parkerae7c4582017-02-28 16:30:30 -080011141 .as_int
11142 : 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011143#else
11144 zeromv[0].as_int = 0;
11145 zeromv[1].as_int = 0;
11146#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011147 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
11148 best_mbmode.mv[0].as_int &&
11149 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
11150 best_mbmode.mv[1].as_int)
11151 best_mbmode.mode = NEAREST_NEARESTMV;
11152 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
11153 best_mbmode.mv[0].as_int &&
11154 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
11155 best_mbmode.mv[1].as_int)
11156 best_mbmode.mode = NEAREST_NEARMV;
11157 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
11158 best_mbmode.mv[0].as_int &&
11159 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
11160 best_mbmode.mv[1].as_int)
11161 best_mbmode.mode = NEAR_NEARESTMV;
11162 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
11163 best_mbmode.mv[0].as_int &&
11164 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
11165 best_mbmode.mv[1].as_int)
11166 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011167 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11168 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011169 best_mbmode.mode = ZERO_ZEROMV;
11170 }
11171#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -080011172#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011173 }
11174
11175#if CONFIG_REF_MV
David Barkercdcac6d2016-12-01 17:04:16 +000011176 {
Jingning Han731af492016-11-17 11:53:23 -080011177 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11178 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011179 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011180 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011181#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011182 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11183 best_mbmode.ref_frame[1] };
11184 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011185 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011186 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011187 .as_int;
11188 zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
David Barker45390c12017-02-20 14:44:40 +000011189 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011190 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011191 .as_int;
11192 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11193 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11194#else
11195 zeromv[0].as_int = zeromv[1].as_int = 0;
11196#endif // CONFIG_GLOBAL_MOTION
11197 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11198 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11199#if CONFIG_EXT_INTER
11200 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11201#else
Emil Keyder01770b32017-01-20 18:03:11 -050011202 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011203 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11204#endif // CONFIG_EXT_INTER
11205 ) {
11206 best_mbmode.mode = ZEROMV;
11207 }
David Barker68e6e862016-11-24 15:10:15 +000011208 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011209 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011210#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011211
11212 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11213 rd_cost->rate = INT_MAX;
11214 rd_cost->rdcost = INT64_MAX;
11215 return;
11216 }
11217
Yaowu Xuc27fc142016-08-22 16:08:15 -070011218#if CONFIG_DUAL_FILTER
11219 assert((cm->interp_filter == SWITCHABLE) ||
11220 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11221 !is_inter_block(&best_mbmode));
11222 assert((cm->interp_filter == SWITCHABLE) ||
11223 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11224 !is_inter_block(&best_mbmode));
11225 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11226 assert((cm->interp_filter == SWITCHABLE) ||
11227 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11228 !is_inter_block(&best_mbmode));
11229 assert((cm->interp_filter == SWITCHABLE) ||
11230 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11231 !is_inter_block(&best_mbmode));
11232 }
11233#else
11234 assert((cm->interp_filter == SWITCHABLE) ||
11235 (cm->interp_filter == best_mbmode.interp_filter) ||
11236 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011237#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011238
11239 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011240 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11241 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011242
11243 // macroblock modes
11244 *mbmi = best_mbmode;
11245 x->skip |= best_skip2;
11246
Yue Chen19e7aa82016-11-30 14:05:39 -080011247// Note: this section is needed since the mode may have been forced to
11248// ZEROMV by the all-zero mode handling of ref-mv.
11249#if CONFIG_GLOBAL_MOTION
11250 if (mbmi->mode == ZEROMV
11251#if CONFIG_EXT_INTER
11252 || mbmi->mode == ZERO_ZEROMV
11253#endif // CONFIG_EXT_INTER
11254 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011255#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11256 // Correct the motion mode for ZEROMV
11257 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11258#if SEPARATE_GLOBAL_MOTION
11259 0, xd->global_motion,
11260#endif // SEPARATE_GLOBAL_MOTION
11261 xd->mi[0]);
11262 if (mbmi->motion_mode > last_motion_mode_allowed)
11263 mbmi->motion_mode = last_motion_mode_allowed;
11264#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11265
11266 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011267 if (is_nontrans_global_motion(xd)) {
11268#if CONFIG_DUAL_FILTER
11269 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11270 ? EIGHTTAP_REGULAR
11271 : cm->interp_filter;
11272 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11273 ? EIGHTTAP_REGULAR
11274 : cm->interp_filter;
11275#else
11276 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11277 : cm->interp_filter;
11278#endif // CONFIG_DUAL_FILTER
11279 }
11280 }
11281#endif // CONFIG_GLOBAL_MOTION
11282
Yaowu Xuc27fc142016-08-22 16:08:15 -070011283#if CONFIG_REF_MV
11284 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11285 if (mbmi->mode != NEWMV)
11286 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11287 else
11288 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11289 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011290#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011291
11292 for (i = 0; i < REFERENCE_MODES; ++i) {
11293 if (best_pred_rd[i] == INT64_MAX)
11294 best_pred_diff[i] = INT_MIN;
11295 else
11296 best_pred_diff[i] = best_rd - best_pred_rd[i];
11297 }
11298
11299 x->skip |= best_mode_skippable;
11300
11301 assert(best_mode_index >= 0);
11302
11303 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11304 best_mode_skippable);
11305
Urvang Joshib100db72016-10-12 16:28:56 -070011306#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011307 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11308 restore_uv_color_map(cpi, x);
11309 }
Urvang Joshib100db72016-10-12 16:28:56 -070011310#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011311}
11312
Urvang Joshi52648442016-10-13 17:27:51 -070011313void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11314 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011315 int mi_row, int mi_col,
Urvang Joshi52648442016-10-13 17:27:51 -070011316 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011317 PICK_MODE_CONTEXT *ctx,
11318 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011319 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011320 MACROBLOCKD *const xd = &x->e_mbd;
11321 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11322 unsigned char segment_id = mbmi->segment_id;
11323 const int comp_pred = 0;
11324 int i;
11325 int64_t best_pred_diff[REFERENCE_MODES];
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;
James Zern7b9407a2016-05-18 23:48:05 -070011329 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011330 int64_t this_rd = INT64_MAX;
11331 int rate2 = 0;
11332 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011333 (void)mi_row;
11334 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011335
11336 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11337 &comp_mode_p);
11338
11339 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11340 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11341 x->pred_mv_sad[i] = INT_MAX;
11342
11343 rd_cost->rate = INT_MAX;
11344
11345 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11346
Urvang Joshib100db72016-10-12 16:28:56 -070011347#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011348 mbmi->palette_mode_info.palette_size[0] = 0;
11349 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011350#endif // CONFIG_PALETTE
11351
hui su5db97432016-10-14 16:10:14 -070011352#if CONFIG_FILTER_INTRA
11353 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11354 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11355#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011356 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011357 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011358 mbmi->uv_mode = DC_PRED;
11359 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011360 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011361#if CONFIG_GLOBAL_MOTION
11362 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011363 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011364 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11365 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011366 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011367#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011368 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011369#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011370 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011371 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011372
Yaowu Xuc27fc142016-08-22 16:08:15 -070011373#if CONFIG_REF_MV
11374 mbmi->ref_mv_idx = 0;
11375 mbmi->pred_mv[0].as_int = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011376#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011377
11378 if (cm->interp_filter != BILINEAR) {
11379 best_filter = EIGHTTAP_REGULAR;
11380 if (cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011381 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11382 int rs;
11383 int best_rs = INT_MAX;
11384 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11385#if CONFIG_DUAL_FILTER
11386 int k;
11387 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11388#else
11389 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011390#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011391 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011392 if (rs < best_rs) {
11393 best_rs = rs;
11394#if CONFIG_DUAL_FILTER
11395 best_filter = mbmi->interp_filter[0];
11396#else
11397 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011398#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011399 }
11400 }
11401 }
11402 }
11403 // Set the appropriate filter
11404 if (cm->interp_filter == SWITCHABLE) {
11405#if CONFIG_DUAL_FILTER
11406 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
11407#else
11408 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011409#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011410 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011411 } else {
11412#if CONFIG_DUAL_FILTER
11413 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
11414#else
11415 mbmi->interp_filter = cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011416#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011417 }
11418
11419 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011420 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011421
11422 // Estimate the reference frame signaling cost and add it
11423 // to the rolling cost variable.
11424 rate2 += ref_costs_single[LAST_FRAME];
11425 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11426
11427 rd_cost->rate = rate2;
11428 rd_cost->dist = distortion2;
11429 rd_cost->rdcost = this_rd;
11430
11431 if (this_rd >= best_rd_so_far) {
11432 rd_cost->rate = INT_MAX;
11433 rd_cost->rdcost = INT64_MAX;
11434 return;
11435 }
11436
11437#if CONFIG_DUAL_FILTER
11438 assert((cm->interp_filter == SWITCHABLE) ||
11439 (cm->interp_filter == mbmi->interp_filter[0]));
11440#else
11441 assert((cm->interp_filter == SWITCHABLE) ||
11442 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011443#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011444
Yaowu Xuf883b422016-08-30 14:01:10 -070011445 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11446 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011447
Yaowu Xuf883b422016-08-30 14:01:10 -070011448 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011449
11450 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11451}
11452
Urvang Joshi52648442016-10-13 17:27:51 -070011453void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11454 TileDataEnc *tile_data, struct macroblock *x,
11455 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070011456 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011457#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011458 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011459#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011460 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11461 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011462 const AV1_COMMON *const cm = &cpi->common;
11463 const RD_OPT *const rd_opt = &cpi->rd;
11464 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011465 MACROBLOCKD *const xd = &x->e_mbd;
11466 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11467 const struct segmentation *const seg = &cm->seg;
11468 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11469 unsigned char segment_id = mbmi->segment_id;
11470 int comp_pred, i;
11471 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11472 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11473 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11474 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011475 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011476#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011477 AOM_LAST2_FLAG,
11478 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011479#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011480 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011481#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011482 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011483#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011484 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011485 };
11486 int64_t best_rd = best_rd_so_far;
11487 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11488 int64_t best_pred_diff[REFERENCE_MODES];
11489 int64_t best_pred_rd[REFERENCE_MODES];
11490 MB_MODE_INFO best_mbmode;
11491 int ref_index, best_ref_index = 0;
11492 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11493 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011494 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011495#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011496 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011497#else
James Zern7b9407a2016-05-18 23:48:05 -070011498 InterpFilter tmp_best_filter = SWITCHABLE;
Fergus Simpson4063a682017-02-28 16:52:22 -080011499#endif // CONFIG_DUAL_FILTER
Jingning Han3f167252016-06-07 16:11:42 -070011500 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11501 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011502 int skip_uv;
11503 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011504 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011505 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
11506#if CONFIG_EXT_INTER
11507 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
11508#else
11509 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
11510#endif // CONFIG_EXT_INTER
11511 b_mode_info best_bmodes[4];
11512 int best_skip2 = 0;
11513 int ref_frame_skip_mask[2] = { 0 };
11514 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011515 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011516#if CONFIG_PVQ
11517 od_rollback_buffer pre_buf;
11518
11519 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011520#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070011521
11522#if CONFIG_SUPERTX
11523 best_rd_so_far = INT64_MAX;
11524 best_rd = best_rd_so_far;
11525 best_yrd = best_rd_so_far;
11526#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011527 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011528
hui su5db97432016-10-14 16:10:14 -070011529#if CONFIG_FILTER_INTRA
11530 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11531 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11532#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011533 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011534#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -080011535 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011536 mbmi->use_wedge_interintra = 0;
11537#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011538#if CONFIG_WARPED_MOTION
11539 mbmi->num_proj_ref[0] = 0;
11540 mbmi->num_proj_ref[1] = 0;
11541#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011542
11543 for (i = 0; i < 4; i++) {
11544 int j;
11545#if CONFIG_EXT_INTER
11546 int k;
11547
11548 for (k = 0; k < 2; k++)
11549 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11550 seg_mvs[i][k][j].as_int = INVALID_MV;
11551#else
11552 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11553 seg_mvs[i][j].as_int = INVALID_MV;
11554#endif // CONFIG_EXT_INTER
11555 }
11556
11557 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11558 &comp_mode_p);
11559
11560 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11561 rate_uv_intra = INT_MAX;
11562
11563 rd_cost->rate = INT_MAX;
11564#if CONFIG_SUPERTX
11565 *returnrate_nocoef = INT_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -080011566#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011567
11568 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11569 x->mbmi_ext->mode_context[ref_frame] = 0;
11570#if CONFIG_REF_MV && CONFIG_EXT_INTER
11571 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
11572#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
11573 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11574 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11575 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11576 } else {
11577 ref_frame_skip_mask[0] |= (1 << ref_frame);
11578 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11579 }
11580 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11581#if CONFIG_EXT_INTER
11582 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
11583#endif // CONFIG_EXT_INTER
11584 frame_mv[ZEROMV][ref_frame].as_int = 0;
11585 }
11586
Urvang Joshib100db72016-10-12 16:28:56 -070011587#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011588 mbmi->palette_mode_info.palette_size[0] = 0;
11589 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011590#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011591
11592 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11593 int mode_excluded = 0;
11594 int64_t this_rd = INT64_MAX;
11595 int disable_skip = 0;
11596 int compmode_cost = 0;
11597 int rate2 = 0, rate_y = 0, rate_uv = 0;
11598 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11599 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011600 int this_skip2 = 0;
11601 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011602
Yushin Cho77bba8d2016-11-04 16:36:56 -070011603#if CONFIG_PVQ
11604 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011605#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -070011606
Yaowu Xuf883b422016-08-30 14:01:10 -070011607 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11608 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011609
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011610#if CONFIG_REF_MV
11611 mbmi->ref_mv_idx = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011612#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011613
Yaowu Xuc27fc142016-08-22 16:08:15 -070011614 // Look at the reference frame of the best mode so far and set the
11615 // skip mask to look at a subset of the remaining modes.
11616 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11617 if (ref_index == 3) {
11618 switch (best_mbmode.ref_frame[0]) {
11619 case INTRA_FRAME: break;
11620 case LAST_FRAME:
11621 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11622#if CONFIG_EXT_REFS
11623 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11624 (1 << BWDREF_FRAME) |
11625#endif // CONFIG_EXT_REFS
11626 (1 << ALTREF_FRAME);
11627 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11628 break;
11629#if CONFIG_EXT_REFS
11630 case LAST2_FRAME:
11631 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11632 (1 << GOLDEN_FRAME) |
11633 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11634 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11635 break;
11636 case LAST3_FRAME:
11637 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11638 (1 << GOLDEN_FRAME) |
11639 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11640 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11641 break;
11642#endif // CONFIG_EXT_REFS
11643 case GOLDEN_FRAME:
11644 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11645#if CONFIG_EXT_REFS
11646 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11647 (1 << BWDREF_FRAME) |
11648#endif // CONFIG_EXT_REFS
11649 (1 << ALTREF_FRAME);
11650 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11651 break;
11652#if CONFIG_EXT_REFS
11653 case BWDREF_FRAME:
11654 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11655 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11656 (1 << ALTREF_FRAME);
11657 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11658 break;
11659#endif // CONFIG_EXT_REFS
11660 case ALTREF_FRAME:
11661 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11662#if CONFIG_EXT_REFS
11663 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11664 (1 << BWDREF_FRAME) |
11665#endif // CONFIG_EXT_REFS
11666 (1 << GOLDEN_FRAME);
11667#if CONFIG_EXT_REFS
11668 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11669#endif // CONFIG_EXT_REFS
11670 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011671 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011672 case TOTAL_REFS_PER_FRAME:
11673 assert(0 && "Invalid Reference frame");
11674 break;
11675 }
11676 }
11677 }
11678
11679 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011680 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011681 continue;
11682
11683 // Test best rd so far against threshold for trying this mode.
11684 if (!internal_active_edge &&
11685 rd_less_than_thresh(best_rd,
11686 rd_opt->threshes[segment_id][bsize][ref_index],
11687 tile_data->thresh_freq_fact[bsize][ref_index]))
11688 continue;
11689
11690 comp_pred = second_ref_frame > INTRA_FRAME;
11691 if (comp_pred) {
11692 if (!cpi->allow_comp_inter_inter) continue;
11693 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11694 // Do not allow compound prediction if the segment level reference frame
11695 // feature is in use as in this case there can only be one reference.
11696 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11697
11698 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11699 best_mbmode.ref_frame[0] == INTRA_FRAME)
11700 continue;
11701 }
11702
11703 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11704 // sub8x8 blocks.
11705 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011706 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011707 continue;
11708
11709 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011710 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011711 continue;
11712
11713 if (comp_pred)
11714 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11715 else if (ref_frame != INTRA_FRAME)
11716 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11717
11718 // If the segment reference frame feature is enabled....
11719 // then do nothing if the current ref frame is not allowed..
11720 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11721 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11722 continue;
11723 // Disable this drop out case if the ref frame
11724 // segment level feature is enabled for this segment. This is to
11725 // prevent the possibility that we end up unable to pick any mode.
11726 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11727 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11728 // unless ARNR filtering is enabled in which case we want
11729 // an unfiltered alternative. We allow near/nearest as well
11730 // because they may result in zero-zero MVs but be cheaper.
11731 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11732 continue;
11733 }
11734
11735 mbmi->tx_size = TX_4X4;
11736 mbmi->uv_mode = DC_PRED;
11737 mbmi->ref_frame[0] = ref_frame;
11738 mbmi->ref_frame[1] = second_ref_frame;
11739// Evaluate all sub-pel filters irrespective of whether we can use
11740// them for this frame.
11741#if CONFIG_DUAL_FILTER
11742 for (i = 0; i < 4; ++i)
11743 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11744 ? EIGHTTAP_REGULAR
11745 : cm->interp_filter;
11746#else
11747 mbmi->interp_filter =
11748 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011749#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011750 x->skip = 0;
11751 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11752
11753 // Select prediction reference frames.
11754 for (i = 0; i < MAX_MB_PLANE; i++) {
11755 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11756 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11757 }
11758
11759#if CONFIG_VAR_TX
11760 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011761 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -080011762#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011763
11764 if (ref_frame == INTRA_FRAME) {
11765 int rate;
11766 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011767 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011768 continue;
11769 rate2 += rate;
11770 rate2 += intra_cost_penalty;
11771 distortion2 += distortion_y;
11772
11773 if (rate_uv_intra == INT_MAX) {
11774 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11775 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11776 }
11777 rate2 += rate_uv_intra;
11778 rate_uv = rate_uv_tokenonly;
11779 distortion2 += dist_uv;
11780 distortion_uv = dist_uv;
11781 mbmi->uv_mode = mode_uv;
11782 } else {
11783 int rate;
11784 int64_t distortion;
11785 int64_t this_rd_thresh;
11786 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11787 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11788 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11789 int tmp_best_skippable = 0;
11790 int switchable_filter_index;
11791 int_mv *second_ref =
11792 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11793 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11794 MB_MODE_INFO tmp_best_mbmode;
11795#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011796 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011797#else
11798 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
Fergus Simpson4063a682017-02-28 16:52:22 -080011799#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011800 int pred_exists = 0;
11801 int uv_skippable;
11802#if CONFIG_EXT_INTER
11803 int_mv compound_seg_newmvs[4][2];
11804 for (i = 0; i < 4; i++) {
11805 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11806 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11807 }
11808#endif // CONFIG_EXT_INTER
11809
11810 this_rd_thresh = (ref_frame == LAST_FRAME)
11811 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11812 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11813#if CONFIG_EXT_REFS
11814 this_rd_thresh = (ref_frame == LAST2_FRAME)
11815 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11816 : this_rd_thresh;
11817 this_rd_thresh = (ref_frame == LAST3_FRAME)
11818 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11819 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011820 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11821 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11822 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011823#endif // CONFIG_EXT_REFS
11824 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11825 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11826 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011827
11828 // TODO(any): Add search of the tx_type to improve rd performance at the
11829 // expense of speed.
11830 mbmi->tx_type = DCT_DCT;
11831
11832 if (cm->interp_filter != BILINEAR) {
11833#if CONFIG_DUAL_FILTER
11834 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11835 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11836 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11837 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11838#else
11839 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011840#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011841 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11842#if CONFIG_DUAL_FILTER
11843 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11844#else
11845 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011846#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011847 } else if (sf->adaptive_pred_interp_filter == 1 &&
11848 ctx->pred_interp_filter < SWITCHABLE) {
11849#if CONFIG_DUAL_FILTER
11850 tmp_best_filter[0] = ctx->pred_interp_filter;
11851#else
11852 tmp_best_filter = ctx->pred_interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011853#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011854 } else if (sf->adaptive_pred_interp_filter == 2) {
11855#if CONFIG_DUAL_FILTER
11856 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
11857 ? ctx->pred_interp_filter
11858 : 0;
11859#else
11860 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
11861 ? ctx->pred_interp_filter
11862 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011863#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011864 } else {
11865#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011866 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011867#else
Angie Chiang5678ad92016-11-21 09:38:40 -080011868 const int filter_set_size = SWITCHABLE_FILTERS;
Fergus Simpson4063a682017-02-28 16:52:22 -080011869#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011870 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080011871 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011872 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011873 int newbest, rs;
11874 int64_t rs_rd;
11875 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
11876#if CONFIG_DUAL_FILTER
11877 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
11878 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
11879 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
11880 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
11881#else
11882 mbmi->interp_filter = switchable_filter_index;
Fergus Simpson4063a682017-02-28 16:52:22 -080011883#endif // CONFIG_DUAL_FILTER
Yushin Cho482016d2017-01-06 14:06:13 -080011884 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011885 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11886 &rate, &rate_y, &distortion, &skippable, &total_sse,
11887 (int)this_rd_thresh, seg_mvs,
11888#if CONFIG_EXT_INTER
11889 compound_seg_newmvs,
11890#endif // CONFIG_EXT_INTER
11891 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011892 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070011893 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011894 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
11895 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
11896
11897 newbest = (tmp_rd < tmp_best_rd);
11898 if (newbest) {
11899#if CONFIG_DUAL_FILTER
11900 tmp_best_filter[0] = mbmi->interp_filter[0];
11901 tmp_best_filter[1] = mbmi->interp_filter[1];
11902 tmp_best_filter[2] = mbmi->interp_filter[2];
11903 tmp_best_filter[3] = mbmi->interp_filter[3];
11904#else
11905 tmp_best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011906#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011907 tmp_best_rd = tmp_rd;
11908 }
11909 if ((newbest && cm->interp_filter == SWITCHABLE) ||
11910 (
11911#if CONFIG_DUAL_FILTER
11912 mbmi->interp_filter[0] == cm->interp_filter
11913#else
11914 mbmi->interp_filter == cm->interp_filter
Fergus Simpson4063a682017-02-28 16:52:22 -080011915#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011916 && cm->interp_filter != SWITCHABLE)) {
11917 tmp_best_rdu = tmp_rd;
11918 tmp_best_rate = rate;
11919 tmp_best_ratey = rate_y;
11920 tmp_best_distortion = distortion;
11921 tmp_best_sse = total_sse;
11922 tmp_best_skippable = skippable;
11923 tmp_best_mbmode = *mbmi;
11924 for (i = 0; i < 4; i++) {
11925 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
11926 }
11927 pred_exists = 1;
11928 }
11929 } // switchable_filter_index loop
11930 }
11931 }
11932
11933 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
11934
11935#if CONFIG_DUAL_FILTER
11936 mbmi->interp_filter[0] =
11937 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
11938 : cm->interp_filter);
11939 mbmi->interp_filter[1] =
11940 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
11941 : cm->interp_filter);
11942 mbmi->interp_filter[2] =
11943 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
11944 : cm->interp_filter);
11945 mbmi->interp_filter[3] =
11946 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
11947 : cm->interp_filter);
11948#else
11949 mbmi->interp_filter =
11950 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
11951 : cm->interp_filter);
Fergus Simpson4063a682017-02-28 16:52:22 -080011952#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011953
11954 if (!pred_exists) {
11955 // Handles the special case when a filter that is not in the
11956 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080011957 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011958 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11959 &rate, &rate_y, &distortion, &skippable, &total_sse,
11960 (int)this_rd_thresh, seg_mvs,
11961#if CONFIG_EXT_INTER
11962 compound_seg_newmvs,
11963#endif // CONFIG_EXT_INTER
11964 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011965 if (tmp_rd == INT64_MAX) continue;
11966 } else {
11967 total_sse = tmp_best_sse;
11968 rate = tmp_best_rate;
11969 rate_y = tmp_best_ratey;
11970 distortion = tmp_best_distortion;
11971 skippable = tmp_best_skippable;
11972 *mbmi = tmp_best_mbmode;
11973 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
11974 }
11975 // Add in the cost of the transform type
11976 if (!xd->lossless[mbmi->segment_id]) {
11977 int rate_tx_type = 0;
11978#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080011979 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
11980 1) {
11981 const int eset =
11982 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011983 rate_tx_type =
11984 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
11985 }
11986#else
11987 if (mbmi->tx_size < TX_32X32) {
11988 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
11989 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011990#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011991 rate += rate_tx_type;
11992 rate_y += rate_tx_type;
11993 }
11994
11995 rate2 += rate;
11996 distortion2 += distortion;
11997
11998 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070011999 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012000
12001 if (!mode_excluded)
12002 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
12003 : cm->reference_mode == COMPOUND_REFERENCE;
12004
Yaowu Xuf883b422016-08-30 14:01:10 -070012005 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012006
12007 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070012008 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012009 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
12010
12011 if (tmp_best_rdu > 0) {
12012 // If even the 'Y' rd value of split is higher than best so far
12013 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070012014 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070012015 RD_STATS rd_stats_uv;
David Barkerac37fa32016-12-02 12:30:21 +000012016 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
12017 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012018#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012019 is_cost_valid_uv =
12020 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080012021#else
12022 is_cost_valid_uv =
12023 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Fergus Simpson4063a682017-02-28 16:52:22 -080012024#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012025 rate_uv = rd_stats_uv.rate;
12026 distortion_uv = rd_stats_uv.dist;
12027 uv_skippable = rd_stats_uv.skip;
12028 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080012029
Angie Chiangb5dda482016-11-02 16:19:58 -070012030 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012031 rate2 += rate_uv;
12032 distortion2 += distortion_uv;
12033 skippable = skippable && uv_skippable;
12034 total_sse += uv_sse;
12035 } else {
12036 continue;
12037 }
12038 }
12039
12040 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
12041
12042 // Estimate the reference frame signaling cost and add it
12043 // to the rolling cost variable.
12044 if (second_ref_frame > INTRA_FRAME) {
12045 rate2 += ref_costs_comp[ref_frame];
12046#if CONFIG_EXT_REFS
12047 rate2 += ref_costs_comp[second_ref_frame];
12048#endif // CONFIG_EXT_REFS
12049 } else {
12050 rate2 += ref_costs_single[ref_frame];
12051 }
12052
12053 if (!disable_skip) {
12054 // Skip is never coded at the segment level for sub8x8 blocks and instead
12055 // always coded in the bitstream at the mode info level.
12056
12057 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
12058 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
12059 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
12060 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012061 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012062 } else {
12063 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070012064 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012065 distortion2 = total_sse;
12066 assert(total_sse >= 0);
12067 rate2 -= (rate_y + rate_uv);
12068 rate_y = 0;
12069 rate_uv = 0;
12070 this_skip2 = 1;
12071 }
12072 } else {
12073 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012074 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012075 }
12076
12077 // Calculate the final RD estimate for this mode.
12078 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
12079 }
12080
12081 if (!disable_skip && ref_frame == INTRA_FRAME) {
12082 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070012083 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012084 }
12085
12086 // Did this mode help.. i.e. is it the new best mode
12087 if (this_rd < best_rd || x->skip) {
12088 if (!mode_excluded) {
12089 // Note index of best mode so far
12090 best_ref_index = ref_index;
12091
12092 if (ref_frame == INTRA_FRAME) {
12093 /* required for left and above block mv */
12094 mbmi->mv[0].as_int = 0;
12095 }
12096
12097 rd_cost->rate = rate2;
12098#if CONFIG_SUPERTX
12099 *returnrate_nocoef = rate2 - rate_y - rate_uv;
12100 if (!disable_skip)
12101 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070012102 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
12103 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
12104 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012105 assert(*returnrate_nocoef > 0);
12106#endif // CONFIG_SUPERTX
12107 rd_cost->dist = distortion2;
12108 rd_cost->rdcost = this_rd;
12109 best_rd = this_rd;
12110 best_yrd =
12111 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
12112 best_mbmode = *mbmi;
12113 best_skip2 = this_skip2;
12114
12115#if CONFIG_VAR_TX
12116 for (i = 0; i < MAX_MB_PLANE; ++i)
12117 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080012118#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012119
12120 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070012121 }
12122 }
12123
12124 /* keep record of best compound/single-only prediction */
12125 if (!disable_skip && ref_frame != INTRA_FRAME) {
12126 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
12127
12128 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
12129 single_rate = rate2 - compmode_cost;
12130 hybrid_rate = rate2;
12131 } else {
12132 single_rate = rate2;
12133 hybrid_rate = rate2 + compmode_cost;
12134 }
12135
12136 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
12137 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
12138
12139 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
12140 best_pred_rd[SINGLE_REFERENCE] = single_rd;
12141 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
12142 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
12143
12144 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
12145 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
12146 }
12147
Yaowu Xuc27fc142016-08-22 16:08:15 -070012148 if (x->skip && !comp_pred) break;
12149 }
12150
12151 if (best_rd >= best_rd_so_far) {
12152 rd_cost->rate = INT_MAX;
12153 rd_cost->rdcost = INT64_MAX;
12154#if CONFIG_SUPERTX
12155 *returnrate_nocoef = INT_MAX;
12156#endif // CONFIG_SUPERTX
12157 return;
12158 }
12159
Yaowu Xuc27fc142016-08-22 16:08:15 -070012160 if (best_rd == INT64_MAX) {
12161 rd_cost->rate = INT_MAX;
12162 rd_cost->dist = INT64_MAX;
12163 rd_cost->rdcost = INT64_MAX;
12164#if CONFIG_SUPERTX
12165 *returnrate_nocoef = INT_MAX;
12166#endif // CONFIG_SUPERTX
12167 return;
12168 }
12169
12170#if CONFIG_DUAL_FILTER
12171 assert((cm->interp_filter == SWITCHABLE) ||
12172 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12173 !is_inter_block(&best_mbmode));
12174#else
12175 assert((cm->interp_filter == SWITCHABLE) ||
12176 (cm->interp_filter == best_mbmode.interp_filter) ||
12177 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080012178#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012179
Yaowu Xuf883b422016-08-30 14:01:10 -070012180 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12181 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012182
12183 // macroblock modes
12184 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012185#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012186 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080012187#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012188
12189 x->skip |= best_skip2;
12190 if (!is_inter_block(&best_mbmode)) {
12191 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12192 } else {
12193 for (i = 0; i < 4; ++i)
12194 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12195
Yaowu Xuc27fc142016-08-22 16:08:15 -070012196#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012197 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12198 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Fergus Simpson4063a682017-02-28 16:52:22 -080012199#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012200 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12201 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012202 }
12203
Yue Chen19e7aa82016-11-30 14:05:39 -080012204// Note: this section is needed since the mode may have been forced to ZEROMV
12205#if CONFIG_GLOBAL_MOTION
12206 if (mbmi->mode == ZEROMV
12207#if CONFIG_EXT_INTER
12208 || mbmi->mode == ZERO_ZEROMV
12209#endif // CONFIG_EXT_INTER
12210 ) {
12211 if (is_nontrans_global_motion(xd)) {
12212#if CONFIG_DUAL_FILTER
12213 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12214 ? EIGHTTAP_REGULAR
12215 : cm->interp_filter;
12216 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12217 ? EIGHTTAP_REGULAR
12218 : cm->interp_filter;
12219#else
12220 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12221 : cm->interp_filter;
12222#endif // CONFIG_DUAL_FILTER
12223 }
12224 }
12225#endif // CONFIG_GLOBAL_MOTION
12226
Yaowu Xuc27fc142016-08-22 16:08:15 -070012227 for (i = 0; i < REFERENCE_MODES; ++i) {
12228 if (best_pred_rd[i] == INT64_MAX)
12229 best_pred_diff[i] = INT_MIN;
12230 else
12231 best_pred_diff[i] = best_rd - best_pred_rd[i];
12232 }
12233
12234 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12235}
12236
Yue Chencb60b182016-10-13 15:18:22 -070012237#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012238// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012239//
12240// The OBMC predictor is computed as:
12241//
12242// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012243// AOM_BLEND_A64(Mh(x),
12244// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012245// PLeft(x, y))
12246//
Yaowu Xuf883b422016-08-30 14:01:10 -070012247// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012248// rounding, this can be written as:
12249//
Yaowu Xuf883b422016-08-30 14:01:10 -070012250// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012251// Mh(x) * Mv(y) * P(x,y) +
12252// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012253// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012254//
12255// Where :
12256//
Yaowu Xuf883b422016-08-30 14:01:10 -070012257// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12258// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012259//
12260// This function computes 'wsrc' and 'mask' as:
12261//
12262// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012263// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012264// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012265// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012266//
12267// mask(x, y) = Mh(x) * Mv(y)
12268//
12269// These can then be used to efficiently approximate the error for any
12270// predictor P in the context of the provided neighbouring predictors by
12271// computing:
12272//
12273// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012274// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012275//
Yaowu Xuf883b422016-08-30 14:01:10 -070012276static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012277 const MACROBLOCKD *xd, int mi_row,
12278 int mi_col, const uint8_t *above,
12279 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012280 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012281 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12282 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012283 const int bw = xd->n8_w << MI_SIZE_LOG2;
12284 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012285 int32_t *mask_buf = x->mask_buf;
12286 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012287 const int wsrc_stride = bw;
12288 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012289 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
12290#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012291 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12292#else
12293 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070012294#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012295
12296 // plane 0 should not be subsampled
12297 assert(xd->plane[0].subsampling_x == 0);
12298 assert(xd->plane[0].subsampling_y == 0);
12299
Yaowu Xuf883b422016-08-30 14:01:10 -070012300 av1_zero_array(wsrc_buf, bw * bh);
12301 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012302
12303 // handle above row
12304 if (xd->up_available) {
12305 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012306 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012307 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012308 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012309
12310 assert(miw > 0);
12311
12312 i = 0;
12313 do { // for each mi in the above row
12314 const int mi_col_offset = i;
12315 const MB_MODE_INFO *const above_mbmi =
12316 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12317 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012318 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012319 const int neighbor_bw = mi_step * MI_SIZE;
12320
12321 if (is_neighbor_overlappable(above_mbmi)) {
12322 const int tmp_stride = above_stride;
12323 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12324 int32_t *mask = mask_buf + (i * MI_SIZE);
12325
12326 if (!is_hbd) {
12327 const uint8_t *tmp = above;
12328
12329 for (row = 0; row < overlap; ++row) {
12330 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012331 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012332 for (col = 0; col < neighbor_bw; ++col) {
12333 wsrc[col] = m1 * tmp[col];
12334 mask[col] = m0;
12335 }
12336 wsrc += wsrc_stride;
12337 mask += mask_stride;
12338 tmp += tmp_stride;
12339 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012340#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012341 } else {
12342 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12343
12344 for (row = 0; row < overlap; ++row) {
12345 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012346 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012347 for (col = 0; col < neighbor_bw; ++col) {
12348 wsrc[col] = m1 * tmp[col];
12349 mask[col] = m0;
12350 }
12351 wsrc += wsrc_stride;
12352 mask += mask_stride;
12353 tmp += tmp_stride;
12354 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012355#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012356 }
12357 }
12358
12359 above += neighbor_bw;
12360 i += mi_step;
12361 } while (i < miw);
12362 }
12363
12364 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012365 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12366 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012367 }
12368
12369 // handle left column
12370 if (xd->left_available) {
12371 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012372 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012373 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012374 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012375
12376 assert(mih > 0);
12377
12378 i = 0;
12379 do { // for each mi in the left column
12380 const int mi_row_offset = i;
12381 const MB_MODE_INFO *const left_mbmi =
12382 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12383 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012384 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012385 const int neighbor_bh = mi_step * MI_SIZE;
12386
12387 if (is_neighbor_overlappable(left_mbmi)) {
12388 const int tmp_stride = left_stride;
12389 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12390 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12391
12392 if (!is_hbd) {
12393 const uint8_t *tmp = left;
12394
12395 for (row = 0; row < neighbor_bh; ++row) {
12396 for (col = 0; col < overlap; ++col) {
12397 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012398 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12399 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12400 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12401 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012402 }
12403 wsrc += wsrc_stride;
12404 mask += mask_stride;
12405 tmp += tmp_stride;
12406 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012407#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012408 } else {
12409 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
12410
12411 for (row = 0; row < neighbor_bh; ++row) {
12412 for (col = 0; col < overlap; ++col) {
12413 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012414 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12415 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12416 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12417 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012418 }
12419 wsrc += wsrc_stride;
12420 mask += mask_stride;
12421 tmp += tmp_stride;
12422 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012423#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012424 }
12425 }
12426
12427 left += neighbor_bh * left_stride;
12428 i += mi_step;
12429 } while (i < mih);
12430 }
12431
12432 if (!is_hbd) {
12433 const uint8_t *src = x->plane[0].src.buf;
12434
12435 for (row = 0; row < bh; ++row) {
12436 for (col = 0; col < bw; ++col) {
12437 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12438 }
12439 wsrc_buf += wsrc_stride;
12440 src += x->plane[0].src.stride;
12441 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012442#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012443 } else {
12444 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12445
12446 for (row = 0; row < bh; ++row) {
12447 for (col = 0; col < bw; ++col) {
12448 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12449 }
12450 wsrc_buf += wsrc_stride;
12451 src += x->plane[0].src.stride;
12452 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012453#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012454 }
12455}
Yue Chenf27b1602017-01-13 11:11:43 -080012456
12457#if CONFIG_NCOBMC
12458void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12459 int mi_row, int mi_col) {
12460 const AV1_COMMON *const cm = &cpi->common;
12461 MACROBLOCKD *const xd = &x->e_mbd;
12462 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12463 MB_MODE_INFO backup_mbmi;
12464 BLOCK_SIZE bsize = mbmi->sb_type;
12465 int ref, skip_blk, backup_skip = x->skip;
12466 int64_t rd_causal;
12467 RD_STATS rd_stats_y, rd_stats_uv;
12468 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12469 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12470
12471 // Recompute the best causal predictor and rd
12472 mbmi->motion_mode = SIMPLE_TRANSLATION;
12473 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12474 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12475 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12476 assert(cfg != NULL);
12477 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12478 &xd->block_refs[ref]->sf);
12479 }
12480 av1_setup_dst_planes(x->e_mbd.plane, get_frame_new_buffer(&cpi->common),
12481 mi_row, mi_col);
12482
12483 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
12484
12485 av1_subtract_plane(x, bsize, 0);
12486 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12487 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12488 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12489 if (rd_stats_y.skip && rd_stats_uv.skip) {
12490 rd_stats_y.rate = rate_skip1;
12491 rd_stats_uv.rate = 0;
12492 rd_stats_y.dist = rd_stats_y.sse;
12493 rd_stats_uv.dist = rd_stats_uv.sse;
12494 skip_blk = 0;
12495 } else if (RDCOST(x->rdmult, x->rddiv,
12496 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12497 (rd_stats_y.dist + rd_stats_uv.dist)) >
12498 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12499 (rd_stats_y.sse + rd_stats_uv.sse))) {
12500 rd_stats_y.rate = rate_skip1;
12501 rd_stats_uv.rate = 0;
12502 rd_stats_y.dist = rd_stats_y.sse;
12503 rd_stats_uv.dist = rd_stats_uv.sse;
12504 skip_blk = 1;
12505 } else {
12506 rd_stats_y.rate += rate_skip0;
12507 skip_blk = 0;
12508 }
12509 backup_skip = skip_blk;
12510 backup_mbmi = *mbmi;
12511 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12512 (rd_stats_y.dist + rd_stats_uv.dist));
12513 rd_causal += RDCOST(x->rdmult, x->rddiv,
12514 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12515
12516 // Check non-causal mode
12517 mbmi->motion_mode = OBMC_CAUSAL;
Sarah Parker19234cc2017-03-10 16:43:25 -080012518 assert_motion_mode_valid(OBMC_CAUSAL,
12519#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
12520 0, cm->global_motion,
12521#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
12522 mi);
Yue Chenf27b1602017-01-13 11:11:43 -080012523 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12524
12525 av1_subtract_plane(x, bsize, 0);
12526 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12527 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12528 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12529 if (rd_stats_y.skip && rd_stats_uv.skip) {
12530 rd_stats_y.rate = rate_skip1;
12531 rd_stats_uv.rate = 0;
12532 rd_stats_y.dist = rd_stats_y.sse;
12533 rd_stats_uv.dist = rd_stats_uv.sse;
12534 skip_blk = 0;
12535 } else if (RDCOST(x->rdmult, x->rddiv,
12536 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12537 (rd_stats_y.dist + rd_stats_uv.dist)) >
12538 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12539 (rd_stats_y.sse + rd_stats_uv.sse))) {
12540 rd_stats_y.rate = rate_skip1;
12541 rd_stats_uv.rate = 0;
12542 rd_stats_y.dist = rd_stats_y.sse;
12543 rd_stats_uv.dist = rd_stats_uv.sse;
12544 skip_blk = 1;
12545 } else {
12546 rd_stats_y.rate += rate_skip0;
12547 skip_blk = 0;
12548 }
12549
12550 if (rd_causal >
12551 RDCOST(x->rdmult, x->rddiv,
12552 rd_stats_y.rate + rd_stats_uv.rate +
12553 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12554 (rd_stats_y.dist + rd_stats_uv.dist))) {
12555 x->skip = skip_blk;
12556 } else {
12557 *mbmi = backup_mbmi;
12558 x->skip = backup_skip;
12559 }
12560}
Fergus Simpson4063a682017-02-28 16:52:22 -080012561#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070012562#endif // CONFIG_MOTION_VAR