blob: a5bc755615e56dfa35260915bf91b1d039c64a05 [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);
Alex Converse76b89632017-03-20 11:47:12 -0700496 (void)qm;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800497#if 1
498 min_var = INT_MAX;
499 mean_var = 0;
500 for (i = 0; i < 3; i++) {
501 for (j = 0; j < 3; j++) {
502 int varx;
503 int vary;
504 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
505 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
506 min_var = OD_MINI(min_var, varx);
507 mean_var += 1. / (1 + varx);
508 /* The cast to (double) is to avoid an overflow before the sqrt.*/
509 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
510 }
511 }
512 /* We use a different variance statistic depending on whether activity
513 masking is used, since the harmonic mean appeared slghtly worse with
514 masking off. The calibration constant just ensures that we preserve the
515 rate compared to activity=1. */
516 if (use_activity_masking) {
517 calibration = 1.95;
518 var_stat = 9. / mean_var;
519 } else {
520 calibration = 1.62;
521 var_stat = min_var;
522 }
523 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
524 activity masking constant. */
525 activity = calibration * pow(.25 + var_stat, -1. / 6);
526#else
527 activity = 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800528#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800529 sum = 0;
530 for (i = 0; i < 8; i++) {
531 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500532 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800533 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500534 /* Normalize the filter to unit DC response. */
535 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
536 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800537 return activity * activity * (sum + vardist);
538}
539
540// Note : Inputs x and y are in a pixel domain
541static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
542 od_coeff *y, int bsize_w, int bsize_h,
543 int qindex) {
544 int i;
545 double sum;
546 sum = 0;
547
Yushin Cho7a428ba2017-01-12 16:28:49 -0800548 assert(bsize_w >= 8 && bsize_h >= 8);
549
550 if (qm == OD_FLAT_QM) {
551 for (i = 0; i < bsize_w * bsize_h; i++) {
552 double tmp;
553 tmp = x[i] - y[i];
554 sum += tmp * tmp;
555 }
556 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500557 int j;
558 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
559 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
560 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
561 int mid = OD_DIST_LP_MID;
562 for (i = 0; i < bsize_h; i++) {
563 for (j = 0; j < bsize_w; j++) {
564 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
565 }
566 }
567 for (i = 0; i < bsize_h; i++) {
568 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
569 tmp[i * bsize_w + bsize_w - 1] =
570 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
571 for (j = 1; j < bsize_w - 1; j++) {
572 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
573 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
574 }
575 }
576 for (j = 0; j < bsize_w; j++) {
577 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
578 e_lp[(bsize_h - 1) * bsize_w + j] =
579 mid * tmp[(bsize_h - 1) * bsize_w + j] +
580 2 * tmp[(bsize_h - 2) * bsize_w + j];
581 }
582 for (i = 1; i < bsize_h - 1; i++) {
583 for (j = 0; j < bsize_w; j++) {
584 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
585 tmp[(i - 1) * bsize_w + j] +
586 tmp[(i + 1) * bsize_w + j];
587 }
588 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800589 for (i = 0; i < bsize_h; i += 8) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800590 for (j = 0; j < bsize_w; j += 8) {
591 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500592 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
593 bsize_w);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800594 }
595 }
David Michael Barrd091b802017-01-21 16:05:46 +0900596 /* Scale according to linear regression against SSE, for 8x8 blocks. */
597 if (activity_masking) {
598 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
599 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
600 } else {
601 sum *= qindex >= 128
602 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
603 : qindex <= 43
604 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
605 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
606 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800607 }
608 return sum;
609}
610
611static int64_t av1_daala_dist(const uint8_t *src, int src_stride,
612 const uint8_t *dst, int dst_stride, int tx_size,
613 int qm, int use_activity_masking, int qindex) {
614 int i, j;
615 int64_t d;
616 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
617 const int bsw = block_size_wide[tx_bsize];
618 const int bsh = block_size_high[tx_bsize];
619 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
620 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
621
622 assert(qm == OD_HVS_QM);
623
624 for (j = 0; j < bsh; j++)
625 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
626
627 for (j = 0; j < bsh; j++)
628 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
629
630 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
631 qindex);
632 return d;
633}
Fergus Simpson4063a682017-02-28 16:52:22 -0800634#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800635
Yaowu Xuf883b422016-08-30 14:01:10 -0700636static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700637 uint8_t *src, int src_stride,
638 uint8_t *dst, int dst_stride,
639 double *hordist, double *verdist) {
Jingning Han73db4ac2016-11-30 11:23:27 -0800640 int bw = block_size_wide[bsize];
641 int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700642 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
643 unsigned int var[16];
644 double total = 0;
645
646 const int f_index = bsize - BLOCK_16X16;
647 if (f_index < 0) {
648 int i, j, index;
649 int w_shift = bw == 8 ? 1 : 2;
650 int h_shift = bh == 8 ? 1 : 2;
Yaowu Xuf883b422016-08-30 14:01:10 -0700651#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700652 if (cpi->common.use_highbitdepth) {
653 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
654 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
655 for (i = 0; i < bh; ++i)
656 for (j = 0; j < bw; ++j) {
657 index = (j >> w_shift) + ((i >> h_shift) << 2);
658 esq[index] +=
659 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
660 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
661 }
662 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700663#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700664
665 for (i = 0; i < bh; ++i)
666 for (j = 0; j < bw; ++j) {
667 index = (j >> w_shift) + ((i >> h_shift) << 2);
668 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
669 (src[j + i * src_stride] - dst[j + i * dst_stride]);
670 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700671#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700673#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 } else {
675 var[0] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
676 var[1] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
677 dst_stride, &esq[1]);
678 var[2] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
679 dst_stride, &esq[2]);
680 var[3] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
681 dst + 3 * bw / 4, dst_stride, &esq[3]);
682 src += bh / 4 * src_stride;
683 dst += bh / 4 * dst_stride;
684
685 var[4] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
686 var[5] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
687 dst_stride, &esq[5]);
688 var[6] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
689 dst_stride, &esq[6]);
690 var[7] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
691 dst + 3 * bw / 4, dst_stride, &esq[7]);
692 src += bh / 4 * src_stride;
693 dst += bh / 4 * dst_stride;
694
695 var[8] = cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
696 var[9] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
697 dst_stride, &esq[9]);
698 var[10] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
699 dst_stride, &esq[10]);
700 var[11] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
701 dst + 3 * bw / 4, dst_stride, &esq[11]);
702 src += bh / 4 * src_stride;
703 dst += bh / 4 * dst_stride;
704
705 var[12] =
706 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
707 var[13] = cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4,
708 dst_stride, &esq[13]);
709 var[14] = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2,
710 dst_stride, &esq[14]);
711 var[15] = cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride,
712 dst + 3 * bw / 4, dst_stride, &esq[15]);
713 }
714
715 total = esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] + esq[6] +
716 esq[7] + esq[8] + esq[9] + esq[10] + esq[11] + esq[12] + esq[13] +
717 esq[14] + esq[15];
718 if (total > 0) {
719 const double e_recip = 1.0 / total;
720 hordist[0] =
721 ((double)esq[0] + (double)esq[4] + (double)esq[8] + (double)esq[12]) *
722 e_recip;
723 hordist[1] =
724 ((double)esq[1] + (double)esq[5] + (double)esq[9] + (double)esq[13]) *
725 e_recip;
726 hordist[2] =
727 ((double)esq[2] + (double)esq[6] + (double)esq[10] + (double)esq[14]) *
728 e_recip;
729 verdist[0] =
730 ((double)esq[0] + (double)esq[1] + (double)esq[2] + (double)esq[3]) *
731 e_recip;
732 verdist[1] =
733 ((double)esq[4] + (double)esq[5] + (double)esq[6] + (double)esq[7]) *
734 e_recip;
735 verdist[2] =
736 ((double)esq[8] + (double)esq[9] + (double)esq[10] + (double)esq[11]) *
737 e_recip;
738 } else {
739 hordist[0] = verdist[0] = 0.25;
740 hordist[1] = verdist[1] = 0.25;
741 hordist[2] = verdist[2] = 0.25;
742 }
743 (void)var[0];
744 (void)var[1];
745 (void)var[2];
746 (void)var[3];
747 (void)var[4];
748 (void)var[5];
749 (void)var[6];
750 (void)var[7];
751 (void)var[8];
752 (void)var[9];
753 (void)var[10];
754 (void)var[11];
755 (void)var[12];
756 (void)var[13];
757 (void)var[14];
758 (void)var[15];
759}
760
Yaowu Xuf883b422016-08-30 14:01:10 -0700761static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize, uint8_t *src,
762 int src_stride, uint8_t *dst, int dst_stride,
763 double *hdist, double *vdist) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700764 int prune_bitmask = 0;
765 double svm_proj_h = 0, svm_proj_v = 0;
766 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
767 hdist, vdist);
768
769 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
770 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
771 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
772 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
773 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
774 prune_bitmask |= 1 << FLIPADST_1D;
775 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
776 prune_bitmask |= 1 << ADST_1D;
777
778 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
779 prune_bitmask |= 1 << (FLIPADST_1D + 8);
780 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
781 prune_bitmask |= 1 << (ADST_1D + 8);
782
783 return prune_bitmask;
784}
785
786#if CONFIG_EXT_TX
787static void get_horver_correlation(int16_t *diff, int stride, int w, int h,
788 double *hcorr, double *vcorr) {
789 // Returns hor/ver correlation coefficient
790 const int num = (h - 1) * (w - 1);
791 double num_r;
792 int i, j;
793 int64_t xy_sum = 0, xz_sum = 0;
794 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
795 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
796 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
797 *hcorr = *vcorr = 1;
798
799 assert(num > 0);
800 num_r = 1.0 / num;
801 for (i = 1; i < h; ++i) {
802 for (j = 1; j < w; ++j) {
803 const int16_t x = diff[i * stride + j];
804 const int16_t y = diff[i * stride + j - 1];
805 const int16_t z = diff[(i - 1) * stride + j];
806 xy_sum += x * y;
807 xz_sum += x * z;
808 x_sum += x;
809 y_sum += y;
810 z_sum += z;
811 x2_sum += x * x;
812 y2_sum += y * y;
813 z2_sum += z * z;
814 }
815 }
816 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
817 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
818 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
819 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
820 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
821 if (x_var_n > 0 && y_var_n > 0) {
822 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
823 *hcorr = *hcorr < 0 ? 0 : *hcorr;
824 }
825 if (x_var_n > 0 && z_var_n > 0) {
826 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
827 *vcorr = *vcorr < 0 ? 0 : *vcorr;
828 }
829}
830
831int dct_vs_idtx(int16_t *diff, int stride, int w, int h, double *hcorr,
832 double *vcorr) {
833 int prune_bitmask = 0;
834 get_horver_correlation(diff, stride, w, h, hcorr, vcorr);
835
836 if (*vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
837 prune_bitmask |= 1 << IDTX_1D;
838 else if (*vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
839 prune_bitmask |= 1 << DCT_1D;
840
841 if (*hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
842 prune_bitmask |= 1 << (IDTX_1D + 8);
843 else if (*hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
844 prune_bitmask |= 1 << (DCT_1D + 8);
845 return prune_bitmask;
846}
847
848// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700849static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 MACROBLOCK *x, MACROBLOCKD *xd, int adst_flipadst,
851 int dct_idtx) {
852 struct macroblock_plane *const p = &x->plane[0];
853 struct macroblockd_plane *const pd = &xd->plane[0];
854 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
855 const int bw = 4 << (b_width_log2_lookup[bs]);
856 const int bh = 4 << (b_height_log2_lookup[bs]);
857 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
858 double hcorr, vcorr;
859 int prune = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700860 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700861
862 if (adst_flipadst)
863 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
864 pd->dst.buf, pd->dst.stride, hdist, vdist);
865 if (dct_idtx) prune |= dct_vs_idtx(p->src_diff, bw, bw, bh, &hcorr, &vcorr);
866
867 return prune;
868}
869#endif // CONFIG_EXT_TX
870
871// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700872static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700873 MACROBLOCK *x, MACROBLOCKD *xd) {
874 struct macroblock_plane *const p = &x->plane[0];
875 struct macroblockd_plane *const pd = &xd->plane[0];
876 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700877 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700878 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
879 pd->dst.stride, hdist, vdist);
880}
881
Yaowu Xuf883b422016-08-30 14:01:10 -0700882static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700883 MACROBLOCKD *xd, int tx_set) {
884#if CONFIG_EXT_TX
885 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
886#else
887 const int tx_set_1D[TX_TYPES_1D] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -0800888#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700889
890 switch (cpi->sf.tx_type_search.prune_mode) {
891 case NO_PRUNE: return 0; break;
892 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700893 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 return 0;
895 return prune_one_for_sby(cpi, bsize, x, xd);
896 break;
897#if CONFIG_EXT_TX
898 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700899 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
901 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
902 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700903 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
905 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
906 break;
Fergus Simpson4063a682017-02-28 16:52:22 -0800907#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908 }
909 assert(0);
910 return 0;
911}
912
913static int do_tx_type_search(TX_TYPE tx_type, int prune) {
914// TODO(sarahparker) implement for non ext tx
915#if CONFIG_EXT_TX
916 return !(((prune >> vtx_tab[tx_type]) & 1) |
917 ((prune >> (htx_tab[tx_type] + 8)) & 1));
918#else
919 // temporary to avoid compiler warnings
920 (void)vtx_tab;
921 (void)htx_tab;
922 (void)tx_type;
923 (void)prune;
924 return 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800925#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700926}
927
Yaowu Xuf883b422016-08-30 14:01:10 -0700928static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700929 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
930 int plane, int64_t sse, int *rate,
931 int64_t *dist) {
932 const struct macroblockd_plane *const pd = &xd->plane[plane];
933 const int dequant_shift =
Yaowu Xuf883b422016-08-30 14:01:10 -0700934#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Yaowu Xuf883b422016-08-30 14:01:10 -0700936#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 3;
938
939 // Fast approximate the modelling function.
940 if (cpi->sf.simple_model_rd_from_var) {
941 const int64_t square_error = sse;
942 int quantizer = (pd->dequant[1] >> dequant_shift);
943
944 if (quantizer < 120)
945 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700946 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947 else
948 *rate = 0;
949 *dist = (square_error * quantizer) >> 8;
950 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700951 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
952 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 }
954
955 *dist <<= 4;
956}
957
Yaowu Xuf883b422016-08-30 14:01:10 -0700958static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700959 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
960 int plane_to, int *out_rate_sum,
961 int64_t *out_dist_sum, int *skip_txfm_sb,
962 int64_t *skip_sse_sb) {
963 // Note our transform coeffs are 8 times an orthogonal transform.
964 // Hence quantizer step is also 8 times. To get effective quantizer
965 // we need to divide by 8 before sending to modeling function.
966 int plane;
967 const int ref = xd->mi[0]->mbmi.ref_frame[0];
968
969 int64_t rate_sum = 0;
970 int64_t dist_sum = 0;
971 int64_t total_sse = 0;
972
973 x->pred_sse[ref] = 0;
974
975 for (plane = plane_from; plane <= plane_to; ++plane) {
976 struct macroblock_plane *const p = &x->plane[plane];
977 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han31b6a4f2017-02-23 11:05:53 -0800978#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -0800979 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
980#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700981 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Fergus Simpson4063a682017-02-28 16:52:22 -0800982#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700983
984 unsigned int sse;
985 int rate;
986 int64_t dist;
987
Jingning Han9ce464c2017-02-20 15:36:30 -0800988#if CONFIG_CB4X4
989 if (x->skip_chroma_rd && plane) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -0800990#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -0800991
Yaowu Xuc27fc142016-08-22 16:08:15 -0700992 // TODO(geza): Write direct sse functions that do not compute
993 // variance as well.
994 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
995 &sse);
996
997 if (plane == 0) x->pred_sse[ref] = sse;
998
999 total_sse += sse;
1000
1001 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
1002
1003 rate_sum += rate;
1004 dist_sum += dist;
1005 }
1006
1007 *skip_txfm_sb = total_sse == 0;
1008 *skip_sse_sb = total_sse << 4;
1009 *out_rate_sum = (int)rate_sum;
1010 *out_dist_sum = dist_sum;
1011}
1012
Yaowu Xuf883b422016-08-30 14:01:10 -07001013int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
1014 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 int i;
1016 int64_t error = 0, sqcoeff = 0;
1017
1018 for (i = 0; i < block_size; i++) {
1019 const int diff = coeff[i] - dqcoeff[i];
1020 error += diff * diff;
1021 sqcoeff += coeff[i] * coeff[i];
1022 }
1023
1024 *ssz = sqcoeff;
1025 return error;
1026}
1027
Yaowu Xuf883b422016-08-30 14:01:10 -07001028int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
1029 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001030 int i;
1031 int64_t error = 0;
1032
1033 for (i = 0; i < block_size; i++) {
1034 const int diff = coeff[i] - dqcoeff[i];
1035 error += diff * diff;
1036 }
1037
1038 return error;
1039}
1040
Yaowu Xuf883b422016-08-30 14:01:10 -07001041#if CONFIG_AOM_HIGHBITDEPTH
1042int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
1043 const tran_low_t *dqcoeff, intptr_t block_size,
1044 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001045 int i;
1046 int64_t error = 0, sqcoeff = 0;
1047 int shift = 2 * (bd - 8);
1048 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1049
1050 for (i = 0; i < block_size; i++) {
1051 const int64_t diff = coeff[i] - dqcoeff[i];
1052 error += diff * diff;
1053 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
1054 }
1055 assert(error >= 0 && sqcoeff >= 0);
1056 error = (error + rounding) >> shift;
1057 sqcoeff = (sqcoeff + rounding) >> shift;
1058
1059 *ssz = sqcoeff;
1060 return error;
1061}
Yaowu Xuf883b422016-08-30 14:01:10 -07001062#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001063
Thomas Daede6ff6af62017-02-03 16:29:24 -08001064#if CONFIG_PVQ
1065// Without PVQ, av1_block_error_c() return two kind of errors,
1066// 1) reconstruction (i.e. decoded) error and
1067// 2) Squared sum of transformed residue (i.e. 'coeff')
1068// However, if PVQ is enabled, coeff does not keep the transformed residue
1069// but instead a transformed original is kept.
1070// Hence, new parameter ref vector (i.e. transformed predicted signal)
1071// is required to derive the residue signal,
1072// i.e. coeff - ref = residue (all transformed).
1073
1074#if CONFIG_AOM_HIGHBITDEPTH
1075static int64_t av1_highbd_block_error2_c(const tran_low_t *coeff,
1076 const tran_low_t *dqcoeff,
1077 const tran_low_t *ref,
1078 intptr_t block_size, int64_t *ssz,
1079 int bd) {
1080 int64_t error;
1081 int64_t sqcoeff;
1082 int shift = 2 * (bd - 8);
1083 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1084 // Use the existing sse codes for calculating distortion of decoded signal:
1085 // i.e. (orig - decoded)^2
1086 // For high bit depth, throw away ssz until a 32-bit version of
1087 // av1_block_error_fp is written.
1088 int64_t ssz_trash;
1089 error = av1_block_error(coeff, dqcoeff, block_size, &ssz_trash);
1090 // prediction residue^2 = (orig - ref)^2
1091 sqcoeff = av1_block_error(coeff, ref, block_size, &ssz_trash);
1092 error = (error + rounding) >> shift;
1093 sqcoeff = (sqcoeff + rounding) >> shift;
1094 *ssz = sqcoeff;
1095 return error;
1096}
1097#else
1098// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1099// a separate function that does not do the extra computations for ssz.
1100static int64_t av1_block_error2_c(const tran_low_t *coeff,
1101 const tran_low_t *dqcoeff,
1102 const tran_low_t *ref, intptr_t block_size,
1103 int64_t *ssz) {
1104 int64_t error;
1105 // Use the existing sse codes for calculating distortion of decoded signal:
1106 // i.e. (orig - decoded)^2
1107 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1108 // prediction residue^2 = (orig - ref)^2
1109 *ssz = av1_block_error_fp(coeff, ref, block_size);
1110 return error;
1111}
1112#endif // CONFIG_AOM_HIGHBITDEPTH
1113#endif // CONFIG_PVQ
1114
Jingning Hanab77e732017-02-28 15:20:59 -08001115#if !CONFIG_PVQ || CONFIG_VAR_TX
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001116/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001117 * decide whether to include cost of a trailing EOB node or not (i.e. we
1118 * can skip this if the last coefficient in this transform block, e.g. the
1119 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1120 * were non-zero). */
Angie Chiang22ba7512016-10-20 17:10:33 -07001121int av1_cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1122 int block, int coeff_ctx, TX_SIZE tx_size,
1123 const int16_t *scan, const int16_t *nb,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001124 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125 MACROBLOCKD *const xd = &x->e_mbd;
1126 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1127 const struct macroblock_plane *p = &x->plane[plane];
1128 const struct macroblockd_plane *pd = &xd->plane[plane];
1129 const PLANE_TYPE type = pd->plane_type;
1130 const uint16_t *band_count = &band_count_table[tx_size][1];
1131 const int eob = p->eobs[block];
1132 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1133 const int tx_size_ctx = txsize_sqr_map[tx_size];
1134 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1135 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1136 uint8_t token_cache[MAX_TX_SQUARE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001137 int pt = coeff_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138 int c, cost;
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001139#if CONFIG_NEW_TOKENSET
1140 const int ref = is_inter_block(mbmi);
1141 aom_prob *blockz_probs =
1142 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
Thomas Davies10525752017-03-06 12:10:46 +00001143
Fergus Simpson4063a682017-02-28 16:52:22 -08001144#endif // CONFIG_NEW_TOKENSET
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001145
Yaowu Xuf883b422016-08-30 14:01:10 -07001146#if CONFIG_AOM_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001147 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001149 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Fergus Simpson4063a682017-02-28 16:52:22 -08001150#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001151
1152#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1153 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001154 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001155#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001156 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001157
1158 if (eob == 0) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001159#if CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001161 cost = av1_cost_bit(blockz_probs[pt], 0);
1162#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001163 cost = token_costs[0][0][pt][EOB_TOKEN];
Fergus Simpson4063a682017-02-28 16:52:22 -08001164#endif // CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001165 } else {
1166 if (use_fast_coef_costing) {
1167 int band_left = *band_count++;
1168
1169 // dc token
1170 int v = qcoeff[0];
1171 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001172 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001173#if CONFIG_NEW_TOKENSET
1174 cost += (*token_costs)[!prev_t][pt][prev_t];
1175#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001176 cost += (*token_costs)[0][pt][prev_t];
Thomas Davies10525752017-03-06 12:10:46 +00001177#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001178
Yaowu Xuf883b422016-08-30 14:01:10 -07001179 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 ++token_costs;
1181
1182 // ac tokens
1183 for (c = 1; c < eob; c++) {
1184 const int rc = scan[c];
1185 int16_t t;
1186
1187 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001188 cost += av1_get_token_cost(v, &t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001189#if CONFIG_NEW_TOKENSET
1190 cost += (*token_costs)[!t][!prev_t][t];
1191#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001192 cost += (*token_costs)[!prev_t][!prev_t][t];
Thomas Davies10525752017-03-06 12:10:46 +00001193#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001194 prev_t = t;
1195 if (!--band_left) {
1196 band_left = *band_count++;
1197 ++token_costs;
1198 }
1199 }
1200
1201 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001202 if (band_left || CONFIG_NEW_TOKENSET)
1203 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001204
1205 } else { // !use_fast_coef_costing
1206 int band_left = *band_count++;
1207
1208 // dc token
1209 int v = qcoeff[0];
1210 int16_t tok;
Thomas Davies10525752017-03-06 12:10:46 +00001211#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001212 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Thomas Davies10525752017-03-06 12:10:46 +00001213#endif
Alex Converseda3d94f2017-03-15 14:54:29 -07001214 cost = av1_get_token_cost(v, &tok, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001215#if CONFIG_NEW_TOKENSET
1216 cost += (*token_costs)[!tok][pt][tok];
1217#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001218 cost += (*token_costs)[0][pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001219#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220
Yaowu Xuf883b422016-08-30 14:01:10 -07001221 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222 ++token_costs;
1223
Thomas Davies10525752017-03-06 12:10:46 +00001224#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001225 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001226#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001227
1228 // ac tokens
1229 for (c = 1; c < eob; c++) {
1230 const int rc = scan[c];
1231
1232 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001233 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234 pt = get_coef_context(nb, token_cache, c);
Thomas Davies10525752017-03-06 12:10:46 +00001235#if CONFIG_NEW_TOKENSET
1236 cost += (*token_costs)[!tok][pt][tok];
1237#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238 cost += (*tok_cost_ptr)[pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001239#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001240 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001241 if (!--band_left) {
1242 band_left = *band_count++;
1243 ++token_costs;
1244 }
Thomas Davies10525752017-03-06 12:10:46 +00001245#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001246 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001247#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248 }
1249
1250 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001251 if (band_left || CONFIG_NEW_TOKENSET) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252 pt = get_coef_context(nb, token_cache, c);
1253 cost += (*token_costs)[0][pt][EOB_TOKEN];
1254 }
1255 }
1256 }
1257
Yaowu Xuc27fc142016-08-22 16:08:15 -07001258 return cost;
1259}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001260#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001261
Yaowu Xuf883b422016-08-30 14:01:10 -07001262static void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, int block,
1263 int blk_row, int blk_col, TX_SIZE tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 int64_t *out_dist, int64_t *out_sse) {
1265 MACROBLOCKD *const xd = &x->e_mbd;
1266 const struct macroblock_plane *const p = &x->plane[plane];
1267 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001268#if CONFIG_DAALA_DIST
1269 int qm = OD_HVS_QM;
1270 int use_activity_masking = 0;
1271#if CONFIG_PVQ
1272 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001273#endif // CONFIG_PVQ
1274#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001275
1276 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277 // Transform domain distortion computation is more accurate as it does
1278 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001279 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001280 int64_t this_sse;
Debargha Mukherjee0e119122016-11-04 12:10:23 -07001281 int shift = (MAX_TX_SCALE - get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1283 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001284#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001285 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001286
Yaowu Xuf883b422016-08-30 14:01:10 -07001287#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001289 *out_dist = av1_highbd_block_error2_c(coeff, dqcoeff, ref_coeff,
1290 buffer_length, &this_sse, bd) >>
1291 shift;
1292#else
1293 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1294 &this_sse) >>
1295 shift;
1296#endif // CONFIG_AOM_HIGHBITDEPTH
1297#elif CONFIG_AOM_HIGHBITDEPTH
1298 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001299 *out_dist =
1300 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1301 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001302#else
1303 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001304 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001305#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 *out_sse = this_sse >> shift;
1307 } else {
1308 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Jingning Hanb9c57272016-10-25 10:15:39 -07001309 const int bsw = block_size_wide[tx_bsize];
1310 const int bsh = block_size_high[tx_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001311 const int src_stride = x->plane[plane].src.stride;
1312 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001313 // Scale the transform block index to pixel unit.
1314 const int src_idx = (blk_row * src_stride + blk_col)
1315 << tx_size_wide_log2[0];
1316 const int dst_idx = (blk_row * dst_stride + blk_col)
1317 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001318 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1319 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1320 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1321 const uint16_t eob = p->eobs[block];
1322
1323 unsigned int tmp;
1324
1325 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001326 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001327
Yushin Cho7a428ba2017-01-12 16:28:49 -08001328#if CONFIG_DAALA_DIST
1329 if (plane == 0) {
1330 if (bsw >= 8 && bsh >= 8)
1331 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1332 use_activity_masking, x->qindex);
1333 else
1334 tmp = 0;
1335 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001336#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001337 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
1338
Yaowu Xuc27fc142016-08-22 16:08:15 -07001339 *out_sse = (int64_t)tmp * 16;
1340
1341 if (eob) {
1342 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuf883b422016-08-30 14:01:10 -07001343#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001344 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
1345 uint8_t *recon = (uint8_t *)recon16;
1346#else
1347 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07001348#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001349
Luc Trudeau005feb62017-02-22 13:34:01 -05001350 const PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001351
1352 INV_TXFM_PARAM inv_txfm_param;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001353 const int block_raster_idx =
1354 av1_block_index_to_raster_order(tx_size, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001355
Urvang Joshifeb925f2016-12-05 10:37:29 -08001356 inv_txfm_param.tx_type =
1357 get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001358 inv_txfm_param.tx_size = tx_size;
1359 inv_txfm_param.eob = eob;
1360 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1361
Yaowu Xuf883b422016-08-30 14:01:10 -07001362#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1364 recon = CONVERT_TO_BYTEPTR(recon);
1365 inv_txfm_param.bd = xd->bd;
Yaowu Xuf883b422016-08-30 14:01:10 -07001366 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367 NULL, 0, bsw, bsh, xd->bd);
hui subb9c73b2017-03-17 15:51:02 -07001368 av1_highbd_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001369 } else
Yaowu Xuf883b422016-08-30 14:01:10 -07001370#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001371 {
Yushin Cho721868c2016-11-14 16:04:33 +09001372#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -07001373 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001374 bsw, bsh);
Yushin Cho721868c2016-11-14 16:04:33 +09001375#else
1376 int i, j;
1377
1378 for (j = 0; j < bsh; j++)
1379 for (i = 0; i < bsw; i++) recon[j * MAX_TX_SIZE + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08001380#endif // !CONFIG_PVQ
hui subb9c73b2017-03-17 15:51:02 -07001381 av1_inv_txfm_add(dqcoeff, recon, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001382 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001383#if CONFIG_DAALA_DIST
1384 if (plane == 0) {
1385 if (bsw >= 8 && bsh >= 8)
1386 tmp = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, tx_size, qm,
1387 use_activity_masking, x->qindex);
1388 else
1389 tmp = 0;
1390 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001391#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001392 cpi->fn_ptr[tx_bsize].vf(src, src_stride, recon, MAX_TX_SIZE, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001393 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001394 *out_dist = (int64_t)tmp * 16;
1395 }
1396}
1397
Yushin Cho77bba8d2016-11-04 16:36:56 -07001398#if !CONFIG_PVQ
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07001399static int rate_block(int plane, int block, int coeff_ctx, TX_SIZE tx_size,
Debargha Mukherjee29630542016-09-06 13:15:31 -07001400 struct rdcost_block_args *args) {
Angie Chiang22ba7512016-10-20 17:10:33 -07001401 return av1_cost_coeffs(&args->cpi->common, args->x, plane, block, coeff_ctx,
1402 tx_size, args->scan_order->scan,
1403 args->scan_order->neighbors,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001404 args->use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405}
Fergus Simpson4063a682017-02-28 16:52:22 -08001406#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001407
1408static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
1409 TX_SIZE tx_size) {
1410 uint64_t sse;
1411 switch (tx_size) {
Jingning Han2194eec2016-12-01 15:20:16 -08001412#if CONFIG_CB4X4
1413 case TX_2X2:
1414 sse = aom_sum_squares_2d_i16_c(diff, diff_stride, tx_size_wide[tx_size]);
1415 break;
Fergus Simpson4063a682017-02-28 16:52:22 -08001416#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001417 case TX_4X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001418 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1419 aom_sum_squares_2d_i16(diff + 4 * diff_stride, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 break;
1421 case TX_8X4:
Yaowu Xuf883b422016-08-30 14:01:10 -07001422 sse = aom_sum_squares_2d_i16(diff, diff_stride, 4) +
1423 aom_sum_squares_2d_i16(diff + 4, diff_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001424 break;
1425 case TX_8X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001426 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1427 aom_sum_squares_2d_i16(diff + 8 * diff_stride, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001428 break;
1429 case TX_16X8:
Yaowu Xuf883b422016-08-30 14:01:10 -07001430 sse = aom_sum_squares_2d_i16(diff, diff_stride, 8) +
1431 aom_sum_squares_2d_i16(diff + 8, diff_stride, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432 break;
1433 case TX_16X32:
Yaowu Xuf883b422016-08-30 14:01:10 -07001434 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1435 aom_sum_squares_2d_i16(diff + 16 * diff_stride, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436 break;
1437 case TX_32X16:
Yaowu Xuf883b422016-08-30 14:01:10 -07001438 sse = aom_sum_squares_2d_i16(diff, diff_stride, 16) +
1439 aom_sum_squares_2d_i16(diff + 16, diff_stride, 16);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001440 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001441 default:
1442 assert(tx_size < TX_SIZES);
Jingning Hanc598cf82016-10-25 10:37:34 -07001443 sse = aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001444 break;
1445 }
1446 return sse;
1447}
1448
1449static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1450 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1451 struct rdcost_block_args *args = arg;
1452 MACROBLOCK *const x = args->x;
1453 MACROBLOCKD *const xd = &x->e_mbd;
1454 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001455 const AV1_COMMON *cm = &args->cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456 int64_t rd1, rd2, rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001457 int coeff_ctx = combine_entropy_contexts(*(args->t_above + blk_col),
1458 *(args->t_left + blk_row));
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001459 RD_STATS this_rd_stats;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001460#if CONFIG_DAALA_DIST
1461 int qm = OD_HVS_QM;
1462 int use_activity_masking = 0;
1463#if CONFIG_PVQ
1464 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001465#endif // CONFIG_PVQ
1466#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001467
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001468 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001469
1470 if (args->exit_early) return;
1471
1472 if (!is_inter_block(mbmi)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07001473 struct encode_b_args b_args = {
Angie Chiangff6d8902016-10-21 11:02:09 -07001474 (AV1_COMMON *)cm, x, NULL, &mbmi->skip, args->t_above, args->t_left, 1
Yaowu Xuc27fc142016-08-22 16:08:15 -07001475 };
Yaowu Xuf883b422016-08-30 14:01:10 -07001476 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
Urvang Joshi454280d2016-10-14 16:51:44 -07001477 &b_args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001478 if (args->cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001479 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1480 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001481 } else {
1482 // Note that the encode block_intra call above already calls
hui subb9c73b2017-03-17 15:51:02 -07001483 // av1_inv_txfm_add, so we can't just call dist_block here.
Yaowu Xuc27fc142016-08-22 16:08:15 -07001484 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -07001485 const aom_variance_fn_t variance = args->cpi->fn_ptr[tx_bsize].vf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001486 const struct macroblock_plane *const p = &x->plane[plane];
1487 const struct macroblockd_plane *const pd = &xd->plane[plane];
1488
1489 const int src_stride = p->src.stride;
1490 const int dst_stride = pd->dst.stride;
Jingning Hanc598cf82016-10-25 10:37:34 -07001491 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001492
Jingning Han81492262016-12-05 15:48:47 -08001493 const uint8_t *src =
1494 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1495 const uint8_t *dst =
1496 &pd->dst
1497 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1498 const int16_t *diff = &p->src_diff[(blk_row * diff_stride + blk_col)
1499 << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001500 unsigned int tmp;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001501
1502#if CONFIG_DAALA_DIST
1503 if (plane == 0) {
1504 const int bsw = block_size_wide[tx_bsize];
1505 const int bsh = block_size_high[tx_bsize];
1506
1507 if (bsw >= 8 && bsh >= 8) {
1508 const int16_t *pred = &pd->pred[(blk_row * diff_stride + blk_col)
1509 << tx_size_wide_log2[0]];
1510 int i, j;
1511 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1512
1513 for (j = 0; j < bsh; j++)
1514 for (i = 0; i < bsw; i++)
1515 pred8[j * bsw + i] = pred[j * diff_stride + i];
1516
1517 this_rd_stats.sse =
1518 av1_daala_dist(src, src_stride, pred8, bsw, tx_size, qm,
1519 use_activity_masking, x->qindex);
1520 } else {
1521 this_rd_stats.sse = 0;
1522 }
1523 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001524#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001525 {
1526 this_rd_stats.sse = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001527
Yaowu Xuf883b422016-08-30 14:01:10 -07001528#if CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001529 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1530 this_rd_stats.sse =
1531 ROUND_POWER_OF_TWO(this_rd_stats.sse, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07001532#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001533 }
1534
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001535 this_rd_stats.sse = this_rd_stats.sse * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001536
Yushin Cho7a428ba2017-01-12 16:28:49 -08001537#if CONFIG_DAALA_DIST
1538 if (plane == 0) {
1539 const int bsw = block_size_wide[tx_bsize];
1540 const int bsh = block_size_high[tx_bsize];
1541
1542 if (bsw >= 8 && bsh >= 8)
1543 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1544 use_activity_masking, x->qindex);
1545 else
1546 tmp = 0;
1547 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001548#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001549 variance(src, src_stride, dst, dst_stride, &tmp);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001550 this_rd_stats.dist = (int64_t)tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001551 }
1552 } else {
1553// full forward transform and quantization
1554#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001555 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1556 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001557#else
Angie Chiangff6d8902016-10-21 11:02:09 -07001558 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001559 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001560#endif // CONFIG_NEW_QUANT
Yushin Cho721868c2016-11-14 16:04:33 +09001561#if !CONFIG_PVQ
Yaowu Xufd873802016-12-12 09:37:54 -08001562 if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id]) {
1563 args->t_above[blk_col] = args->t_left[blk_row] =
1564 (av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx) > 0);
1565 } else {
1566 args->t_above[blk_col] = (x->plane[plane].eobs[block] > 0);
1567 args->t_left[blk_row] = (x->plane[plane].eobs[block] > 0);
1568 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001569#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001570 dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size,
1571 &this_rd_stats.dist, &this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001572 }
1573
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001574 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001575 if (args->this_rd + rd > args->best_rd) {
1576 args->exit_early = 1;
1577 return;
1578 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001579#if !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001580 this_rd_stats.rate = rate_block(plane, block, coeff_ctx, tx_size, args);
Angie Chiang3963d632016-11-10 18:41:40 -08001581#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001582 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1583 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001584#endif // CONFIG_RD_DEBUG
Angie Chiang3963d632016-11-10 18:41:40 -08001585
Yushin Cho77bba8d2016-11-04 16:36:56 -07001586#else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001587 this_rd_stats.rate = x->rate;
Yushin Cho721868c2016-11-14 16:04:33 +09001588 args->t_above[blk_col] = !x->pvq_skip[plane];
1589 args->t_left[blk_row] = !x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001590#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001591 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1592 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001593
1594 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001595 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001596
Yushin Cho7a428ba2017-01-12 16:28:49 -08001597#if CONFIG_DAALA_DIST
1598 if (plane == 0 && tx_size <= TX_4X4) {
1599 rd = 0;
1600 x->rate_4x4[block] = this_rd_stats.rate;
1601 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001602#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001603
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001604#if !CONFIG_PVQ
1605 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1606#else
1607 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001608#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001609 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001610
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611 args->this_rd += rd;
1612
1613 if (args->this_rd > args->best_rd) {
1614 args->exit_early = 1;
1615 return;
1616 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001617}
1618
Yushin Cho7a428ba2017-01-12 16:28:49 -08001619#if CONFIG_DAALA_DIST
1620static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
1621 int blk_col, BLOCK_SIZE plane_bsize,
1622 TX_SIZE tx_size, void *arg) {
1623 struct rdcost_block_args *args = arg;
1624 MACROBLOCK *const x = args->x;
1625 MACROBLOCKD *const xd = &x->e_mbd;
1626 // MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1627 // const AV1_COMMON *cm = &args->cpi->common;
1628 int64_t rd1, rd2, rd;
1629 RD_STATS this_rd_stats;
1630 int qm = OD_HVS_QM;
1631 int use_activity_masking = 0;
1632
1633#if CONFIG_PVQ
1634 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001635#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08001636 av1_init_rd_stats(&this_rd_stats);
1637
1638 if (args->exit_early) return;
1639
1640 {
1641 const struct macroblock_plane *const p = &x->plane[plane];
1642 const struct macroblockd_plane *const pd = &xd->plane[plane];
1643
1644 const int src_stride = p->src.stride;
1645 const int dst_stride = pd->dst.stride;
1646 const int diff_stride = block_size_wide[plane_bsize];
1647
1648 const uint8_t *src =
1649 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1650 const uint8_t *dst =
1651 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1652
1653 unsigned int tmp;
1654
1655 int qindex = x->qindex;
1656
1657 const int16_t *pred =
1658 &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
1659 int i, j;
1660 const int tx_blk_size = 1 << (tx_size + 2);
1661 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1662
1663 for (j = 0; j < tx_blk_size; j++)
1664 for (i = 0; i < tx_blk_size; i++)
1665 pred8[j * tx_blk_size + i] = pred[j * diff_stride + i];
1666
1667 this_rd_stats.sse =
1668 av1_daala_dist(src, src_stride, pred8, tx_blk_size, tx_size, qm,
1669 use_activity_masking, qindex);
1670
1671 this_rd_stats.sse = this_rd_stats.sse * 16;
1672
1673 tmp = av1_daala_dist(src, src_stride, dst, dst_stride, tx_size, qm,
1674 use_activity_masking, qindex);
1675
1676 this_rd_stats.dist = (int64_t)tmp * 16;
1677 }
1678
1679 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
1680 if (args->this_rd + rd > args->best_rd) {
1681 args->exit_early = 1;
1682 return;
1683 }
1684
1685 {
1686 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
1687 // The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
1688 this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
1689 x->rate_4x4[block - max_blocks_wide] +
1690 x->rate_4x4[block - 1] + x->rate_4x4[block];
1691 }
1692 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1693 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
1694
1695 rd = AOMMIN(rd1, rd2);
1696
1697 args->rd_stats.dist += this_rd_stats.dist;
1698 args->rd_stats.sse += this_rd_stats.sse;
1699
1700 args->this_rd += rd;
1701
1702 if (args->this_rd > args->best_rd) {
1703 args->exit_early = 1;
1704 return;
1705 }
1706}
Fergus Simpson4063a682017-02-28 16:52:22 -08001707#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001708
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001709static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1710 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1711 BLOCK_SIZE bsize, TX_SIZE tx_size,
1712 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001713 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001714 MACROBLOCKD *const xd = &x->e_mbd;
1715 const struct macroblockd_plane *const pd = &xd->plane[plane];
1716 TX_TYPE tx_type;
1717 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001718 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001719 args.x = x;
1720 args.cpi = cpi;
1721 args.best_rd = ref_best_rd;
1722 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001723 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001724
1725 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1726
Yaowu Xuf883b422016-08-30 14:01:10 -07001727 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001728
1729 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001730 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001731 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732
Yushin Cho7a428ba2017-01-12 16:28:49 -08001733#if CONFIG_DAALA_DIST
1734 if (plane == 0 &&
1735 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
1736 av1_foreach_8x8_transformed_block_in_plane(
1737 xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
1738 else
Fergus Simpson4063a682017-02-28 16:52:22 -08001739#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001740 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1741 &args);
1742
Yaowu Xuc27fc142016-08-22 16:08:15 -07001743 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001744 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001746 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001747 }
1748}
1749
1750#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001751void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1752 int64_t *distortion, int *skippable,
1753 int64_t *sse, int64_t ref_best_rd, int plane,
1754 BLOCK_SIZE bsize, TX_SIZE tx_size,
1755 int use_fast_coef_casting) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001756 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001757 MACROBLOCKD *const xd = &x->e_mbd;
1758 const struct macroblockd_plane *const pd = &xd->plane[plane];
1759 struct rdcost_block_args args;
1760 TX_TYPE tx_type;
1761
Yaowu Xuf883b422016-08-30 14:01:10 -07001762 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001763 args.cpi = cpi;
1764 args.x = x;
1765 args.best_rd = ref_best_rd;
1766 args.use_fast_coef_costing = use_fast_coef_casting;
1767
1768#if CONFIG_EXT_TX
1769 assert(tx_size < TX_SIZES);
1770#endif // CONFIG_EXT_TX
1771
1772 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1773
Yaowu Xuf883b422016-08-30 14:01:10 -07001774 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775
1776 tx_type = get_tx_type(pd->plane_type, xd, 0, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07001777 args.scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07001778 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001779
1780 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1781 &args);
1782
1783 if (args.exit_early) {
1784 *rate = INT_MAX;
1785 *distortion = INT64_MAX;
1786 *sse = INT64_MAX;
1787 *skippable = 0;
1788 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001789 *distortion = args.rd_stats.dist;
1790 *rate = args.rd_stats.rate;
1791 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792 *skippable = !x->plane[plane].eobs[0];
1793 }
1794}
1795#endif // CONFIG_SUPERTX
1796
Urvang Joshifeb925f2016-12-05 10:37:29 -08001797static int tx_size_cost(const AV1_COMP *const cpi, MACROBLOCK *x,
1798 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1799 const AV1_COMMON *const cm = &cpi->common;
1800 MACROBLOCKD *const xd = &x->e_mbd;
1801 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1802
1803 const int tx_select =
1804 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1805
1806 if (tx_select) {
1807 const int is_inter = is_inter_block(mbmi);
1808 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1809 : intra_tx_size_cat_lookup[bsize];
1810 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1811 const int depth = tx_size_to_depth(coded_tx_size);
1812 const int tx_size_ctx = get_tx_size_context(xd);
1813 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1814 return r_tx_size;
1815 } else {
1816 return 0;
1817 }
1818}
1819
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001820static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1821 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1822 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001823 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001824 MACROBLOCKD *const xd = &x->e_mbd;
1825 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1826 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001827 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 int s0, s1;
1829 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001830 const int tx_select =
1831 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001832
1833 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001834
1835 assert(skip_prob > 0);
1836#if CONFIG_EXT_TX && CONFIG_RECT_TX
1837 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1838#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1839
Yaowu Xuf883b422016-08-30 14:01:10 -07001840 s0 = av1_cost_bit(skip_prob, 0);
1841 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842
1843 mbmi->tx_type = tx_type;
1844 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001845 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001846 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001847 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001849 if (get_ext_tx_types(tx_size, bs, is_inter, cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001850 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08001851 const int ext_tx_set =
1852 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001853 if (is_inter) {
1854 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001855 rd_stats->rate +=
clang-format67948d32016-09-07 22:40:40 -07001856 cpi->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1857 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858 } else {
1859 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Urvang Joshifeb925f2016-12-05 10:37:29 -08001860 rd_stats->rate +=
1861 cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[mbmi->tx_size]]
1862 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001863 }
1864 }
1865#else
1866 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1867 !FIXED_TX_TYPE) {
1868 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001869 rd_stats->rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001871 rd_stats->rate +=
1872 cpi->intra_tx_type_costs[mbmi->tx_size]
1873 [intra_mode_to_tx_type_context[mbmi->mode]]
1874 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 }
1876 }
1877#endif // CONFIG_EXT_TX
1878
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001879 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001881 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001882 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001883 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1884 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001885 }
1886 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001887 rd = RDCOST(x->rdmult, x->rddiv,
1888 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889 }
1890
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001891 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001892
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001893 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1894 !(rd_stats->skip))
1895 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001896
1897 return rd;
1898}
1899
Urvang Joshi52648442016-10-13 17:27:51 -07001900static int64_t choose_tx_size_fix_type(const AV1_COMP *const cpi, BLOCK_SIZE bs,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001901 MACROBLOCK *x, RD_STATS *rd_stats,
1902 int64_t ref_best_rd, TX_TYPE tx_type,
Yushin Cho55711e62016-11-10 18:49:24 -08001903#if CONFIG_PVQ
1904 od_rollback_buffer buf,
Fergus Simpson4063a682017-02-28 16:52:22 -08001905#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001906 int prune) {
Urvang Joshi52648442016-10-13 17:27:51 -07001907 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001908 MACROBLOCKD *const xd = &x->e_mbd;
1909 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 int64_t rd = INT64_MAX;
1911 int n;
1912 int start_tx, end_tx;
1913 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
1914 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1915 TX_SIZE best_tx_size = max_tx_size;
1916 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
1917 const int is_inter = is_inter_block(mbmi);
1918#if CONFIG_EXT_TX
1919#if CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001920 int evaluate_rect_tx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921#endif // CONFIG_RECT_TX
1922 int ext_tx_set;
1923#endif // CONFIG_EXT_TX
1924
1925 if (tx_select) {
1926#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001927 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001928#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1929 start_tx = max_tx_size;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001930 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001931 } else {
1932 const TX_SIZE chosen_tx_size =
1933 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
1934#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001935 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
1936 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1938 start_tx = chosen_tx_size;
1939 end_tx = chosen_tx_size;
1940 }
1941
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001942 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001943
1944 mbmi->tx_type = tx_type;
1945
1946#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07001947 if (evaluate_rect_tx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001948 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001949 RD_STATS this_rd_stats;
Sarah Parkere68a3e42017-02-16 14:03:24 -08001950 ext_tx_set =
1951 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08001952 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
1953 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001954 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001955 rect_tx_size);
1956 best_tx_size = rect_tx_size;
1957 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001958 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001959 }
1960 }
1961#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1962
1963 last_rd = INT64_MAX;
1964 for (n = start_tx; n >= end_tx; --n) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001965 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001966#if CONFIG_EXT_TX && CONFIG_RECT_TX
1967 if (is_rect_tx(n)) break;
1968#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1969 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, n)) continue;
1970 if (!is_inter && x->use_default_intra_tx_type &&
1971 tx_type != get_default_tx_type(0, xd, 0, n))
1972 continue;
1973 if (is_inter && x->use_default_inter_tx_type &&
1974 tx_type != get_default_tx_type(0, xd, 0, n))
1975 continue;
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08001976 if (max_tx_size >= TX_32X32 && n == TX_4X4) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001978 ext_tx_set = get_ext_tx_set(n, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001979 if (is_inter) {
1980 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1981 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1982 if (!do_tx_type_search(tx_type, prune)) continue;
1983 }
1984 } else {
1985 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1986 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1987 }
1988 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1989 }
1990#else // CONFIG_EXT_TX
1991 if (n >= TX_32X32 && tx_type != DCT_DCT) continue;
1992 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1993 !do_tx_type_search(tx_type, prune))
1994 continue;
1995#endif // CONFIG_EXT_TX
1996
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001997 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
Yushin Cho55711e62016-11-10 18:49:24 -08001998#if CONFIG_PVQ
1999 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002000#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001 // Early termination in transform size search.
2002 if (cpi->sf.tx_size_search_breakout &&
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002003 (rd == INT64_MAX ||
2004 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07002005 (n < (int)max_tx_size && rd > last_rd)))
2006 break;
2007
2008 last_rd = rd;
2009 if (rd < best_rd) {
2010 best_tx_size = n;
2011 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002012 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002013 }
2014 }
2015 mbmi->tx_size = best_tx_size;
2016
2017 return best_rd;
2018}
2019
2020#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07002021static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
2022 MACROBLOCK *x, int *r, int64_t *d, int *s,
2023 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002024 RD_STATS rd_stats;
2025 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
2026 max_txsize_lookup[bs]);
2027 *r = rd_stats.rate;
2028 *d = rd_stats.dist;
2029 *s = rd_stats.skip;
2030 *sse = rd_stats.sse;
2031 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002032}
2033#endif // CONFIG_EXT_INTER
2034
Urvang Joshi52648442016-10-13 17:27:51 -07002035static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002036 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07002037 BLOCK_SIZE bs) {
2038 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002039 MACROBLOCKD *const xd = &x->e_mbd;
2040 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2041 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002042 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002043 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
2044 int s0 = av1_cost_bit(skip_prob, 0);
2045 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002046 const int is_inter = is_inter_block(mbmi);
2047 int prune = 0;
2048#if CONFIG_EXT_TX
2049 int ext_tx_set;
2050#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002051 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052
2053 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002054#if CONFIG_VAR_TX
2055 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002056#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002057#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002058 ext_tx_set =
2059 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002060#endif // CONFIG_EXT_TX
2061
2062 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2063#if CONFIG_EXT_TX
2064 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2065#else
2066 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08002067#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002068#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002069 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2070 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002071 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002072#if CONFIG_PVQ
2073 od_rollback_buffer pre_buf, post_buf;
2074
2075 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2076 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002077#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002078
2079 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002080 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002081 if (is_inter) {
2082 if (x->use_default_inter_tx_type &&
2083 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2084 continue;
2085 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2086 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2087 if (!do_tx_type_search(tx_type, prune)) continue;
2088 }
2089 } else {
2090 if (x->use_default_intra_tx_type &&
2091 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2092 continue;
2093 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2094 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2095 }
2096 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2097 }
2098
2099 mbmi->tx_type = tx_type;
2100
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002101 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002103#if CONFIG_PVQ
2104 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002105#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002106 if (this_rd_stats.rate == INT_MAX) continue;
Sarah Parkere68a3e42017-02-16 14:03:24 -08002107 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter,
2108 cm->reduced_tx_set_used) > 1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109 if (is_inter) {
2110 if (ext_tx_set > 0)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002111 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002112 cpi->inter_tx_type_costs[ext_tx_set]
2113 [txsize_sqr_map[mbmi->tx_size]]
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002114 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002115 } else {
2116 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002117 this_rd_stats.rate +=
Urvang Joshifeb925f2016-12-05 10:37:29 -08002118 cpi->intra_tx_type_costs[ext_tx_set]
2119 [txsize_sqr_map[mbmi->tx_size]]
2120 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121 }
2122 }
2123
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002124 if (this_rd_stats.skip)
2125 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002126 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002127 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2128 this_rd_stats.dist);
2129 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2130 !this_rd_stats.skip)
2131 this_rd =
2132 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133
2134 if (this_rd < best_rd) {
2135 best_rd = this_rd;
2136 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002137 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002138#if CONFIG_PVQ
2139 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002140#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002141 }
2142 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002143#if CONFIG_PVQ
2144 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002145#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002146 } else {
2147 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002148 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2149 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002150 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002151#else // CONFIG_EXT_TX
2152 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2153 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002154 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155 if (!is_inter && x->use_default_intra_tx_type &&
2156 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2157 continue;
2158 if (is_inter && x->use_default_inter_tx_type &&
2159 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2160 continue;
2161 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002162 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002163 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002164 if (this_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002165 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002166 this_rd_stats.rate +=
2167 cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002168 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2169 !do_tx_type_search(tx_type, prune))
2170 continue;
2171 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002172 this_rd_stats.rate +=
2173 cpi->intra_tx_type_costs[mbmi->tx_size]
2174 [intra_mode_to_tx_type_context[mbmi->mode]]
2175 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002176 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002177 if (this_rd_stats.skip)
2178 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002179 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002180 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2181 this_rd_stats.dist);
2182 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2183 this_rd =
2184 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002185
2186 if (this_rd < best_rd) {
2187 best_rd = this_rd;
2188 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002189 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002190 }
2191 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002192 } else {
2193 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002194 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2195 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002196 }
2197#endif // CONFIG_EXT_TX
2198 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002199}
2200
Urvang Joshi52648442016-10-13 17:27:51 -07002201static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002202 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002203 BLOCK_SIZE bs) {
2204 MACROBLOCKD *const xd = &x->e_mbd;
2205 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2206
2207 mbmi->tx_size = TX_4X4;
2208 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002209#if CONFIG_VAR_TX
2210 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002211#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002212
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002213 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2214 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002215}
2216
Urvang Joshi52648442016-10-13 17:27:51 -07002217static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002218 MACROBLOCK *x, RD_STATS *rd_stats,
2219 int64_t ref_best_rd, BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002220 MACROBLOCKD *const xd = &x->e_mbd;
2221 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002222 int64_t rd = INT64_MAX;
2223 int64_t best_rd = INT64_MAX;
2224 TX_SIZE best_tx = max_txsize_lookup[bs];
2225 const int is_inter = is_inter_block(mbmi);
2226 TX_TYPE tx_type, best_tx_type = DCT_DCT;
2227 int prune = 0;
2228
Yushin Cho77bba8d2016-11-04 16:36:56 -07002229#if CONFIG_PVQ
2230 od_rollback_buffer buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08002231#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2233 // passing -1 in for tx_type indicates that all 1D
2234 // transforms should be considered for pruning
2235 prune = prune_tx_types(cpi, bs, x, xd, -1);
2236
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002237 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238
Yushin Cho77bba8d2016-11-04 16:36:56 -07002239#if CONFIG_PVQ
2240 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002241#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002242 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002243 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002244#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07002245 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -08002246#endif // CONFIG_REF_MV
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002247 rd = choose_tx_size_fix_type(cpi, bs, x, &this_rd_stats, ref_best_rd,
Yushin Cho55711e62016-11-10 18:49:24 -08002248 tx_type,
2249#if CONFIG_PVQ
2250 buf,
Fergus Simpson4063a682017-02-28 16:52:22 -08002251#endif // CONFIG_PVQ
Yushin Cho55711e62016-11-10 18:49:24 -08002252 prune);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253 if (rd < best_rd) {
2254 best_rd = rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002255 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256 best_tx_type = tx_type;
2257 best_tx = mbmi->tx_size;
2258 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002259#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2260 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002261#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07002262 }
2263
2264 mbmi->tx_size = best_tx;
2265 mbmi->tx_type = best_tx_type;
2266
Jingning Hane67b38a2016-11-04 10:30:00 -07002267#if CONFIG_VAR_TX
2268 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002269#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002270
Yaowu Xuc27fc142016-08-22 16:08:15 -07002271#if !CONFIG_EXT_TX
2272 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002273#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002274#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002275 if (best_rd != INT64_MAX) {
Guillaume Martres930118c2016-12-06 20:26:22 -10002276 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx);
Yushin Cho05f540a2016-11-08 22:12:51 -08002277 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002278#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002279}
2280
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002281static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2282 RD_STATS *rd_stats, BLOCK_SIZE bs,
2283 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002284 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002285 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002286
2287 assert(bs == xd->mi[0]->mbmi.sb_type);
2288
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002289 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002290 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002291 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002292 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002293 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002294 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002295 }
2296}
2297
2298static int conditional_skipintra(PREDICTION_MODE mode,
2299 PREDICTION_MODE best_intra_mode) {
2300 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2301 best_intra_mode != D135_PRED)
2302 return 1;
2303 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2304 best_intra_mode != D45_PRED)
2305 return 1;
2306 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2307 best_intra_mode != D45_PRED)
2308 return 1;
2309 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2310 best_intra_mode != D135_PRED)
2311 return 1;
2312 return 0;
2313}
2314
hui su308a6392017-01-12 14:49:57 -08002315// Model based RD estimation for luma intra blocks.
2316static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002317 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002318 MACROBLOCKD *const xd = &x->e_mbd;
2319 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2320 RD_STATS this_rd_stats;
2321 int row, col;
2322 int64_t temp_sse, this_rd;
2323 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2324 const int stepr = tx_size_high_unit[tx_size];
2325 const int stepc = tx_size_wide_unit[tx_size];
2326 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2327 const int max_blocks_high = max_block_high(xd, bsize, 0);
2328 mbmi->tx_size = tx_size;
2329 // Prediction.
2330 for (row = 0; row < max_blocks_high; row += stepr) {
2331 for (col = 0; col < max_blocks_wide; col += stepc) {
2332 struct macroblockd_plane *const pd = &xd->plane[0];
2333 uint8_t *dst =
2334 &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
David Barker839467f2017-01-19 11:06:15 +00002335 av1_predict_intra_block(xd, pd->width, pd->height,
2336 txsize_to_bsize[tx_size], mbmi->mode, dst,
2337 pd->dst.stride, dst, pd->dst.stride, col, row, 0);
hui su308a6392017-01-12 14:49:57 -08002338 }
2339 }
2340 // RD estimation.
2341 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2342 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002343#if CONFIG_EXT_INTRA
2344 if (av1_is_directional_mode(mbmi->mode, bsize)) {
2345 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
2346 mode_cost += write_uniform_cost(2 * max_angle_delta + 1,
2347 max_angle_delta + mbmi->angle_delta[0]);
2348 }
2349#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002350#if CONFIG_FILTER_INTRA
2351 if (mbmi->mode == DC_PRED) {
2352 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2353 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2354 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2355 mode_cost += (av1_cost_bit(prob, 1) +
2356 write_uniform_cost(FILTER_INTRA_MODES, mode));
2357 } else {
2358 mode_cost += av1_cost_bit(prob, 0);
2359 }
2360 }
2361#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002362 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2363 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002364 return this_rd;
2365}
2366
Urvang Joshib100db72016-10-12 16:28:56 -07002367#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002368// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2369// new_height'. Extra rows and columns are filled in by copying last valid
2370// row/column.
2371static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2372 int orig_height, int new_width,
2373 int new_height) {
2374 int j;
2375 assert(new_width >= orig_width);
2376 assert(new_height >= orig_height);
2377 if (new_width == orig_width && new_height == orig_height) return;
2378
2379 for (j = orig_height - 1; j >= 0; --j) {
2380 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2381 // Copy last column to extra columns.
2382 memset(color_map + j * new_width + orig_width,
2383 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2384 }
2385 // Copy last row to extra rows.
2386 for (j = orig_height; j < new_height; ++j) {
2387 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2388 new_width);
2389 }
2390}
2391
hui sude0c70a2017-01-09 17:12:17 -08002392static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2393 BLOCK_SIZE bsize, int palette_ctx,
2394 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2395 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002396 int64_t *best_rd, int64_t *best_model_rd,
2397 int *rate, int *rate_tokenonly,
2398 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002399 int rate_overhead = 0;
2400 MACROBLOCKD *const xd = &x->e_mbd;
2401 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002402 MB_MODE_INFO *const mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002403 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002404 const int src_stride = x->plane[0].src.stride;
2405 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002406 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002407 int block_width, block_height, rows, cols;
2408 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2409 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002410
2411 assert(cpi->common.allow_screen_content_tools);
2412
Yaowu Xuf883b422016-08-30 14:01:10 -07002413#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002414 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002415 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2416 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002418#endif // CONFIG_AOM_HIGHBITDEPTH
2419 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002420#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002421 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002422#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002423
2424 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002425 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002426 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002427 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002428 float *const data = x->palette_buffer->kmeans_data_buf;
2429 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002430 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002431 RD_STATS tokenonly_rd_stats;
2432 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002433 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07002434#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2436 if (cpi->common.use_highbitdepth)
2437 lb = ub = src16[0];
2438 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002439#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002440 lb = ub = src[0];
2441
Yaowu Xuf883b422016-08-30 14:01:10 -07002442#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002443 if (cpi->common.use_highbitdepth) {
2444 for (r = 0; r < rows; ++r) {
2445 for (c = 0; c < cols; ++c) {
2446 val = src16[r * src_stride + c];
2447 data[r * cols + c] = val;
2448 if (val < lb)
2449 lb = val;
2450 else if (val > ub)
2451 ub = val;
2452 }
2453 }
2454 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002455#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002456 for (r = 0; r < rows; ++r) {
2457 for (c = 0; c < cols; ++c) {
2458 val = src[r * src_stride + c];
2459 data[r * cols + c] = val;
2460 if (val < lb)
2461 lb = val;
2462 else if (val > ub)
2463 ub = val;
2464 }
2465 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002466#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002468#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002469
2470 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002471#if CONFIG_FILTER_INTRA
2472 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2473#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002474
2475 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2476
2477 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2478 --n) {
2479 for (i = 0; i < n; ++i)
2480 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07002481 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
2482 k = av1_remove_duplicates(centroids, n);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002483
Yaowu Xuf883b422016-08-30 14:01:10 -07002484#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002485 if (cpi->common.use_highbitdepth)
2486 for (i = 0; i < k; ++i)
2487 pmi->palette_colors[i] =
2488 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2489 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002490#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 for (i = 0; i < k; ++i)
2492 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2493 pmi->palette_size[0] = k;
2494
Yaowu Xuf883b422016-08-30 14:01:10 -07002495 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002496 extend_palette_color_map(color_map, cols, rows, block_width,
2497 block_height);
hui su78c611a2017-01-13 17:06:04 -08002498 palette_mode_cost =
2499 dc_mode_cost + cpi->common.bit_depth * k * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08002500 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002502 av1_cost_bit(
2503 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002504 1);
2505 for (i = 0; i < rows; ++i) {
2506 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002507 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002508 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002509 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002511 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2512 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002513 }
2514 }
hui su78c611a2017-01-13 17:06:04 -08002515 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2516 if (*best_model_rd != INT64_MAX &&
2517 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2518 continue;
2519 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2520 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2521 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2522 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002523 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002524 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002525 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002526 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527 if (this_rd < *best_rd) {
2528 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002530 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002531 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002532 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002533 if (rate) *rate = this_rate;
2534 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2535 if (distortion) *distortion = tokenonly_rd_stats.dist;
2536 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002537 }
2538 }
2539 }
hui sude0c70a2017-01-09 17:12:17 -08002540
2541 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2542 memcpy(color_map, best_palette_color_map,
2543 rows * cols * sizeof(best_palette_color_map[0]));
2544 }
2545 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 return rate_overhead;
2547}
Urvang Joshib100db72016-10-12 16:28:56 -07002548#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549
Urvang Joshifeb925f2016-12-05 10:37:29 -08002550// Wrappers to make function pointers usable.
2551static void inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2552 int stride, int eob, TX_TYPE tx_type,
2553 int lossless) {
2554 (void)lossless;
2555 av1_inv_txfm_add_4x8(input, dest, stride, eob, tx_type);
2556}
2557
2558static void inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2559 int stride, int eob, TX_TYPE tx_type,
2560 int lossless) {
2561 (void)lossless;
2562 av1_inv_txfm_add_8x4(input, dest, stride, eob, tx_type);
2563}
2564
2565typedef void (*inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int, int,
2566 TX_TYPE, int);
2567#if CONFIG_AOM_HIGHBITDEPTH
2568
2569void highbd_inv_txfm_add_4x8_wrapper(const tran_low_t *input, uint8_t *dest,
2570 int stride, int eob, int bd,
2571 TX_TYPE tx_type, int is_lossless) {
2572 (void)is_lossless;
2573 av1_highbd_inv_txfm_add_4x8(input, dest, stride, eob, bd, tx_type);
2574}
2575
2576void highbd_inv_txfm_add_8x4_wrapper(const tran_low_t *input, uint8_t *dest,
2577 int stride, int eob, int bd,
2578 TX_TYPE tx_type, int is_lossless) {
2579 (void)is_lossless;
2580 av1_highbd_inv_txfm_add_8x4(input, dest, stride, eob, bd, tx_type);
2581}
2582
2583typedef void (*highbd_inv_txfm_func_ptr)(const tran_low_t *, uint8_t *, int,
2584 int, int, TX_TYPE, int);
2585#endif // CONFIG_AOM_HIGHBITDEPTH
2586
2587static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002588 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2589 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2590 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002591 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002592 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002593 PREDICTION_MODE mode;
2594 MACROBLOCKD *const xd = &x->e_mbd;
2595 int64_t best_rd = rd_thresh;
2596 struct macroblock_plane *p = &x->plane[0];
2597 struct macroblockd_plane *pd = &xd->plane[0];
2598 const int src_stride = p->src.stride;
2599 const int dst_stride = pd->dst.stride;
2600 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002601 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002602#if CONFIG_CB4X4
2603 // TODO(jingning): This is a temporal change. The whole function should be
2604 // out when cb4x4 is enabled.
2605 ENTROPY_CONTEXT ta[4], tempa[4];
2606 ENTROPY_CONTEXT tl[4], templ[4];
2607#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002608 ENTROPY_CONTEXT ta[2], tempa[2];
2609 ENTROPY_CONTEXT tl[2], templ[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08002610#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002611
2612 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2613 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2614 const int tx_width_unit = tx_size_wide_unit[tx_size];
2615 const int tx_height_unit = tx_size_high_unit[tx_size];
2616 const int pred_block_width = block_size_wide[bsize];
2617 const int pred_block_height = block_size_high[bsize];
2618 const int tx_width = tx_size_wide[tx_size];
2619 const int tx_height = tx_size_high[tx_size];
2620 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2621 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002622 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002623 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002624 uint8_t best_dst[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002625 inv_txfm_func_ptr inv_txfm_func =
2626 (tx_size == TX_4X4) ? av1_inv_txfm_add_4x4
2627 : (tx_size == TX_4X8) ? inv_txfm_add_4x8_wrapper
2628 : inv_txfm_add_8x4_wrapper;
Yaowu Xuf883b422016-08-30 14:01:10 -07002629#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002630 uint16_t best_dst16[8 * 8];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002631 highbd_inv_txfm_func_ptr highbd_inv_txfm_func =
2632 (tx_size == TX_4X4)
2633 ? av1_highbd_inv_txfm_add_4x4
2634 : (tx_size == TX_4X8) ? highbd_inv_txfm_add_4x8_wrapper
2635 : highbd_inv_txfm_add_8x4_wrapper;
Fergus Simpson4063a682017-02-28 16:52:22 -08002636#endif // CONFIG_AOM_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002637 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2638#if CONFIG_EXT_TX && CONFIG_RECT_TX
2639 const int sub_bsize = bsize;
2640#else
2641 const int sub_bsize = BLOCK_4X4;
2642#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002643
Yushin Cho77bba8d2016-11-04 16:36:56 -07002644#if CONFIG_PVQ
2645 od_rollback_buffer pre_buf, post_buf;
2646 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2647 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002648#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002649
Urvang Joshifeb925f2016-12-05 10:37:29 -08002650 assert(bsize < BLOCK_8X8);
2651 assert(tx_width < 8 || tx_height < 8);
2652#if CONFIG_EXT_TX && CONFIG_RECT_TX
2653 assert(tx_width == pred_block_width && tx_height == pred_block_height);
2654#else
2655 assert(tx_width == 4 && tx_height == 4);
2656#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2657
2658 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2659 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2660
2661 xd->mi[0]->mbmi.tx_size = tx_size;
2662
Urvang Joshib100db72016-10-12 16:28:56 -07002663#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002664 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002665#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002666
Yaowu Xuf883b422016-08-30 14:01:10 -07002667#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002668 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002669#if CONFIG_PVQ
2670 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2671#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2673 int64_t this_rd;
2674 int ratey = 0;
2675 int64_t distortion = 0;
2676 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002677 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002678
Urvang Joshifeb925f2016-12-05 10:37:29 -08002679 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2680 (1 << mode)))
2681 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002682
2683 // Only do the oblique modes if the best so far is
2684 // one of the neighboring directional modes
2685 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2686 if (conditional_skipintra(mode, *best_mode)) continue;
2687 }
2688
Urvang Joshifeb925f2016-12-05 10:37:29 -08002689 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2690 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002691
Urvang Joshifeb925f2016-12-05 10:37:29 -08002692 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2693 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2694 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2695 const int block =
2696 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002697 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2698 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08002699#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002700 int16_t *const src_diff = av1_raster_block_offset_int16(
2701 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002702#else
2703 int i, j;
2704#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002705 int skip;
2706 assert(block < 4);
2707 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2708 idx == 0 && idy == 0));
2709 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2710 block == 0 || block == 2));
2711 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002712 av1_predict_intra_block(
2713 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2714 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002715#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002716 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2717 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002718#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002719 if (is_lossless) {
2720 TX_TYPE tx_type =
2721 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2722 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002723 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002724 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002725#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002726#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002727 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002728 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002729#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002730 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002731 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002732#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002733 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002734 scan_order->scan, scan_order->neighbors,
2735 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002736 skip = (p->eobs[block] == 0);
2737 can_skip &= skip;
2738 tempa[idx] = !skip;
2739 templ[idy] = !skip;
2740#if CONFIG_EXT_TX
2741 if (tx_size == TX_8X4) {
2742 tempa[idx + 1] = tempa[idx];
2743 } else if (tx_size == TX_4X8) {
2744 templ[idy + 1] = templ[idy];
2745 }
2746#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002747#else
2748 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002749
Thomas Daede6ff6af62017-02-03 16:29:24 -08002750 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2751 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
2752
2753 ratey += x->rate;
2754 skip = x->pvq_skip[0];
2755 tempa[idx] = !skip;
2756 templ[idy] = !skip;
2757 can_skip &= skip;
2758#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002759 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2760 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08002761#if CONFIG_PVQ
2762 if (!skip) {
2763 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2764 for (j = 0; j < tx_height; j++)
2765 for (i = 0; i < tx_width; i++)
2766 *CONVERT_TO_SHORTPTR(dst + j * dst_stride + i) = 0;
2767 } else {
2768 for (j = 0; j < tx_height; j++)
2769 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
2770 }
2771#endif
2772 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2773 dst_stride, p->eobs[block], xd->bd, DCT_DCT,
2774 1);
2775#if CONFIG_PVQ
2776 }
2777#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002778 } else {
2779 int64_t dist;
2780 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002781 TX_TYPE tx_type =
2782 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2783 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002784 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002785 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002786#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002787#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002788 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002789 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790#else
Angie Chiangff6d8902016-10-21 11:02:09 -07002791 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002792 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002793#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002794 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
2795 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002796 scan_order->scan, scan_order->neighbors,
2797 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002798 skip = (p->eobs[block] == 0);
2799 can_skip &= skip;
2800 tempa[idx] = !skip;
2801 templ[idy] = !skip;
2802#if CONFIG_EXT_TX
2803 if (tx_size == TX_8X4) {
2804 tempa[idx + 1] = tempa[idx];
2805 } else if (tx_size == TX_4X8) {
2806 templ[idy + 1] = templ[idy];
2807 }
2808#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002809#else
2810 (void)scan_order;
2811
2812 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2813 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2814 ratey += x->rate;
2815 skip = x->pvq_skip[0];
2816 tempa[idx] = !skip;
2817 templ[idy] = !skip;
2818 can_skip &= skip;
2819#endif
2820#if CONFIG_PVQ
2821 if (!skip) {
2822 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2823 for (j = 0; j < tx_height; j++)
2824 for (i = 0; i < tx_width; i++)
2825 *CONVERT_TO_SHORTPTR(dst + j * dst_stride + i) = 0;
2826 } else {
2827 for (j = 0; j < tx_height; j++)
2828 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
2829 }
2830#endif
2831 highbd_inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst,
2832 dst_stride, p->eobs[block], xd->bd, tx_type,
2833 0);
2834#if CONFIG_PVQ
2835 }
2836#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002837 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 dist = (int64_t)tmp << 4;
2839 distortion += dist;
2840 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2841 goto next_highbd;
2842 }
2843 }
2844 }
2845
2846 rate += ratey;
2847 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2848
2849 if (this_rd < best_rd) {
2850 *bestrate = rate;
2851 *bestratey = ratey;
2852 *bestdistortion = distortion;
2853 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002854 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002856 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2857 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08002858#if CONFIG_PVQ
2859 od_encode_checkpoint(&x->daala_enc, &post_buf);
2860#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002861 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002862 memcpy(best_dst16 + idy * 8,
2863 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002864 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002865 }
2866 }
2867 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08002868#if CONFIG_PVQ
2869 od_encode_rollback(&x->daala_enc, &pre_buf);
2870#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 }
2872
2873 if (best_rd >= rd_thresh) return best_rd;
2874
Thomas Daede6ff6af62017-02-03 16:29:24 -08002875#if CONFIG_PVQ
2876 od_encode_rollback(&x->daala_enc, &post_buf);
2877#endif
2878
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002879 if (y_skip) *y_skip &= best_can_skip;
2880
Urvang Joshifeb925f2016-12-05 10:37:29 -08002881 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002883 best_dst16 + idy * 8,
2884 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002885 }
2886
2887 return best_rd;
2888 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002889#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002890
Yushin Cho77bba8d2016-11-04 16:36:56 -07002891#if CONFIG_PVQ
2892 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002893#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002894
Yaowu Xuc27fc142016-08-22 16:08:15 -07002895 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2896 int64_t this_rd;
2897 int ratey = 0;
2898 int64_t distortion = 0;
2899 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002900 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002901
Urvang Joshifeb925f2016-12-05 10:37:29 -08002902 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2903 (1 << mode))) {
2904 continue;
2905 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002906
2907 // Only do the oblique modes if the best so far is
2908 // one of the neighboring directional modes
2909 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2910 if (conditional_skipintra(mode, *best_mode)) continue;
2911 }
2912
Urvang Joshifeb925f2016-12-05 10:37:29 -08002913 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2914 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002915
Urvang Joshifeb925f2016-12-05 10:37:29 -08002916 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2917 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2918 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2919 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002920 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2921 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002922#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002923 int16_t *const src_diff = av1_raster_block_offset_int16(
2924 BLOCK_8X8, block_raster_idx, p->src_diff);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002925#else
Urvang Joshifeb925f2016-12-05 10:37:29 -08002926 int i, j;
Fergus Simpson4063a682017-02-28 16:52:22 -08002927#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002928 int skip;
2929 assert(block < 4);
2930 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2931 idx == 0 && idy == 0));
2932 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2933 block == 0 || block == 2));
2934 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002935 av1_predict_intra_block(xd, pd->width, pd->height,
2936 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2937 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002938#if CONFIG_CB4X4
2939 2 * (col + idx), 2 * (row + idy),
2940#else
2941 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002942#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002943 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002944#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002945 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2946 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002947#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002948
Urvang Joshifeb925f2016-12-05 10:37:29 -08002949 if (is_lossless) {
2950 TX_TYPE tx_type =
2951 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
2952 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002954 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002955#if CONFIG_CB4X4
2956 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002957#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002958#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002959#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08002960 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002961 tx_size, coeff_ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002962#else
Jingning Hand1097fc2016-12-06 10:55:34 -08002963 av1_xform_quant(cm, x, 0, block,
2964#if CONFIG_CB4X4
2965 2 * (row + idy), 2 * (col + idx),
2966#else
2967 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002968#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002969 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002970#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002971 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002972 scan_order->scan, scan_order->neighbors,
2973 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002974 skip = (p->eobs[block] == 0);
2975 can_skip &= skip;
2976 tempa[idx] = !skip;
2977 templ[idy] = !skip;
2978#if CONFIG_EXT_TX
2979 if (tx_size == TX_8X4) {
2980 tempa[idx + 1] = tempa[idx];
2981 } else if (tx_size == TX_4X8) {
2982 templ[idy + 1] = templ[idy];
2983 }
2984#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002985#else
Yushin Cho900243b2017-01-03 11:02:38 -08002986 (void)scan_order;
2987
2988 av1_xform_quant(cm, x, 0, block,
2989#if CONFIG_CB4X4
2990 2 * (row + idy), 2 * (col + idx),
2991#else
2992 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002993#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002994 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
Yushin Cho900243b2017-01-03 11:02:38 -08002995
2996 ratey += x->rate;
2997 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08002998 tempa[idx] = !skip;
2999 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08003000 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08003001#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003002 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
3003 goto next;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003004#if CONFIG_PVQ
3005 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003006 for (j = 0; j < tx_height; j++)
3007 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08003008#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003009 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
3010 p->eobs[block], DCT_DCT, 1);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003011#if CONFIG_PVQ
3012 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003013#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003014 } else {
3015 int64_t dist;
3016 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003017 TX_TYPE tx_type =
3018 get_tx_type(PLANE_TYPE_Y, xd, block_raster_idx, tx_size);
3019 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003020 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003021 combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08003022#if CONFIG_CB4X4
3023 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08003024#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08003025#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003026#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003027 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003028 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003029#else
Jingning Hand1097fc2016-12-06 10:55:34 -08003030 av1_xform_quant(cm, x, 0, block,
3031#if CONFIG_CB4X4
3032 2 * (row + idy), 2 * (col + idx),
3033#else
3034 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003035#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08003036 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003037#endif // CONFIG_NEW_QUANT
Urvang Joshifeb925f2016-12-05 10:37:29 -08003038 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
3039 ratey += av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003040 scan_order->scan, scan_order->neighbors,
3041 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003042 skip = (p->eobs[block] == 0);
3043 can_skip &= skip;
3044 tempa[idx] = !skip;
3045 templ[idy] = !skip;
3046#if CONFIG_EXT_TX
3047 if (tx_size == TX_8X4) {
3048 tempa[idx + 1] = tempa[idx];
3049 } else if (tx_size == TX_4X8) {
3050 templ[idy + 1] = templ[idy];
3051 }
3052#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07003053#else
Yushin Cho900243b2017-01-03 11:02:38 -08003054 (void)scan_order;
3055
3056 av1_xform_quant(cm, x, 0, block,
3057#if CONFIG_CB4X4
3058 2 * (row + idy), 2 * (col + idx),
3059#else
3060 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003061#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08003062 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yushin Cho900243b2017-01-03 11:02:38 -08003063 ratey += x->rate;
3064 skip = x->pvq_skip[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003065 tempa[idx] = !skip;
3066 templ[idy] = !skip;
Yushin Cho900243b2017-01-03 11:02:38 -08003067 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08003068#endif // !CONFIG_PVQ
Yushin Chob27a17f2016-12-23 14:33:02 -08003069#if CONFIG_PVQ
3070 if (!skip) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003071 for (j = 0; j < tx_height; j++)
3072 for (i = 0; i < tx_width; i++) dst[j * dst_stride + i] = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08003073#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003074 inv_txfm_func(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
3075 p->eobs[block], tx_type, 0);
Yushin Chob27a17f2016-12-23 14:33:02 -08003076#if CONFIG_PVQ
3077 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003078#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003079 // No need for av1_block_error2_c because the ssz is unused
Urvang Joshifeb925f2016-12-05 10:37:29 -08003080 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081 dist = (int64_t)tmp << 4;
3082 distortion += dist;
3083 // To use the pixel domain distortion, the step below needs to be
3084 // put behind the inv txfm. Compared to calculating the distortion
3085 // in the frequency domain, the overhead of encoding effort is low.
3086 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
3087 goto next;
3088 }
3089 }
3090 }
3091
3092 rate += ratey;
3093 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
3094
3095 if (this_rd < best_rd) {
3096 *bestrate = rate;
3097 *bestratey = ratey;
3098 *bestdistortion = distortion;
3099 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003100 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003101 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003102 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3103 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003104#if CONFIG_PVQ
3105 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003106#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003107 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003108 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003109 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003110 }
3111 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003112#if CONFIG_PVQ
3113 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003114#endif // CONFIG_PVQ
3115 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003116
3117 if (best_rd >= rd_thresh) return best_rd;
3118
Yushin Cho77bba8d2016-11-04 16:36:56 -07003119#if CONFIG_PVQ
3120 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003121#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003122
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003123 if (y_skip) *y_skip &= best_can_skip;
3124
Urvang Joshifeb925f2016-12-05 10:37:29 -08003125 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003126 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003127 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003128
3129 return best_rd;
3130}
3131
Urvang Joshi52648442016-10-13 17:27:51 -07003132static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3133 MACROBLOCK *mb, int *rate,
3134 int *rate_y, int64_t *distortion,
3135 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003136 const MACROBLOCKD *const xd = &mb->e_mbd;
3137 MODE_INFO *const mic = xd->mi[0];
3138 const MODE_INFO *above_mi = xd->above_mi;
3139 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003140 MB_MODE_INFO *const mbmi = &mic->mbmi;
3141 const BLOCK_SIZE bsize = mbmi->sb_type;
3142 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3143 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003144 int idx, idy;
3145 int cost = 0;
3146 int64_t total_distortion = 0;
3147 int tot_rate_y = 0;
3148 int64_t total_rd = 0;
3149 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003150 const int is_lossless = xd->lossless[mbmi->segment_id];
3151#if CONFIG_EXT_TX && CONFIG_RECT_TX
3152 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3153#else
3154 const TX_SIZE tx_size = TX_4X4;
3155#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003156
3157#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003158#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003159 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003160#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003162#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003163 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003164#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003165
3166 // TODO(any): Add search of the tx_type to improve rd performance at the
3167 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003168 mbmi->tx_type = DCT_DCT;
3169 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003170
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003171 if (y_skip) *y_skip = 1;
3172
Urvang Joshifeb925f2016-12-05 10:37:29 -08003173 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3174 // 8x8 coding block.
3175 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3176 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 PREDICTION_MODE best_mode = DC_PRED;
3178 int r = INT_MAX, ry = INT_MAX;
3179 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003180 int j;
3181 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003182 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003183 const PREDICTION_MODE A =
3184 av1_above_block_mode(mic, above_mi, pred_block_idx);
3185 const PREDICTION_MODE L =
3186 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003187
3188 bmode_costs = cpi->y_mode_costs[A][L];
3189 }
3190
Urvang Joshifeb925f2016-12-05 10:37:29 -08003191 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003192 cpi, mb, idy, idx, &best_mode, bmode_costs,
3193 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003194 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003195#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003196 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003197#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003198 total_rd += this_rd;
3199 cost += r;
3200 total_distortion += d;
3201 tot_rate_y += ry;
3202
Urvang Joshifeb925f2016-12-05 10:37:29 -08003203 mic->bmi[pred_block_idx].as_mode = best_mode;
3204 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3205 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3206 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3207 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003208
3209 if (total_rd >= best_rd) return INT64_MAX;
3210 }
3211 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003212 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003213
Yushin Cho7a428ba2017-01-12 16:28:49 -08003214#if CONFIG_DAALA_DIST
3215 {
3216 const struct macroblock_plane *p = &mb->plane[0];
3217 const struct macroblockd_plane *pd = &xd->plane[0];
3218 const int src_stride = p->src.stride;
3219 const int dst_stride = pd->dst.stride;
3220 uint8_t *src = p->src.buf;
3221 uint8_t *dst = pd->dst.buf;
3222 int use_activity_masking = 0;
3223 int qm = OD_HVS_QM;
3224
3225#if CONFIG_PVQ
3226 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003227#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003228 // Daala-defined distortion computed for the block of 8x8 pixels
3229 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, TX_8X8,
3230 qm, use_activity_masking, mb->qindex)
3231 << 4;
3232 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003233#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003234 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003235 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003236 int rate_tx_type = 0;
3237#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003238 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3239 1) {
3240 const int eset =
3241 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003242 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3243 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003244 }
3245#else
clang-format67948d32016-09-07 22:40:40 -07003246 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003247 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3248 [intra_mode_to_tx_type_context[mbmi->mode]]
3249 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003250#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003251 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003252 cost += rate_tx_type;
3253 tot_rate_y += rate_tx_type;
3254 }
3255
3256 *rate = cost;
3257 *rate_y = tot_rate_y;
3258 *distortion = total_distortion;
3259
3260 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3261}
3262
hui su5db97432016-10-14 16:10:14 -07003263#if CONFIG_FILTER_INTRA
3264// Return 1 if an filter intra mode is selected; return 0 otherwise.
3265static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3266 int *rate, int *rate_tokenonly,
3267 int64_t *distortion, int *skippable,
3268 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003269 int64_t *best_rd, int64_t *best_model_rd,
3270 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271 MACROBLOCKD *const xd = &x->e_mbd;
3272 MODE_INFO *const mic = xd->mi[0];
3273 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003274 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003275 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003276 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003277 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278 TX_TYPE best_tx_type;
3279
hui su5db97432016-10-14 16:10:14 -07003280 av1_zero(filter_intra_mode_info);
3281 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003282 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003283#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003284 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003285#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003286
3287 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003288 int this_rate;
3289 int64_t this_rd, this_model_rd;
3290 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003291 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003292 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003293 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3294 if (*best_model_rd != INT64_MAX &&
3295 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3296 continue;
3297 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003298 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3299 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003300 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003301 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003303 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003304
3305 if (this_rd < *best_rd) {
3306 *best_rd = this_rd;
3307 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003308 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309 best_tx_type = mic->mbmi.tx_type;
3310 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003311 *rate_tokenonly = tokenonly_rd_stats.rate;
3312 *distortion = tokenonly_rd_stats.dist;
3313 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003314 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003315 }
3316 }
3317
hui su5db97432016-10-14 16:10:14 -07003318 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003319 mbmi->mode = DC_PRED;
3320 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003321 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3322 filter_intra_mode_info.use_filter_intra_mode[0];
3323 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3324 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003325 mbmi->tx_type = best_tx_type;
3326 return 1;
3327 } else {
3328 return 0;
3329 }
3330}
hui su5db97432016-10-14 16:10:14 -07003331#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332
hui su5db97432016-10-14 16:10:14 -07003333#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003334// Run RD calculation with given luma intra prediction angle., and return
3335// the RD cost. Update the best mode info. if the RD cost is the best so far.
3336static int64_t calc_rd_given_intra_angle(
3337 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3338 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3339 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3340 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003341#if CONFIG_INTRA_INTERP
3342 INTRA_FILTER *best_filter,
3343#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003344 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003345 int this_rate;
3346 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003347 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003348 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003349
hui su45dc5972016-12-08 17:42:50 -08003350 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003351 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3352 if (*best_model_rd != INT64_MAX &&
3353 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3354 return INT64_MAX;
3355 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003356 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3357 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3358
3359 this_rate = tokenonly_rd_stats.rate + mode_cost +
3360 write_uniform_cost(2 * max_angle_delta + 1,
3361 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003362 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003363
3364 if (this_rd < *best_rd) {
3365 *best_rd = this_rd;
3366 *best_angle_delta = mbmi->angle_delta[0];
3367 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003368#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003369 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003370#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003371 *best_tx_type = mbmi->tx_type;
3372 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003373 rd_stats->rate = tokenonly_rd_stats.rate;
3374 rd_stats->dist = tokenonly_rd_stats.dist;
3375 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 }
hui su45dc5972016-12-08 17:42:50 -08003377 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003378}
3379
hui su45dc5972016-12-08 17:42:50 -08003380// With given luma directional intra prediction mode, pick the best angle delta
3381// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003382static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003383 int *rate, RD_STATS *rd_stats,
3384 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003385 int64_t best_rd,
3386 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003387 MACROBLOCKD *const xd = &x->e_mbd;
3388 MODE_INFO *const mic = xd->mi[0];
3389 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su45dc5972016-12-08 17:42:50 -08003390 int i, angle_delta, best_angle_delta = 0;
3391 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
3392 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003393#if CONFIG_INTRA_INTERP
3394 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003395 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003396 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003397#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003398 int64_t this_rd, best_rd_in, rd_cost[16];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3400 TX_TYPE best_tx_type = mbmi->tx_type;
3401
hui su45dc5972016-12-08 17:42:50 -08003402 for (i = 0; i < 2 * (max_angle_delta + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003403
hui su45dc5972016-12-08 17:42:50 -08003404 for (angle_delta = 0; angle_delta <= max_angle_delta; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003405#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003406 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3407 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3408 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003409#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003410 for (i = 0; i < 2; ++i) {
3411 best_rd_in = (best_rd == INT64_MAX)
3412 ? INT64_MAX
3413 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3414 this_rd = calc_rd_given_intra_angle(
3415 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003416#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003417 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003418#else
hui su45dc5972016-12-08 17:42:50 -08003419 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003420#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003421 best_rd_in, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3422 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003423#if CONFIG_INTRA_INTERP
3424 &best_filter,
3425#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003426 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003427 rd_cost[2 * angle_delta + i] = this_rd;
3428 if (first_try && this_rd == INT64_MAX) return best_rd;
3429 first_try = 0;
3430 if (angle_delta == 0) {
3431 rd_cost[1] = this_rd;
3432 break;
3433 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003434 }
hui su45dc5972016-12-08 17:42:50 -08003435#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003436 }
hui su45dc5972016-12-08 17:42:50 -08003437#endif // CONFIG_INTRA_INTERP
3438 }
3439
3440 assert(best_rd != INT64_MAX);
3441 for (angle_delta = 1; angle_delta <= max_angle_delta; angle_delta += 2) {
3442 int64_t rd_thresh;
3443#if CONFIG_INTRA_INTERP
3444 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3445 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3446 mic->mbmi.intra_filter = filter;
3447#endif // CONFIG_INTRA_INTERP
3448 for (i = 0; i < 2; ++i) {
3449 int skip_search = 0;
3450 rd_thresh = best_rd + (best_rd >> 5);
3451 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3452 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3453 skip_search = 1;
3454 if (!skip_search) {
3455 this_rd = calc_rd_given_intra_angle(
3456 cpi, x, bsize,
3457#if CONFIG_INTRA_INTERP
3458 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3459#else
3460 mode_cost,
3461#endif // CONFIG_INTRA_INTERP
3462 best_rd, (1 - 2 * i) * angle_delta, max_angle_delta, rate,
3463 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3464#if CONFIG_INTRA_INTERP
3465 &best_filter,
3466#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003467 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003468 }
3469 }
3470#if CONFIG_INTRA_INTERP
3471 }
3472#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473 }
3474
hui sueda3d762016-12-06 16:58:23 -08003475#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003476 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
3477 p_angle = mode_to_angle_map[mbmi->mode] +
3478 best_angle_delta * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003479 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003480 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3481 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003482 this_rd = calc_rd_given_intra_angle(
3483 cpi, x, bsize,
3484 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3485 best_rd, best_angle_delta, max_angle_delta, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003486 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003487 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003488 }
3489 }
3490 }
hui sueda3d762016-12-06 16:58:23 -08003491#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003492
3493 mbmi->tx_size = best_tx_size;
3494 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003495#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003497#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003498 mbmi->tx_type = best_tx_type;
3499 return best_rd;
3500}
3501
3502// Indices are sign, integer, and fractional part of the gradient value
3503static const uint8_t gradient_to_angle_bin[2][7][16] = {
3504 {
3505 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3506 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3507 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3508 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3509 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3510 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3511 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3512 },
3513 {
3514 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3515 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3516 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3517 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3518 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3519 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3520 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3521 },
3522};
3523
3524static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3525 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
3526};
3527
3528static void angle_estimation(const uint8_t *src, int src_stride, int rows,
3529 int cols, uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003530 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003531 uint64_t hist[DIRECTIONAL_MODES];
3532 uint64_t hist_sum = 0;
3533
3534 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3535 src += src_stride;
3536 for (r = 1; r < rows; ++r) {
3537 for (c = 1; c < cols; ++c) {
3538 dx = src[c] - src[c - 1];
3539 dy = src[c] - src[c - src_stride];
3540 temp = dx * dx + dy * dy;
3541 if (dy == 0) {
3542 index = 2;
3543 } else {
3544 sn = (dx > 0) ^ (dy > 0);
3545 dx = abs(dx);
3546 dy = abs(dy);
3547 remd = dx % dy;
3548 quot = dx / dy;
3549 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003550 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003551 }
3552 hist[index] += temp;
3553 }
3554 src += src_stride;
3555 }
3556
3557 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3558 for (i = 0; i < INTRA_MODES; ++i) {
3559 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003560 const uint8_t angle_bin = mode_to_angle_bin[i];
3561 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003562 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003563 if (angle_bin > 0) {
3564 score += hist[angle_bin - 1];
3565 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003566 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003567 if (angle_bin < DIRECTIONAL_MODES - 1) {
3568 score += hist[angle_bin + 1];
3569 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 }
3571 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3572 directional_mode_skip_mask[i] = 1;
3573 }
3574 }
3575}
3576
Yaowu Xuf883b422016-08-30 14:01:10 -07003577#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003578static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
3579 int rows, int cols,
3580 uint8_t *directional_mode_skip_mask) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003581 int i, r, c, index, dx, dy, temp, sn, remd, quot;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003582 uint64_t hist[DIRECTIONAL_MODES];
3583 uint64_t hist_sum = 0;
3584 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
3585
3586 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3587 src += src_stride;
3588 for (r = 1; r < rows; ++r) {
3589 for (c = 1; c < cols; ++c) {
3590 dx = src[c] - src[c - 1];
3591 dy = src[c] - src[c - src_stride];
3592 temp = dx * dx + dy * dy;
3593 if (dy == 0) {
3594 index = 2;
3595 } else {
3596 sn = (dx > 0) ^ (dy > 0);
3597 dx = abs(dx);
3598 dy = abs(dy);
3599 remd = dx % dy;
3600 quot = dx / dy;
3601 remd = remd * 16 / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003602 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003603 }
3604 hist[index] += temp;
3605 }
3606 src += src_stride;
3607 }
3608
3609 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3610 for (i = 0; i < INTRA_MODES; ++i) {
3611 if (i != DC_PRED && i != TM_PRED) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003612 const uint8_t angle_bin = mode_to_angle_bin[i];
3613 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003614 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003615 if (angle_bin > 0) {
3616 score += hist[angle_bin - 1];
3617 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003619 if (angle_bin < DIRECTIONAL_MODES - 1) {
3620 score += hist[angle_bin + 1];
3621 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622 }
3623 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3624 directional_mode_skip_mask[i] = 1;
3625 }
3626 }
3627}
Yaowu Xuf883b422016-08-30 14:01:10 -07003628#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629#endif // CONFIG_EXT_INTRA
3630
3631// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003632static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3633 int *rate, int *rate_tokenonly,
3634 int64_t *distortion, int *skippable,
3635 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003636 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003637 MACROBLOCKD *const xd = &x->e_mbd;
3638 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003639 MB_MODE_INFO *const mbmi = &mic->mbmi;
3640 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003641 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003642#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003643 const int rows = block_size_high[bsize];
3644 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003645#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003646 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003647#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003648 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003650 const int src_stride = x->plane[0].src.stride;
3651 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003652#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003653#if CONFIG_FILTER_INTRA
3654 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003655 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3656#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003657 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003658#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003659 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003660 uint8_t *best_palette_color_map =
3661 cpi->common.allow_screen_content_tools
3662 ? x->palette_buffer->best_palette_color_map
3663 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003664 int palette_y_mode_ctx = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003665#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003666 const MODE_INFO *above_mi = xd->above_mi;
3667 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003668 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3669 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003670 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003671#if CONFIG_PVQ
3672 od_rollback_buffer pre_buf, post_buf;
3673
3674 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3675 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003676#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 bmode_costs = cpi->y_mode_costs[A][L];
3678
3679#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003680 mbmi->angle_delta[0] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681 memset(directional_mode_skip_mask, 0,
3682 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
Yaowu Xuf883b422016-08-30 14:01:10 -07003683#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003684 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3685 highbd_angle_estimation(src, src_stride, rows, cols,
3686 directional_mode_skip_mask);
3687 else
Fergus Simpson4063a682017-02-28 16:52:22 -08003688#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003689 angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
3690#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003691#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003692 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003693#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003694#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003695 pmi->palette_size[0] = 0;
3696 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003697 palette_y_mode_ctx +=
3698 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003700 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003701#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003702
3703 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3704 x->use_default_intra_tx_type = 1;
3705 else
3706 x->use_default_intra_tx_type = 0;
3707
3708 /* Y Search for intra prediction mode */
3709 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003710 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003711 int this_rate, this_rate_tokenonly, s;
3712 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003713 if (mode_idx == FINAL_MODE_SEARCH) {
3714 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003715 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003716 x->use_default_intra_tx_type = 0;
3717 } else {
hui sude0c70a2017-01-09 17:12:17 -08003718 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003720#if CONFIG_PVQ
3721 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003722#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003724 mbmi->angle_delta[0] = 0;
3725#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003726 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003727 if (best_model_rd != INT64_MAX &&
3728 this_model_rd > best_model_rd + (best_model_rd >> 1))
3729 continue;
3730 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3731#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003732 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3733 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003735 this_rd_stats.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -08003736 this_rd = rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats,
3737 bsize, bmode_costs[mbmi->mode], best_rd,
3738 &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003739 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003740 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003741 }
3742#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003743 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003744#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003745 this_rate_tokenonly = this_rd_stats.rate;
3746 this_distortion = this_rd_stats.dist;
3747 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003748
3749 if (this_rate_tokenonly == INT_MAX) continue;
3750
hui sude0c70a2017-01-09 17:12:17 -08003751 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752
hui sude0c70a2017-01-09 17:12:17 -08003753 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003754 // super_block_yrd above includes the cost of the tx_size in the
3755 // tokenonly rate, but for intra blocks, tx_size is always coded
3756 // (prediction granularity), so we account for it in the full rate,
3757 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003758 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003759 }
Urvang Joshib100db72016-10-12 16:28:56 -07003760#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003761 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Urvang Joshi23a61112017-01-30 14:59:27 -08003762 this_rate +=
3763 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3764 [palette_y_mode_ctx],
3765 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003766#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003767#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003768 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003769 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3770#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003771#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003772 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003773 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -08003774#if CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003775 const int p_angle = mode_to_angle_map[mbmi->mode] +
3776 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07003777 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003778 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003779 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003780#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003781 this_rate += write_uniform_cost(2 * max_angle_delta + 1,
3782 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003783 }
3784#endif // CONFIG_EXT_INTRA
3785 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003786#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003787 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003788 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003789 }
hui su5db97432016-10-14 16:10:14 -07003790#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003791
3792 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003793 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003794 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003795#if CONFIG_FILTER_INTRA
3796 beat_best_rd = 1;
3797#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003798 *rate = this_rate;
3799 *rate_tokenonly = this_rate_tokenonly;
3800 *distortion = this_distortion;
3801 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003802#if CONFIG_PVQ
3803 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003804#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003805 }
3806 }
3807
Yushin Cho77bba8d2016-11-04 16:36:56 -07003808#if CONFIG_PVQ
3809 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003810#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003811
Urvang Joshib100db72016-10-12 16:28:56 -07003812#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003813 if (cpi->common.allow_screen_content_tools) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003814 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3815 bmode_costs[DC_PRED], &best_mbmi,
3816 best_palette_color_map, &best_rd, &best_model_rd,
3817 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003818 }
Urvang Joshib100db72016-10-12 16:28:56 -07003819#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003820
hui su5db97432016-10-14 16:10:14 -07003821#if CONFIG_FILTER_INTRA
3822 if (beat_best_rd) {
3823 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3824 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003825 &best_rd, &best_model_rd,
3826 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003827 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003828 }
3829 }
hui su5db97432016-10-14 16:10:14 -07003830#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831
hui sude0c70a2017-01-09 17:12:17 -08003832 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003833 return best_rd;
3834}
3835
Yue Chena1e48dc2016-08-29 17:29:33 -07003836// Return value 0: early termination triggered, no valid rd cost available;
3837// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003838static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3839 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3840 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003841 MACROBLOCKD *const xd = &x->e_mbd;
3842 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3843 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3844 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003845 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003846 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003847
3848 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003849
Jingning Han31b6a4f2017-02-23 11:05:53 -08003850#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003851 if (x->skip_chroma_rd) return is_cost_valid;
3852 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08003853#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003854
Yushin Cho77bba8d2016-11-04 16:36:56 -07003855#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003856 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003857 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3858 av1_subtract_plane(x, bsize, plane);
3859 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003860#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003861
Yushin Cho09de28b2016-06-21 14:51:23 -07003862 if (is_cost_valid) {
3863 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003864 RD_STATS pn_rd_stats;
3865 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3866 uv_tx_size, cpi->sf.use_fast_coef_costing);
3867 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003868 is_cost_valid = 0;
3869 break;
3870 }
Angie Chiang284d7772016-11-08 11:06:45 -08003871 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3872 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003873 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003874 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003875 is_cost_valid = 0;
3876 break;
3877 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003878 }
3879 }
3880
3881 if (!is_cost_valid) {
3882 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003883 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003884 }
3885
3886 return is_cost_valid;
3887}
3888
Yaowu Xuc27fc142016-08-22 16:08:15 -07003889#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07003890void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3891 int blk_row, int blk_col, int plane, int block,
Angie Chiangb5dda482016-11-02 16:19:58 -07003892 int plane_bsize, int coeff_ctx, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003893 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 MACROBLOCKD *xd = &x->e_mbd;
3895 const struct macroblock_plane *const p = &x->plane[plane];
3896 struct macroblockd_plane *const pd = &xd->plane[plane];
3897 int64_t tmp;
3898 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003899 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003900 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003901 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003902 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003904 int bh = block_size_high[txm_bsize];
3905 int bw = block_size_wide[txm_bsize];
3906 int txb_h = tx_size_high_unit[tx_size];
3907 int txb_w = tx_size_wide_unit[tx_size];
3908
Yaowu Xuc27fc142016-08-22 16:08:15 -07003909 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003910 uint8_t *src =
3911 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3912 uint8_t *dst =
3913 &pd->dst
3914 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuf883b422016-08-30 14:01:10 -07003915#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003916 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3917 uint8_t *rec_buffer;
3918#else
3919 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07003920#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003921 int max_blocks_high = block_size_high[plane_bsize];
3922 int max_blocks_wide = block_size_wide[plane_bsize];
3923 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003924 const int16_t *diff =
3925 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003926 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003927
3928 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929
3930 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003931 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003932 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003933 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3934
3935 max_blocks_high >>= tx_size_wide_log2[0];
3936 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937
3938#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003939 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
3940 coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003941#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003942 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003943 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003944#endif // CONFIG_NEW_QUANT
3945
Yushin Cho721868c2016-11-14 16:04:33 +09003946 // TODO(yushin) : If PVQ is enabled, this should not be called.
Angie Chiangff6d8902016-10-21 11:02:09 -07003947 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003948
3949// TODO(any): Use dist_block to compute distortion
Yaowu Xuf883b422016-08-30 14:01:10 -07003950#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3952 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003953 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003954 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 } else {
3956 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003957 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003958 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959 }
3960#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003961 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003962 0, bw, bh);
Yaowu Xuf883b422016-08-30 14:01:10 -07003963#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003964
Jingning Han9fdc4222016-10-27 21:32:19 -07003965 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003967 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3968 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003969 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003970 for (idy = 0; idy < blocks_height; ++idy) {
3971 for (idx = 0; idx < blocks_width; ++idx) {
3972 const int16_t *d =
3973 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003974 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 }
3976 }
3977 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003978 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979 }
3980
Yaowu Xuf883b422016-08-30 14:01:10 -07003981#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3983 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07003984#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003985 rd_stats->sse += tmp * 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986
3987 if (p->eobs[block] > 0) {
3988 INV_TXFM_PARAM inv_txfm_param;
3989 inv_txfm_param.tx_type = tx_type;
3990 inv_txfm_param.tx_size = tx_size;
3991 inv_txfm_param.eob = p->eobs[block];
3992 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Yushin Cho721868c2016-11-14 16:04:33 +09003993// TODO(yushin) : If PVQ is enabled, rec_buffer needs be set as zeros.
Yaowu Xuf883b422016-08-30 14:01:10 -07003994#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003995 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3996 inv_txfm_param.bd = xd->bd;
hui subb9c73b2017-03-17 15:51:02 -07003997 av1_highbd_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE,
3998 &inv_txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999 } else {
hui subb9c73b2017-03-17 15:51:02 -07004000 av1_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004001 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004002#else // CONFIG_AOM_HIGHBITDEPTH
hui subb9c73b2017-03-17 15:51:02 -07004003 av1_inv_txfm_add(dqcoeff, rec_buffer, MAX_TX_SIZE, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07004004#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004005
Jingning Han4b47c932016-11-03 09:20:08 -07004006 if (txb_w + blk_col > max_blocks_wide ||
4007 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004008 int idx, idy;
4009 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07004010 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
4011 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004012 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08004013 for (idy = 0; idy < blocks_height; ++idy) {
4014 for (idx = 0; idx < blocks_width; ++idx) {
4015 uint8_t *const s =
4016 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
4017 uint8_t *const r =
4018 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08004019 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004020 tmp += this_dist;
4021 }
4022 }
4023 } else {
4024 uint32_t this_dist;
4025 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
4026 &this_dist);
4027 tmp = this_dist;
4028 }
4029 }
Angie Chiangb5dda482016-11-02 16:19:58 -07004030 rd_stats->dist += tmp * 16;
Angie Chiangd81fdb42016-11-03 12:20:58 -07004031 txb_coeff_cost = av1_cost_coeffs(cm, x, plane, block, coeff_ctx, tx_size,
4032 scan_order->scan, scan_order->neighbors, 0);
4033 rd_stats->rate += txb_coeff_cost;
Angie Chiangb5dda482016-11-02 16:19:58 -07004034 rd_stats->skip &= (p->eobs[block] == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08004035
Angie Chiangd81fdb42016-11-03 12:20:58 -07004036#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08004037 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4038 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08004039#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040}
4041
Yaowu Xuf883b422016-08-30 14:01:10 -07004042static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08004043 int blk_col, int plane, int block, int block32,
4044 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07004045 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4046 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07004047 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004048 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004049 MACROBLOCKD *const xd = &x->e_mbd;
4050 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4051 struct macroblock_plane *const p = &x->plane[plane];
4052 struct macroblockd_plane *const pd = &xd->plane[plane];
4053 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4054 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07004055 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004056 [MAX_MIB_SIZE] =
4057 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07004058 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4059 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07004060 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004061 int64_t this_rd = INT64_MAX;
4062 ENTROPY_CONTEXT *pta = ta + blk_col;
4063 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07004065 int ctx =
4066 txfm_partition_context(tx_above + (blk_col >> 1),
4067 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004068 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004069 int tmp_eob = 0;
4070 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07004071 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08004072 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004073
Jingning Han63cbf342016-11-09 15:37:48 -08004074 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08004075
Jingning Hand3fada82016-11-22 10:46:55 -08004076 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004077
4078 if (ref_best_rd < 0) {
4079 *is_cost_valid = 0;
4080 return;
4081 }
4082
Jingning Hance059e82016-10-31 16:27:28 -07004083 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004084
Angie Chiangc0feea82016-11-03 15:36:18 -07004085 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004086
4087 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4088
Jingning Han1c019f92016-11-21 12:53:32 -08004089 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4090 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004091
4092 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4093 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004094
4095 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4096 rd_stats_stack[block32].rate != INT_MAX) {
4097 *rd_stats = rd_stats_stack[block32];
4098 p->eobs[block] = !rd_stats->skip;
4099 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4100 } else {
4101 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
4102 plane_bsize, coeff_ctx, rd_stats);
4103 if (tx_size == TX_32X32) {
4104 rd_stats_stack[block32] = *rd_stats;
4105 }
4106 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004107
Angie Chiangb5dda482016-11-02 16:19:58 -07004108 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4109 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4110 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004111 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004112#if CONFIG_RD_DEBUG
4113 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4114 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004115#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004116 rd_stats->rate = zero_blk_rate;
4117 rd_stats->dist = rd_stats->sse;
4118 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004119 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4120 p->eobs[block] = 0;
4121 } else {
4122 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004123 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004124 }
4125
Jingning Han571189c2016-10-24 10:38:43 -07004126 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004127 rd_stats->rate +=
4128 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4129 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004130 tmp_eob = p->eobs[block];
4131 }
4132
Jingning Han571189c2016-10-24 10:38:43 -07004133 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004134 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4135 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004136 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004137 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138 int this_cost_valid = 1;
4139 int64_t tmp_rd = 0;
4140
Angie Chiangd7246172016-11-03 11:49:15 -07004141 sum_rd_stats.rate =
4142 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004143
4144 assert(tx_size < TX_SIZES_ALL);
4145
Yaowu Xuc27fc142016-08-22 16:08:15 -07004146 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004147 int offsetr = blk_row + (i >> 1) * bsl;
4148 int offsetc = blk_col + (i & 0x01) * bsl;
4149
4150 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4151
Jingning Han63cbf342016-11-09 15:37:48 -08004152 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004153 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004154 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4155 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004156
Angie Chiangc0feea82016-11-03 15:36:18 -07004157 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004158
Angie Chiangd7246172016-11-03 11:49:15 -07004159 tmp_rd =
4160 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004161 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004162 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004163 }
4164 if (this_cost_valid) sum_rd = tmp_rd;
4165 }
4166
4167 if (this_rd < sum_rd) {
4168 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004169 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4170 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004171 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004172 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004174 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4175 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004176 inter_tx_size[idy][idx] = tx_size;
4177 mbmi->tx_size = tx_size;
4178 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004179 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004181 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004182 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4183 }
4184}
4185
Angie Chiangb5dda482016-11-02 16:19:58 -07004186static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4187 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004188 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 MACROBLOCKD *const xd = &x->e_mbd;
4190 int is_cost_valid = 1;
4191 int64_t this_rd = 0;
4192
4193 if (ref_best_rd < 0) is_cost_valid = 0;
4194
Angie Chiangc0feea82016-11-03 15:36:18 -07004195 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004196
4197 if (is_cost_valid) {
4198 const struct macroblockd_plane *const pd = &xd->plane[0];
4199 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004200 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4201 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004202 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004203 const int bh = tx_size_high_unit[max_tx_size];
4204 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004205 int idx, idy;
4206 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004207 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004208 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4210 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4211 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4212 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4213
Angie Chiangb5dda482016-11-02 16:19:58 -07004214 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004215 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004216
Jingning Han9ca05b72017-01-03 14:41:36 -08004217 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004218 memcpy(tx_above, xd->above_txfm_context,
4219 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4220 memcpy(tx_left, xd->left_txfm_context,
4221 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4222
4223 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004224 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004225 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004226 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004227 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004228 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004229 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004230 this_rd += AOMMIN(
4231 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4232 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004233 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004234 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004235 }
4236 }
4237 }
4238
Angie Chiangb5dda482016-11-02 16:19:58 -07004239 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4240 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004241 if (this_rd > ref_best_rd) is_cost_valid = 0;
4242
4243 if (!is_cost_valid) {
4244 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004245 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004246 }
4247}
4248
Yaowu Xuf883b422016-08-30 14:01:10 -07004249static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004250 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004251 int64_t ref_best_rd, TX_TYPE tx_type,
4252 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004253 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004254 MACROBLOCKD *const xd = &x->e_mbd;
4255 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004256 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004257 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4258 int s0 = av1_cost_bit(skip_prob, 0);
4259 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004260 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004261 int row, col;
4262 const int max_blocks_high = max_block_high(xd, bsize, 0);
4263 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004264
4265 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004266 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004267 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004268
Angie Chiangb5dda482016-11-02 16:19:58 -07004269 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004270
Jingning Hane67b38a2016-11-04 10:30:00 -07004271 for (row = 0; row < max_blocks_high / 2; ++row)
4272 for (col = 0; col < max_blocks_wide / 2; ++col)
4273 mbmi->min_tx_size = AOMMIN(
4274 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4275
Yaowu Xuc27fc142016-08-22 16:08:15 -07004276#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004277 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4278 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004279 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004280 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4281 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 if (is_inter) {
4283 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004284 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004285 cpi->inter_tx_type_costs[ext_tx_set]
4286 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004287 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004288 } else {
4289 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004290 rd_stats->rate +=
4291 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4292 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004293 }
4294 }
4295#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004296 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4297 rd_stats->rate +=
4298 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004299#endif // CONFIG_EXT_TX
4300
Angie Chiangb5dda482016-11-02 16:19:58 -07004301 if (rd_stats->skip)
4302 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004303 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004304 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004305
Angie Chiangb5dda482016-11-02 16:19:58 -07004306 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4307 !(rd_stats->skip))
4308 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004309
4310 return rd;
4311}
4312
Angie Chiangb5dda482016-11-02 16:19:58 -07004313static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4314 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004315 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004316 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004317 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4318 MACROBLOCKD *const xd = &x->e_mbd;
4319 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4320 int64_t rd = INT64_MAX;
4321 int64_t best_rd = INT64_MAX;
4322 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4323 const int is_inter = is_inter_block(mbmi);
4324 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004325 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004326 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004327 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
4328 const int n4 = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004329 int idx, idy;
4330 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004331 const int count32 =
4332 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004333#if CONFIG_EXT_PARTITION
4334 RD_STATS rd_stats_stack[16];
4335#else
Jingning Han63cbf342016-11-09 15:37:48 -08004336 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004337#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004338#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004339 const int ext_tx_set =
4340 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004341#endif // CONFIG_EXT_TX
4342
4343 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4344#if CONFIG_EXT_TX
4345 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4346#else
4347 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004348#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004349
Angie Chiangc0feea82016-11-03 15:36:18 -07004350 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351
Jingning Han89d648b2016-11-22 11:22:08 -08004352 for (idx = 0; idx < count32; ++idx)
4353 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004354
Yaowu Xuc27fc142016-08-22 16:08:15 -07004355 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004356 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004357 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004358#if CONFIG_EXT_TX
4359 if (is_inter) {
4360 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4361 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4362 if (!do_tx_type_search(tx_type, prune)) continue;
4363 }
4364 } else {
4365 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4366 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4367 }
4368 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4369 }
4370#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004371 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4372 !do_tx_type_search(tx_type, prune))
4373 continue;
4374#endif // CONFIG_EXT_TX
4375 if (is_inter && x->use_default_inter_tx_type &&
4376 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4377 continue;
4378
Jingning Hane67b38a2016-11-04 10:30:00 -07004379 if (xd->lossless[mbmi->segment_id])
4380 if (tx_type != DCT_DCT) continue;
4381
Angie Chiangb5dda482016-11-02 16:19:58 -07004382 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004383 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004384
4385 if (rd < best_rd) {
4386 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004387 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004388 best_tx_type = mbmi->tx_type;
4389 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004390 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004391 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4392 for (idy = 0; idy < xd->n8_h; ++idy)
4393 for (idx = 0; idx < xd->n8_w; ++idx)
4394 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4395 }
4396 }
4397
4398 mbmi->tx_type = best_tx_type;
4399 for (idy = 0; idy < xd->n8_h; ++idy)
4400 for (idx = 0; idx < xd->n8_w; ++idx)
4401 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4402 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004403 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4405}
4406
Yaowu Xuf883b422016-08-30 14:01:10 -07004407static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004408 int blk_col, int plane, int block, TX_SIZE tx_size,
4409 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004410 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004411 MACROBLOCKD *const xd = &x->e_mbd;
4412 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4413 struct macroblock_plane *const p = &x->plane[plane];
4414 struct macroblockd_plane *const pd = &xd->plane[plane];
4415 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4416 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4417 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4418 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004419 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4420 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004421
Jingning Hand3fada82016-11-22 10:46:55 -08004422 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004423
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4425
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004426 plane_tx_size =
4427 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4428 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004429
4430 if (tx_size == plane_tx_size) {
4431 int coeff_ctx, i;
4432 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4433 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Jingning Han18482fe2016-11-02 17:01:58 -07004434 coeff_ctx = get_entropy_context(tx_size, ta, tl);
Yaowu Xuf883b422016-08-30 14:01:10 -07004435 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiangb5dda482016-11-02 16:19:58 -07004436 plane_bsize, coeff_ctx, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004437
Jingning Han58224042016-10-27 16:35:32 -07004438 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004439 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004440 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004441 tl[i] = !(p->eobs[block] == 0);
4442 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004443 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4444 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004445 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004446 int i;
4447
4448 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004449
4450 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004451 int offsetr = blk_row + (i >> 1) * bsl;
4452 int offsetc = blk_col + (i & 0x01) * bsl;
4453
4454 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4455
4456 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4457 above_ctx, left_ctx, rd_stats);
4458 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004459 }
4460 }
4461}
4462
4463// Return value 0: early termination triggered, no valid rd cost available;
4464// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004465static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4466 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4467 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004468 MACROBLOCKD *const xd = &x->e_mbd;
4469 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4470 int plane;
4471 int is_cost_valid = 1;
4472 int64_t this_rd;
4473
4474 if (ref_best_rd < 0) is_cost_valid = 0;
4475
Angie Chiangc0feea82016-11-03 15:36:18 -07004476 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004477
Jingning Han31b6a4f2017-02-23 11:05:53 -08004478#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004479 if (x->skip_chroma_rd) return is_cost_valid;
4480 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08004481#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004482
Yue Chena1e48dc2016-08-29 17:29:33 -07004483#if CONFIG_EXT_TX && CONFIG_RECT_TX
4484 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004485 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004486 }
4487#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4488
Yaowu Xuc27fc142016-08-22 16:08:15 -07004489 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004490 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004491 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004492 }
4493
Yaowu Xuc27fc142016-08-22 16:08:15 -07004494 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4495 const struct macroblockd_plane *const pd = &xd->plane[plane];
4496 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004497 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4498 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004499 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004500 const int bh = tx_size_high_unit[max_tx_size];
4501 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004502 int idx, idy;
4503 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004504 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004505 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4506 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004507 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004508 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509
Jingning Han9ca05b72017-01-03 14:41:36 -08004510 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004511
4512 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004513 for (idx = 0; idx < mi_width; idx += bw) {
4514 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004515 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516 block += step;
4517 }
4518 }
4519
Angie Chiangb5dda482016-11-02 16:19:58 -07004520 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004521 is_cost_valid = 0;
4522 break;
4523 }
4524
Angie Chiang628d7c92016-11-03 16:24:56 -07004525 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526
Angie Chiangb5dda482016-11-02 16:19:58 -07004527 this_rd =
4528 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4529 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004530
4531 if (this_rd > ref_best_rd) {
4532 is_cost_valid = 0;
4533 break;
4534 }
4535 }
4536
4537 if (!is_cost_valid) {
4538 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004539 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004540 }
4541
4542 return is_cost_valid;
4543}
4544#endif // CONFIG_VAR_TX
4545
Urvang Joshib100db72016-10-12 16:28:56 -07004546#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004547static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4548 int dc_mode_cost,
4549 uint8_t *best_palette_color_map,
4550 MB_MODE_INFO *const best_mbmi,
4551 int64_t *best_rd, int *rate,
4552 int *rate_tokenonly, int64_t *distortion,
4553 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004554 MACROBLOCKD *const xd = &x->e_mbd;
4555 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui sude0c70a2017-01-09 17:12:17 -08004556 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004558 int this_rate;
4559 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004560 int colors_u, colors_v, colors;
4561 const int src_stride = x->plane[1].src.stride;
4562 const uint8_t *const src_u = x->plane[1].src.buf;
4563 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004564 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004565 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004566 int plane_block_width, plane_block_height, rows, cols;
4567 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4568 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004569 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4570
hui su83c26632017-01-24 17:19:06 -08004571 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004572#if CONFIG_FILTER_INTRA
4573 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4574#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575
Yaowu Xuf883b422016-08-30 14:01:10 -07004576#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004578 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4579 cpi->common.bit_depth);
4580 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4581 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004582 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004583#endif // CONFIG_AOM_HIGHBITDEPTH
4584 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4585 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
4586#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004587 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004588#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004589
4590 colors = colors_u > colors_v ? colors_u : colors_v;
4591 if (colors > 1 && colors <= 64) {
4592 int r, c, n, i, j;
4593 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004594 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004595 float lb_u, ub_u, val_u;
4596 float lb_v, ub_v, val_v;
4597 float *const data = x->palette_buffer->kmeans_data_buf;
4598 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599
Yaowu Xuf883b422016-08-30 14:01:10 -07004600#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004601 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4602 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4603 if (cpi->common.use_highbitdepth) {
4604 lb_u = src_u16[0];
4605 ub_u = src_u16[0];
4606 lb_v = src_v16[0];
4607 ub_v = src_v16[0];
4608 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004609#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610 lb_u = src_u[0];
4611 ub_u = src_u[0];
4612 lb_v = src_v[0];
4613 ub_v = src_v[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07004614#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004615 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004616#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004617
Yaowu Xuc27fc142016-08-22 16:08:15 -07004618 for (r = 0; r < rows; ++r) {
4619 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004620#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004621 if (cpi->common.use_highbitdepth) {
4622 val_u = src_u16[r * src_stride + c];
4623 val_v = src_v16[r * src_stride + c];
4624 data[(r * cols + c) * 2] = val_u;
4625 data[(r * cols + c) * 2 + 1] = val_v;
4626 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004627#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004628 val_u = src_u[r * src_stride + c];
4629 val_v = src_v[r * src_stride + c];
4630 data[(r * cols + c) * 2] = val_u;
4631 data[(r * cols + c) * 2 + 1] = val_v;
Yaowu Xuf883b422016-08-30 14:01:10 -07004632#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004633 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004634#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635 if (val_u < lb_u)
4636 lb_u = val_u;
4637 else if (val_u > ub_u)
4638 ub_u = val_u;
4639 if (val_v < lb_v)
4640 lb_v = val_v;
4641 else if (val_v > ub_v)
4642 ub_v = val_v;
4643 }
4644 }
4645
4646 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4647 --n) {
4648 for (i = 0; i < n; ++i) {
4649 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4650 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4651 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004652 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004653 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4654 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004655 pmi->palette_size[1] = n;
4656 for (i = 1; i < 3; ++i) {
4657 for (j = 0; j < n; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004658#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004659 if (cpi->common.use_highbitdepth)
4660 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4661 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4662 else
Yaowu Xuf883b422016-08-30 14:01:10 -07004663#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004664 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4665 clip_pixel((int)centroids[j * 2 + i - 1]);
4666 }
4667 }
4668
Angie Chiang284d7772016-11-08 11:06:45 -08004669 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4670 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004671 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004672 tokenonly_rd_stats.rate + dc_mode_cost +
Yaowu Xuf883b422016-08-30 14:01:10 -07004673 2 * cpi->common.bit_depth * n * av1_cost_bit(128, 0) +
Alex Converse92109812017-02-22 10:21:40 -08004674 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004675 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004676 av1_cost_bit(
4677 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004678
4679 for (i = 0; i < rows; ++i) {
4680 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004681 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004682 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004683 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004684 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004685 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4686 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687 }
4688 }
4689
Angie Chiang284d7772016-11-08 11:06:45 -08004690 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004691 if (this_rd < *best_rd) {
4692 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004693 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004694 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004695 plane_block_width * plane_block_height *
4696 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004697 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004698 *distortion = tokenonly_rd_stats.dist;
4699 *rate_tokenonly = tokenonly_rd_stats.rate;
4700 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004701 }
4702 }
4703 }
hui su83c26632017-01-24 17:19:06 -08004704 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004705 memcpy(color_map, best_palette_color_map,
4706 rows * cols * sizeof(best_palette_color_map[0]));
4707 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004708}
Urvang Joshib100db72016-10-12 16:28:56 -07004709#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710
hui su5db97432016-10-14 16:10:14 -07004711#if CONFIG_FILTER_INTRA
4712// Return 1 if an filter intra mode is selected; return 0 otherwise.
4713static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4714 int *rate, int *rate_tokenonly,
4715 int64_t *distortion, int *skippable,
4716 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004717 MACROBLOCKD *const xd = &x->e_mbd;
4718 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004719 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004720 int this_rate;
4721 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004722 FILTER_INTRA_MODE mode;
4723 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004724 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004725
hui su5db97432016-10-14 16:10:14 -07004726 av1_zero(filter_intra_mode_info);
4727 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004729#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004730 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004731#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732
4733 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004734 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004735 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004736 continue;
4737
Angie Chiang284d7772016-11-08 11:06:45 -08004738 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004739 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004740 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4741 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004742 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004743 if (this_rd < *best_rd) {
4744 *best_rd = this_rd;
4745 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004746 *rate_tokenonly = tokenonly_rd_stats.rate;
4747 *distortion = tokenonly_rd_stats.dist;
4748 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004749 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4750 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004751 }
4752 }
4753
hui su5db97432016-10-14 16:10:14 -07004754 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004756 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4757 filter_intra_mode_info.use_filter_intra_mode[1];
4758 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4759 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004760 return 1;
4761 } else {
4762 return 0;
4763 }
4764}
hui su5db97432016-10-14 16:10:14 -07004765#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766
hui su5db97432016-10-14 16:10:14 -07004767#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004768// Run RD calculation with given chroma intra prediction angle., and return
4769// the RD cost. Update the best mode info. if the RD cost is the best so far.
4770static int64_t pick_intra_angle_routine_sbuv(
4771 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4772 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4773 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004774 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004775 int this_rate;
4776 int64_t this_rd;
4777 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004778
hui su45dc5972016-12-08 17:42:50 -08004779 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4780 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004781 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4782 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004783 if (this_rd < *best_rd) {
4784 *best_rd = this_rd;
4785 *best_angle_delta = mbmi->angle_delta[1];
4786 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004787 rd_stats->rate = tokenonly_rd_stats.rate;
4788 rd_stats->dist = tokenonly_rd_stats.dist;
4789 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004790 }
hui su45dc5972016-12-08 17:42:50 -08004791 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004792}
4793
hui su45dc5972016-12-08 17:42:50 -08004794// With given chroma directional intra prediction mode, pick the best angle
4795// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004796static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004797 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004798 int64_t best_rd, int *rate,
4799 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004800 MACROBLOCKD *const xd = &x->e_mbd;
4801 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su45dc5972016-12-08 17:42:50 -08004802 int i, angle_delta, best_angle_delta = 0;
4803 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA_UV + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004804
hui su45dc5972016-12-08 17:42:50 -08004805 rd_stats->rate = INT_MAX;
4806 rd_stats->skip = 0;
4807 rd_stats->dist = INT64_MAX;
4808 for (i = 0; i < 2 * (MAX_ANGLE_DELTA_UV + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004809
hui su45dc5972016-12-08 17:42:50 -08004810 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4811 for (i = 0; i < 2; ++i) {
4812 best_rd_in = (best_rd == INT64_MAX)
4813 ? INT64_MAX
4814 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4815 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4816 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4817 best_rd_in, rate, rd_stats,
4818 &best_angle_delta, &best_rd);
4819 rd_cost[2 * angle_delta + i] = this_rd;
4820 if (angle_delta == 0) {
4821 if (this_rd == INT64_MAX) return 0;
4822 rd_cost[1] = this_rd;
4823 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 }
4825 }
hui su45dc5972016-12-08 17:42:50 -08004826 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004827
hui su45dc5972016-12-08 17:42:50 -08004828 assert(best_rd != INT64_MAX);
4829 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA_UV; angle_delta += 2) {
4830 int64_t rd_thresh;
4831 for (i = 0; i < 2; ++i) {
4832 int skip_search = 0;
4833 rd_thresh = best_rd + (best_rd >> 5);
4834 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4835 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4836 skip_search = 1;
4837 if (!skip_search) {
4838 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4839 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4840 best_rd, rate, rd_stats,
4841 &best_angle_delta, &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 }
4843 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004844 }
4845
4846 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004847 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004848}
4849#endif // CONFIG_EXT_INTRA
4850
Urvang Joshi52648442016-10-13 17:27:51 -07004851static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4852 int *rate, int *rate_tokenonly,
4853 int64_t *distortion, int *skippable,
4854 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004855 MACROBLOCKD *xd = &x->e_mbd;
4856 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su83c26632017-01-24 17:19:06 -08004857 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004858 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004859 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004860 int this_rate;
4861 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004862#if CONFIG_PVQ
4863 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004864 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004865#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004866#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004867 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004868 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004869#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004870
hui su83c26632017-01-24 17:19:06 -08004871#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004872 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4873#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004874#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004875 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004876#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004877 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004878#if CONFIG_EXT_INTRA
4879 const int is_directional_mode =
4880 av1_is_directional_mode(mode, mbmi->sb_type);
4881#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004882 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4883 (1 << mode)))
4884 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885
4886 mbmi->uv_mode = mode;
4887#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004888 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004889 if (is_directional_mode) {
hui su83c26632017-01-24 17:19:06 -08004890 const int rate_overhead =
4891 cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4892 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004893 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4894 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004895 continue;
4896 } else {
hui su83c26632017-01-24 17:19:06 -08004897#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004898 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004899#if CONFIG_PVQ
4900 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004901#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004902 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004903 }
hui su83c26632017-01-24 17:19:06 -08004904#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004905 }
hui su83c26632017-01-24 17:19:06 -08004906#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004907 this_rate =
4908 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004909
4910#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004911 if (is_directional_mode) {
4912 this_rate +=
4913 write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
4914 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
4915 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004916#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004917#if CONFIG_FILTER_INTRA
4918 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4919 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4920#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004921#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004922 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4923 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004924 this_rate += av1_cost_bit(
4925 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004926#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004927
Yushin Cho77bba8d2016-11-04 16:36:56 -07004928#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004929 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004930#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004931 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004932
4933 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004934 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004935 best_rd = this_rd;
4936 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004937 *rate_tokenonly = tokenonly_rd_stats.rate;
4938 *distortion = tokenonly_rd_stats.dist;
4939 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004940 }
4941 }
4942
Urvang Joshib100db72016-10-12 16:28:56 -07004943#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004944 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4945 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004946 rd_pick_palette_intra_sbuv(cpi, x,
4947 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4948 best_palette_color_map, &best_mbmi, &best_rd,
4949 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004950 }
Urvang Joshib100db72016-10-12 16:28:56 -07004951#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004952
hui su5db97432016-10-14 16:10:14 -07004953#if CONFIG_FILTER_INTRA
4954 if (mbmi->sb_type >= BLOCK_8X8) {
4955 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004956 skippable, bsize, &best_rd))
4957 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004958 }
hui su5db97432016-10-14 16:10:14 -07004959#endif // CONFIG_FILTER_INTRA
4960
hui su83c26632017-01-24 17:19:06 -08004961 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004962 // Make sure we actually chose a mode
4963 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004964 return best_rd;
4965}
4966
Urvang Joshi52648442016-10-13 17:27:51 -07004967static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004968 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4969 TX_SIZE max_tx_size, int *rate_uv,
4970 int *rate_uv_tokenonly, int64_t *dist_uv,
4971 int *skip_uv, PREDICTION_MODE *mode_uv) {
4972 // Use an estimated rd for uv_intra based on DC_PRED if the
4973 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004974 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004975#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004976#if CONFIG_CHROMA_2X2
4977 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4978 bsize, max_tx_size);
4979#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004980 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4981 if (x->skip_chroma_rd) {
4982 *rate_uv = 0;
4983 *rate_uv_tokenonly = 0;
4984 *dist_uv = 0;
4985 *skip_uv = 1;
4986 *mode_uv = DC_PRED;
4987 return;
4988 }
Jingning Han3f167252016-06-07 16:11:42 -07004989 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4990 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004991#endif // CONFIG_CHROMA_2X2
4992#else
4993 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4994 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4995#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004996 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4997}
4998
Urvang Joshi52648442016-10-13 17:27:51 -07004999static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005000#if CONFIG_REF_MV && CONFIG_EXT_INTER
5001 int is_compound,
5002#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5003 int16_t mode_context) {
5004#if CONFIG_REF_MV
5005 int mode_cost = 0;
5006#if CONFIG_EXT_INTER
5007 int16_t mode_ctx =
5008 is_compound ? mode_context : (mode_context & NEWMV_CTX_MASK);
5009#else
5010 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
5011#endif // CONFIG_EXT_INTER
5012 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
5013
5014 assert(is_inter_mode(mode));
5015
5016#if CONFIG_EXT_INTER
5017 if (is_compound) {
clang-format55ce9e02017-02-15 22:27:12 -08005018 return cpi
5019 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 } else {
5021 if (mode == NEWMV || mode == NEWFROMNEARMV) {
5022#else
5023 if (mode == NEWMV) {
5024#endif // CONFIG_EXT_INTER
5025 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
5026#if CONFIG_EXT_INTER
5027 if (!is_compound)
5028 mode_cost += cpi->new2mv_mode_cost[mode == NEWFROMNEARMV];
5029#endif // CONFIG_EXT_INTER
5030 return mode_cost;
5031 } else {
5032 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
5033 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
5034
5035 if (is_all_zero_mv) return mode_cost;
5036
5037 if (mode == ZEROMV) {
5038 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
5039 return mode_cost;
5040 } else {
5041 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
5042 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
5043
5044 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
5045 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
5046 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
5047
5048 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
5049 return mode_cost;
5050 }
5051 }
5052#if CONFIG_EXT_INTER
5053 }
5054#endif // CONFIG_EXT_INTER
5055#else
5056 assert(is_inter_mode(mode));
5057#if CONFIG_EXT_INTER
5058 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08005059 return cpi
5060 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005061 } else {
5062#endif // CONFIG_EXT_INTER
5063 return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
5064#if CONFIG_EXT_INTER
5065 }
5066#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08005067#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005068}
5069
Sarah Parker6fdc8532016-11-16 17:47:13 -08005070#if CONFIG_EXT_INTER
5071static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
5072 COMPOUND_TYPE comp_type) {
5073 switch (comp_type) {
5074 case COMPOUND_AVERAGE: return 0;
5075 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Sarah Parker2f6ce752016-12-08 15:26:46 -08005076#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08005077 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08005078#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08005079 default: assert(0); return 0;
5080 }
5081}
5082#endif // CONFIG_EXT_INTER
5083
Sarah Parkere5299862016-08-16 14:57:37 -07005084#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005085static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08005086 static const int gm_amortization_blks[TRANS_TYPES] = {
5087 4, 6, 8, 10, 10, 10, 12
5088 };
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08005089 static const int gm_params_cost[TRANS_TYPES] = {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -08005090 GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
5091 GM_AFFINE_BITS, GM_HORTRAPEZOID_BITS, GM_VERTRAPEZOID_BITS,
5092 GM_HOMOGRAPHY_BITS,
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08005093 };
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005094 const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
Debargha Mukherjee9febfc12016-12-07 13:20:44 -08005095 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
Debargha Mukherjee705544c2016-11-22 08:55:49 -08005096 if (cpi->global_motion_used[ref][0] >= gm_amortization_blks[gm->wmtype]) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005097 return 0;
5098 } else {
5099 const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
5100 cpi->gmtype_cost[gm->wmtype];
5101 return cost / gm_amortization_blks[gm->wmtype];
5102 }
Sarah Parkere5299862016-08-16 14:57:37 -07005103}
Sarah Parkere5299862016-08-16 14:57:37 -07005104#endif // CONFIG_GLOBAL_MOTION
5105
clang-format55ce9e02017-02-15 22:27:12 -08005106static int set_and_cost_bmi_mvs(
5107 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
5108 PREDICTION_MODE mode, int_mv this_mv[2],
5109 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
5110 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08005112 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005113#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00005114 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
5115 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116 MODE_INFO *const mic = xd->mi[0];
5117 const MB_MODE_INFO *const mbmi = &mic->mbmi;
5118 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5119 int thismvcost = 0;
5120 int idx, idy;
5121 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
5122 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
5123 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005124 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00005125 (void)mi_row;
5126 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005127
5128 switch (mode) {
5129 case NEWMV:
5130#if CONFIG_EXT_INTER
5131 case NEWFROMNEARMV:
5132#endif // CONFIG_EXT_INTER
5133 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5134#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005135 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136 lower_mv_precision(&this_mv[0].as_mv, 0);
5137#endif // CONFIG_EXT_INTER
5138
5139#if CONFIG_REF_MV
5140 for (idx = 0; idx < 1 + is_compound; ++idx) {
5141 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005142 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005143 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005144 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5145 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 }
5147 (void)mvjcost;
5148 (void)mvcost;
5149#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005150 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5151 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005152#if !CONFIG_EXT_INTER
5153 if (is_compound) {
5154 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005155 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5156 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005157 }
5158#endif // !CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08005159#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005160 break;
5161 case NEARMV:
5162 case NEARESTMV:
5163 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5164 if (is_compound)
5165 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5166 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005167 case ZEROMV: {
5168 int ref;
5169 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005170#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005171 this_mv[ref].as_int =
5172 gm_get_motion_vector(
5173 &cpi->common.global_motion[mbmi->ref_frame[ref]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005174 cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005175 mi_row, i)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005176 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005177 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[ref]);
5178#else
5179 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005180#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005181 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005182 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005183 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005184#if CONFIG_EXT_INTER
5185 case NEW_NEWMV:
5186 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5187 compound_seg_newmvs[1].as_int == INVALID_MV) {
5188 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5189 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5190 } else {
5191 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5192 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5193 }
Alex Converse6317c882016-09-29 14:21:37 -07005194 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005195 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005196 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005198 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5199 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
5200 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5201 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005202 break;
5203 case NEW_NEARMV:
5204 case NEW_NEARESTMV:
5205 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005206 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005207 lower_mv_precision(&this_mv[0].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005208 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5209 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5211 break;
5212 case NEAR_NEWMV:
5213 case NEAREST_NEWMV:
5214 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5215 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005216 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005217 lower_mv_precision(&this_mv[1].as_mv, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005218 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5219 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005220 break;
5221 case NEAREST_NEARMV:
5222 case NEAR_NEARESTMV:
5223 case NEAREST_NEARESTMV:
5224 case NEAR_NEARMV:
5225 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5226 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5227 break;
5228 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005229#if CONFIG_GLOBAL_MOTION
5230 this_mv[0].as_int =
5231 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005232 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005233 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005234 .as_int;
5235 this_mv[1].as_int =
5236 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005237 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005238 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005239 .as_int;
5240 thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]) +
5241 GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
5242#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005243 this_mv[0].as_int = 0;
5244 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005245#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005246 break;
5247#endif // CONFIG_EXT_INTER
5248 default: break;
5249 }
5250
5251 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5252 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5253
5254 mic->bmi[i].as_mode = mode;
5255
5256#if CONFIG_REF_MV
5257 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005258 mic->bmi[i].pred_mv[0].as_int =
5259 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5260 if (is_compound)
5261 mic->bmi[i].pred_mv[1].as_int =
5262 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005264 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5265 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005266 }
Fergus Simpson4063a682017-02-28 16:52:22 -08005267#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005268
5269 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5270 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5271 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5272
5273#if CONFIG_REF_MV
5274#if CONFIG_EXT_INTER
5275 if (is_compound)
5276 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5277 else
5278#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005279 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5280 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005281#else // CONFIG_REF_MV
5282 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
5283#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005284#if CONFIG_REF_MV && CONFIG_EXT_INTER
5285 return cost_mv_ref(cpi, mode, is_compound, mode_ctx) + thismvcost;
5286#else
5287 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
5288#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5289}
5290
Yushin Choab44fd12017-01-09 16:06:53 -08005291static int64_t encode_inter_mb_segment_sub8x8(
5292 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5293 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5294 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005295 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005296 MACROBLOCKD *xd = &x->e_mbd;
5297 struct macroblockd_plane *const pd = &xd->plane[0];
5298 struct macroblock_plane *const p = &x->plane[0];
5299 MODE_INFO *const mi = xd->mi[0];
5300 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005301 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5302 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005303 const int width = block_size_wide[plane_bsize];
5304 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005305 int idx, idy;
5306 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005307 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005309 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310 int64_t thisdistortion = 0, thissse = 0;
5311 int thisrate = 0;
5312 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005313 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005314 const int num_4x4_w = tx_size_wide_unit[tx_size];
5315 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005316#if !CONFIG_PVQ
5317 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5318#else
5319 (void)cpi;
5320 (void)ta;
5321 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005322 (void)tx_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08005323#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005324
5325#if CONFIG_EXT_TX && CONFIG_RECT_TX
5326 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5327 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5328 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5329#else
5330 assert(tx_size == TX_4X4);
5331#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005332
Yaowu Xuc27fc142016-08-22 16:08:15 -07005333 assert(tx_type == DCT_DCT);
5334
Yaowu Xuf883b422016-08-30 14:01:10 -07005335 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005336
Yaowu Xuf883b422016-08-30 14:01:10 -07005337#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005338 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005339 aom_highbd_subtract_block(
5340 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5341 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005342 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005343 aom_subtract_block(height, width,
5344 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005345 8, src, p->src.stride, dst, pd->dst.stride);
5346 }
5347#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005348 aom_subtract_block(height, width,
5349 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005350 8, src, p->src.stride, dst, pd->dst.stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07005351#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005352
Jingning Hanbafee8d2016-12-02 10:25:03 -08005353 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5354 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005356 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005357 const int k = i + (idy * 2 + idx);
5358 const int block = av1_raster_order_to_block_index(tx_size, k);
5359 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5360 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005361 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Yushin Cho38395482017-01-03 13:10:41 -08005362#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005363#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005364 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5365 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005366#else
Angie Chiangff6d8902016-10-21 11:02:09 -07005367 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005368 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005369#endif // CONFIG_NEW_QUANT
5370 if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
Angie Chiangff6d8902016-10-21 11:02:09 -07005371 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho77bba8d2016-11-04 16:36:56 -07005372#else
Yushin Cho38395482017-01-03 13:10:41 -08005373 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
5374 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Fergus Simpson4063a682017-02-28 16:52:22 -08005375#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376 dist_block(cpi, x, 0, block, idy + (i >> 1), idx + (i & 0x1), tx_size,
5377 &dist, &ssz);
5378 thisdistortion += dist;
5379 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005380#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005381 thisrate +=
Angie Chiang22ba7512016-10-20 17:10:33 -07005382 av1_cost_coeffs(cm, x, 0, block, coeff_ctx, tx_size, scan_order->scan,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005383 scan_order->neighbors, cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005384 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5385 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005386#else
5387 thisrate += x->rate;
5388 *(ta + (k & 1)) = !x->pvq_skip[0];
5389 *(tl + (k >> 1)) = !x->pvq_skip[0];
Fergus Simpson4063a682017-02-28 16:52:22 -08005390#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005391#if CONFIG_EXT_TX
5392 if (tx_size == TX_8X4) {
5393 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5394 }
5395 if (tx_size == TX_4X8) {
5396 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5397 }
5398#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5400 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005401 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005402 if (rd >= best_yrd) return INT64_MAX;
5403 }
5404 }
5405
5406 *distortion = thisdistortion;
5407 *labelyrate = thisrate;
5408 *sse = thissse;
5409
5410 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5411}
5412
5413typedef struct {
5414 int eobs;
5415 int brate;
5416 int byrate;
5417 int64_t bdist;
5418 int64_t bsse;
5419 int64_t brdcost;
5420 int_mv mvs[2];
5421#if CONFIG_REF_MV
5422 int_mv pred_mv[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005423#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005424#if CONFIG_EXT_INTER
5425 int_mv ref_mv[2];
5426#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005427
5428#if CONFIG_CB4X4
5429 ENTROPY_CONTEXT ta[4];
5430 ENTROPY_CONTEXT tl[4];
5431#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005432 ENTROPY_CONTEXT ta[2];
5433 ENTROPY_CONTEXT tl[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005434#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005435} SEG_RDSTAT;
5436
5437typedef struct {
5438 int_mv *ref_mv[2];
5439 int_mv mvp;
5440
5441 int64_t segment_rd;
5442 int r;
5443 int64_t d;
5444 int64_t sse;
5445 int segment_yrate;
5446 PREDICTION_MODE modes[4];
5447#if CONFIG_EXT_INTER
5448 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5449#else
5450 SEG_RDSTAT rdstat[4][INTER_MODES];
5451#endif // CONFIG_EXT_INTER
5452 int mvthresh;
5453} BEST_SEG_INFO;
5454
5455static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
5456 return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
5457 (mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
5458}
5459
5460static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5461 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5462 struct macroblock_plane *const p = &x->plane[0];
5463 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5464
5465 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005466 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005467 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5468 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005469 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005470 if (has_second_ref(mbmi))
5471 pd->pre[1].buf =
5472 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005473 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005474}
5475
5476static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5477 struct buf_2d orig_pre[2]) {
5478 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5479 x->plane[0].src = orig_src;
5480 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5481 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5482}
5483
5484// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5485// TODO(aconverse): Find out if this is still productive then clean up or remove
5486static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005487 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005488#if CONFIG_REF_MV && CONFIG_EXT_INTER
5489 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
5490#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5491 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005492 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5493 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005494 int_mv zeromv[2];
5495 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5496 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005497 (void)mi_row;
5498 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005499 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5500#if CONFIG_GLOBAL_MOTION
5501 if (this_mode == ZEROMV
5502#if CONFIG_EXT_INTER
5503 || this_mode == ZERO_ZEROMV
5504#endif // CONFIG_EXT_INTER
5505 )
5506 zeromv[cur_frm].as_int =
5507 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005508 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005509 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005510 .as_int;
5511 else
5512#endif // CONFIG_GLOBAL_MOTION
5513 zeromv[cur_frm].as_int = 0;
5514 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005515#if !CONFIG_EXT_INTER
5516 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005517#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005519 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005520 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005521 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005522#if CONFIG_REF_MV
5523 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005524 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525#else
5526 int16_t rfc = mode_context[ref_frames[0]];
Fergus Simpson4063a682017-02-28 16:52:22 -08005527#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005528#if CONFIG_REF_MV && CONFIG_EXT_INTER
5529 int c1 = cost_mv_ref(cpi, NEARMV, ref_frames[1] > INTRA_FRAME, rfc);
5530 int c2 = cost_mv_ref(cpi, NEARESTMV, ref_frames[1] > INTRA_FRAME, rfc);
5531 int c3 = cost_mv_ref(cpi, ZEROMV, ref_frames[1] > INTRA_FRAME, rfc);
5532#else
5533 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5534 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5535 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
5536#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
5537
5538#if !CONFIG_REF_MV
5539 (void)bsize;
5540 (void)block;
Fergus Simpson4063a682017-02-28 16:52:22 -08005541#endif // !CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005542
5543 if (this_mode == NEARMV) {
5544 if (c1 > c3) return 0;
5545 } else if (this_mode == NEARESTMV) {
5546 if (c2 > c3) return 0;
5547 } else {
5548 assert(this_mode == ZEROMV);
5549 if (ref_frames[1] <= INTRA_FRAME) {
5550 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5551 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5552 return 0;
5553 } else {
5554 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5555 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5556 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5557 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5558 return 0;
5559 }
5560 }
5561 }
5562#if CONFIG_EXT_INTER
5563 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
5564 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
5565 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005566 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5567 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568#if CONFIG_REF_MV
5569 int16_t rfc = compound_mode_context[ref_frames[0]];
5570 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
5571 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
5572 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
5573 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
5574 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, 1, rfc);
5575#else
5576 int16_t rfc = mode_context[ref_frames[0]];
5577 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
5578 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5579 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
5580 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
5581 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Fergus Simpson4063a682017-02-28 16:52:22 -08005582#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583
5584 if (this_mode == NEAREST_NEARMV) {
5585 if (c1 > c3) return 0;
5586 } else if (this_mode == NEAREST_NEARESTMV) {
5587 if (c2 > c3) return 0;
5588 } else if (this_mode == NEAR_NEARESTMV) {
5589 if (c4 > c3) return 0;
5590 } else if (this_mode == NEAR_NEARMV) {
5591 if (c5 > c3) return 0;
5592 } else {
5593 assert(this_mode == ZERO_ZEROMV);
5594 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5595 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
5596 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
5597 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
5598 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
5599 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
5600 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
5601 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
5602 return 0;
5603 }
5604 }
5605#endif // CONFIG_EXT_INTER
5606 return 1;
5607}
5608
Urvang Joshi52648442016-10-13 17:27:51 -07005609static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5610 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5611 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005612#if CONFIG_EXT_INTER
5613 int_mv *ref_mv_sub8x8[2],
Fergus Simpson4063a682017-02-28 16:52:22 -08005614#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005615 int_mv single_newmv[TOTAL_REFS_PER_FRAME],
5616 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005617 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005618 const int pw = block_size_wide[bsize];
5619 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005620 MACROBLOCKD *xd = &x->e_mbd;
5621 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005622 // This function should only ever be called for compound modes
5623 assert(has_second_ref(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624 const int refs[2] = { mbmi->ref_frame[0],
5625 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
5626 int_mv ref_mv[2];
5627 int ite, ref;
5628#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005629 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5631 mbmi->interp_filter[3],
5632 };
5633#else
James Zern7b9407a2016-05-18 23:48:05 -07005634 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005635#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005637 struct macroblockd_plane *const pd = &xd->plane[0];
5638#if CONFIG_GLOBAL_MOTION
5639 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5640 const int ic = block & 1;
5641 const int ir = (block - ic) >> 1;
5642 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5643 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
5644 int is_global[2];
5645 for (ref = 0; ref < 2; ++ref) {
5646 WarpedMotionParams *const wm =
5647 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5648 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5649 }
5650#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651
5652 // Do joint motion search in compound mode to get more accurate mv.
5653 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5654 int last_besterr[2] = { INT_MAX, INT_MAX };
5655 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Yaowu Xuf883b422016-08-30 14:01:10 -07005656 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
5657 av1_get_scaled_ref_frame(cpi, mbmi->ref_frame[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658 };
5659
5660// Prediction buffer from second frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005661#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005662 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5663 uint8_t *second_pred;
5664#else
5665 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005666#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005667
Jingning Han61418bb2017-01-23 17:12:48 -08005668#if CONFIG_EXT_INTER && CONFIG_CB4X4
5669 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005670#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005671
Yaowu Xuc27fc142016-08-22 16:08:15 -07005672 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005673#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005674 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5675 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5676 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005677#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005678 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5679
5680 if (scaled_ref_frame[ref]) {
5681 int i;
5682 // Swap out the reference frame for a version that's been scaled to
5683 // match the resolution of the current frame, allowing the existing
5684 // motion search code to be used without additional modifications.
5685 for (i = 0; i < MAX_MB_PLANE; i++)
5686 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005687 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5688 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005689 }
5690
5691 frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
5692 }
5693
5694// Since we have scaled the reference frames to match the size of the current
5695// frame we must use a unit scaling factor during mode selection.
Yaowu Xuf883b422016-08-30 14:01:10 -07005696#if CONFIG_AOM_HIGHBITDEPTH
5697 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5698 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005699#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005700 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5701 cm->height);
5702#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005703
5704 // Allow joint search multiple times iteratively for each reference frame
5705 // and break out of the search loop if it couldn't find a better mv.
5706 for (ite = 0; ite < 4; ite++) {
5707 struct buf_2d ref_yv12[2];
5708 int bestsme = INT_MAX;
5709 int sadpb = x->sadperbit16;
5710 MV *const best_mv = &x->best_mv.as_mv;
5711 int search_range = 3;
5712
5713 int tmp_col_min = x->mv_col_min;
5714 int tmp_col_max = x->mv_col_max;
5715 int tmp_row_min = x->mv_row_min;
5716 int tmp_row_max = x->mv_row_max;
5717 int id = ite % 2; // Even iterations search in the first reference frame,
5718 // odd iterations search in the second. The predictor
5719 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005720 const int plane = 0;
5721 ConvolveParams conv_params = get_conv_params(0, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005722
5723 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005724 ref_yv12[0] = xd->plane[plane].pre[0];
5725 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726
5727#if CONFIG_DUAL_FILTER
5728 // reload the filter types
5729 interp_filter[0] =
5730 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5731 interp_filter[1] =
5732 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005733#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734
5735// Get the prediction block from the 'other' reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005736#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005737 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5738 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005739 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005740 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5741 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005742#if CONFIG_GLOBAL_MOTION
5743 is_global[!id], p_col, p_row,
5744#endif // CONFIG_GLOBAL_MOTION
5745 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005746 } else {
5747 second_pred = (uint8_t *)second_pred_alloc_16;
Angie Chiang9f45bc42017-01-13 16:27:54 -08005748 av1_build_inter_predictor(
5749 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5750 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005751#if CONFIG_GLOBAL_MOTION
5752 is_global[!id], p_col, p_row, plane, !id,
5753#endif // CONFIG_GLOBAL_MOTION
5754 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005755 }
5756#else
Angie Chiang9f45bc42017-01-13 16:27:54 -08005757 av1_build_inter_predictor(
5758 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5759 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005760#if CONFIG_GLOBAL_MOTION
5761 is_global[!id], p_col, p_row, plane, !id,
5762#endif // CONFIG_GLOBAL_MOTION
5763 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07005764#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005765
5766 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005767 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Yaowu Xuf883b422016-08-30 14:01:10 -07005768 av1_set_mv_search_range(x, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005769
5770 // Use the mv result from the single mode as mv predictor.
5771 *best_mv = frame_mv[refs[id]].as_mv;
5772
5773 best_mv->col >>= 3;
5774 best_mv->row >>= 3;
5775
5776#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005777 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08005778#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779
5780 // Small-range full-pixel motion search.
5781 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005782 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5783 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005784 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005785 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5786 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005787
5788 x->mv_col_min = tmp_col_min;
5789 x->mv_col_max = tmp_col_max;
5790 x->mv_row_min = tmp_row_min;
5791 x->mv_row_max = tmp_row_max;
5792
5793 if (bestsme < INT_MAX) {
5794 int dis; /* TODO: use dis in distortion calculation later. */
5795 unsigned int sse;
5796 if (cpi->sf.use_upsampled_references) {
5797 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005798 struct buf_2d backup_pred = pd->pre[0];
5799 const YV12_BUFFER_CONFIG *upsampled_ref =
5800 get_upsampled_ref(cpi, refs[id]);
5801
5802 // Set pred for Y plane
5803 setup_pred_plane(&pd->pre[0], upsampled_ref->y_buffer,
5804 upsampled_ref->y_crop_width,
5805 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5806 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5807 pd->subsampling_y);
5808
Jingning Han271bb2c2016-12-14 12:34:46 -08005809// If bsize < BLOCK_8X8, adjust pred pointer for this block
5810#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811 if (bsize < BLOCK_8X8)
5812 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005813 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5814 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005815 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005816#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005817
5818 bestsme = cpi->find_fractional_mv_step(
5819 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5820 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5821 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5822 &dis, &sse, second_pred, pw, ph, 1);
5823
5824 // Restore the reference frames.
5825 pd->pre[0] = backup_pred;
5826 } else {
5827 (void)block;
5828 bestsme = cpi->find_fractional_mv_step(
5829 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5830 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5831 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5832 &dis, &sse, second_pred, pw, ph, 0);
5833 }
5834 }
5835
5836 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005837 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005838
5839 if (bestsme < last_besterr[id]) {
5840 frame_mv[refs[id]].as_mv = *best_mv;
5841 last_besterr[id] = bestsme;
5842 } else {
5843 break;
5844 }
5845 }
5846
5847 *rate_mv = 0;
5848
5849 for (ref = 0; ref < 2; ++ref) {
5850 if (scaled_ref_frame[ref]) {
5851 // Restore the prediction frame pointers to their unscaled versions.
5852 int i;
5853 for (i = 0; i < MAX_MB_PLANE; i++)
5854 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5855 }
5856#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005857 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08005858#endif // CONFIG_REF_MV
Jingning Han61418bb2017-01-23 17:12:48 -08005859#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005860 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005861#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005862 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5863 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5864 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005865#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005866 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005867 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5868 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5869 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005870#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005871 }
5872}
5873
Yushin Cho482016d2017-01-06 14:06:13 -08005874static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005875 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5877 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
5878 int mvthresh,
5879#if CONFIG_EXT_INTER
5880 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME],
5881 int_mv compound_seg_newmvs[4][2],
5882#else
5883 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
5884#endif // CONFIG_EXT_INTER
5885 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5886 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
5887#if CONFIG_REF_MV
5888 int_mv tmp_ref_mv[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005889#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005890 MACROBLOCKD *xd = &x->e_mbd;
5891 MODE_INFO *mi = xd->mi[0];
5892 MB_MODE_INFO *mbmi = &mi->mbmi;
5893 int mode_idx;
5894 int k, br = 0, idx, idy;
5895 int64_t bd = 0, block_sse = 0;
5896 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005897 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005898 struct macroblock_plane *const p = &x->plane[0];
5899 struct macroblockd_plane *const pd = &xd->plane[0];
5900 const int label_count = 4;
5901 int64_t this_segment_rd = 0;
5902 int label_mv_thresh;
5903 int segmentyrate = 0;
5904 const BLOCK_SIZE bsize = mbmi->sb_type;
5905 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5906 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005907#if CONFIG_CB4X4
5908 ENTROPY_CONTEXT t_above[4], t_left[4];
5909#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005910 ENTROPY_CONTEXT t_above[2], t_left[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005911#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005912 int subpelmv = 1, have_ref = 0;
5913 const int has_second_rf = has_second_ref(mbmi);
5914 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5915 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005916#if CONFIG_PVQ
5917 od_rollback_buffer pre_buf;
5918
5919 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005920#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005921#if CONFIG_EXT_TX && CONFIG_RECT_TX
5922 mbmi->tx_size =
5923 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5924#else
5925 mbmi->tx_size = TX_4X4;
5926#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5927
Yaowu Xuf883b422016-08-30 14:01:10 -07005928 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005929
5930 bsi->segment_rd = best_rd;
5931 bsi->ref_mv[0] = best_ref_mv;
5932 bsi->ref_mv[1] = second_best_ref_mv;
5933 bsi->mvp.as_int = best_ref_mv->as_int;
5934 bsi->mvthresh = mvthresh;
5935
5936 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5937
Sebastien Alaiwand16a8362017-03-09 14:14:40 +01005938#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005939 for (idx = 0; idx < 4; ++idx) {
5940 for (k = NEARESTMV; k <= NEWMV; ++k) {
5941 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5942 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5943
5944 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5945 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5946 }
5947 }
Sebastien Alaiwand16a8362017-03-09 14:14:40 +01005948#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005949
5950 memcpy(t_above, pd->above_context, sizeof(t_above));
5951 memcpy(t_left, pd->left_context, sizeof(t_left));
5952
5953 // 64 makes this threshold really big effectively
5954 // making it so that we very rarely check mvs on
5955 // segments. setting this to 1 would make mv thresh
5956 // roughly equal to what it is for macroblocks
5957 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5958
5959 // Segmentation method overheads
5960 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5961 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5962 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5963 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5964 int_mv mode_mv[MB_MODE_COUNT][2];
5965 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5966 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005967 int64_t new_best_rd = INT64_MAX;
5968 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005969 int ref;
5970#if CONFIG_REF_MV
5971 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5972 uint8_t ref_mv_count[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005973#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974#if CONFIG_EXT_INTER
5975 int mv_idx;
5976 int_mv ref_mvs_sub8x8[2][2];
5977#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005978#if CONFIG_PVQ
5979 od_rollback_buffer idx_buf, post_buf;
5980 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5981 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005982#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005983
5984 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5985 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5986#if CONFIG_EXT_INTER
5987 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Yaowu Xu531d6af2017-03-07 17:48:52 -08005988 av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
5989 mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005990#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005991#if CONFIG_GLOBAL_MOTION
5992 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -08005993 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005994 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005995 mi_col, mi_row, index)
David Barkercdcac6d2016-12-01 17:04:16 +00005996 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005997#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005998 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005999#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07006000 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006001#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006002 ref_mv_stack[ref], &ref_mv_count[ref],
Fergus Simpson4063a682017-02-28 16:52:22 -08006003#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006004#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006005 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006006#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006007 &frame_mv[NEARESTMV][frame],
6008 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009
6010#if CONFIG_REF_MV
6011 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
6012 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
6013 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
6014 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
Fergus Simpson4063a682017-02-28 16:52:22 -08006015#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006016
6017#if CONFIG_EXT_INTER
6018 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
6019 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07006020 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
6021 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006022
6023 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08006024#if CONFIG_GLOBAL_MOTION
6025 frame_mv[ZERO_ZEROMV][frame].as_int =
6026 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08006027 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08006028 mi_col, mi_row, index)
Sarah Parkerc2d38712017-01-24 15:15:41 -08006029 .as_int;
6030#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07006031 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08006032#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006033 frame_mv[NEAREST_NEARESTMV][frame].as_int =
6034 frame_mv[NEARESTMV][frame].as_int;
6035
6036 if (ref == 0) {
6037 frame_mv[NEAREST_NEARMV][frame].as_int =
6038 frame_mv[NEARESTMV][frame].as_int;
6039 frame_mv[NEAR_NEARESTMV][frame].as_int =
6040 frame_mv[NEARMV][frame].as_int;
6041 frame_mv[NEAREST_NEWMV][frame].as_int =
6042 frame_mv[NEARESTMV][frame].as_int;
6043 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
6044 frame_mv[NEAR_NEARMV][frame].as_int =
6045 frame_mv[NEARMV][frame].as_int;
6046 } else if (ref == 1) {
6047 frame_mv[NEAREST_NEARMV][frame].as_int =
6048 frame_mv[NEARMV][frame].as_int;
6049 frame_mv[NEAR_NEARESTMV][frame].as_int =
6050 frame_mv[NEARESTMV][frame].as_int;
6051 frame_mv[NEW_NEARESTMV][frame].as_int =
6052 frame_mv[NEARESTMV][frame].as_int;
6053 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
6054 frame_mv[NEAR_NEARMV][frame].as_int =
6055 frame_mv[NEARMV][frame].as_int;
6056 }
6057 }
6058#endif // CONFIG_EXT_INTER
6059 }
6060
6061// search for the best motion vector on this segment
6062#if CONFIG_EXT_INTER
6063 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
6064 this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
6065 ++this_mode)
6066#else
6067 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
6068#endif // CONFIG_EXT_INTER
6069 {
6070 const struct buf_2d orig_src = x->plane[0].src;
6071 struct buf_2d orig_pre[2];
6072 // This flag controls if the motion estimation will kick off. When it
6073 // is set to a non-zero value, the encoder will force motion estimation.
6074 int run_mv_search = 0;
6075
6076 mode_idx = INTER_OFFSET(this_mode);
6077#if CONFIG_EXT_INTER
6078 mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
6079
6080 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6081 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
6082#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006083 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006084 if (!(inter_mode_mask & (1 << this_mode))) continue;
6085
6086#if CONFIG_REF_MV
6087 run_mv_search = 2;
6088#if !CONFIG_EXT_INTER
6089 if (filter_idx > 0 && this_mode == NEWMV) {
6090 BEST_SEG_INFO *ref_bsi = bsi_buf;
Urvang Joshi454280d2016-10-14 16:51:44 -07006091 SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006092
6093 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006094 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006095 ref_rdstat->mvs[0].as_int &&
6096 ref_rdstat->mvs[0].as_int != INVALID_MV)
6097 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
6098 --run_mv_search;
6099
Urvang Joshi454280d2016-10-14 16:51:44 -07006100 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006101 ref_rdstat->mvs[1].as_int &&
6102 ref_rdstat->mvs[1].as_int != INVALID_MV)
6103 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
6104 --run_mv_search;
6105 } else {
6106 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
6107 ref_rdstat->mvs[0].as_int != INVALID_MV) {
6108 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006109 seg_mvs[index][mbmi->ref_frame[0]].as_int =
6110 ref_rdstat->mvs[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006111 }
6112 }
6113
6114 if (run_mv_search != 0 && filter_idx > 1) {
6115 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07006116 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 run_mv_search = 2;
6118
6119 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006120 if (seg_mvs[index][mbmi->ref_frame[0]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006121 ref_rdstat->mvs[0].as_int &&
6122 ref_rdstat->mvs[0].as_int != INVALID_MV)
6123 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
6124 --run_mv_search;
6125
Urvang Joshi454280d2016-10-14 16:51:44 -07006126 if (seg_mvs[index][mbmi->ref_frame[1]].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006127 ref_rdstat->mvs[1].as_int &&
6128 ref_rdstat->mvs[1].as_int != INVALID_MV)
6129 if (bsi->ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
6130 --run_mv_search;
6131 } else {
6132 if (bsi->ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
6133 ref_rdstat->mvs[0].as_int != INVALID_MV) {
6134 run_mv_search = 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006135 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006136 ref_rdstat->mvs[0].as_int;
6137 }
6138 }
6139 }
6140 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006141#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006142#endif // CONFIG_REF_MV
6143
Sarah Parkere5299862016-08-16 14:57:37 -07006144#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00006145 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07006146 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00006147 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07006148#endif // CONFIG_GLOBAL_MOTION
6149
6150 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006151#if CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006152 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07006154 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00006155 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07006156 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157
6158 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07006159 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
6160 sizeof(bsi->rdstat[index][mode_idx].ta));
6161 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
6162 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006163#if CONFIG_PVQ
6164 od_encode_rollback(&x->daala_enc, &idx_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006165#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006166
6167 // motion search for newmv (single predictor case only)
6168 if (!has_second_rf &&
6169#if CONFIG_EXT_INTER
6170 have_newmv_in_inter_mode(this_mode) &&
Alex Converse6317c882016-09-29 14:21:37 -07006171 (seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006172#else
6173 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006174 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07006175 run_mv_search)
6176#endif // CONFIG_EXT_INTER
6177 ) {
6178 int step_param = 0;
6179 int bestsme = INT_MAX;
6180 int sadpb = x->sadperbit4;
6181 MV mvp_full;
6182 int max_mv;
6183 int cost_list[5];
6184 int tmp_col_min = x->mv_col_min;
6185 int tmp_col_max = x->mv_col_max;
6186 int tmp_row_min = x->mv_row_min;
6187 int tmp_row_max = x->mv_row_max;
6188
6189 /* Is the best so far sufficiently good that we cant justify doing
6190 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07006191 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193#if CONFIG_EXT_INTER
Thomas Daede6eca8352017-03-17 14:14:12 -07006194 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006195#else
6196// use previous block's result as next block's MV predictor.
6197#if !CONFIG_REF_MV
Thomas Daede6eca8352017-03-17 14:14:12 -07006198 if (index > 0) {
6199 bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
6200 if (index == 2)
6201 bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
6202 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006203#endif // !CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006204#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006205 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
6206 : AOMMAX(abs(bsi->mvp.as_mv.row),
6207 abs(bsi->mvp.as_mv.col)) >>
6208 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209
6210 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6211 // Take wtd average of the step_params based on the last frame's
6212 // max mv magnitude and the best ref mvs of the current block for
6213 // the given reference.
6214 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006215 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006216 } else {
6217 step_param = cpi->mv_step_param;
6218 }
6219
6220#if CONFIG_REF_MV
6221 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
6222 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
6223#else
6224 mvp_full.row = bsi->mvp.as_mv.row >> 3;
6225 mvp_full.col = bsi->mvp.as_mv.col >> 3;
Fergus Simpson4063a682017-02-28 16:52:22 -08006226#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227
6228 if (cpi->sf.adaptive_motion_search) {
6229 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
6230 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07006231 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006232 }
6233
6234 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07006235 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006236
Yaowu Xuf883b422016-08-30 14:01:10 -07006237 av1_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006238
6239 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6240
6241#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006242 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08006243#endif // CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07006244 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006245 cpi, x, bsize, &mvp_full, step_param, sadpb,
6246 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6247 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6248
6249 x->mv_col_min = tmp_col_min;
6250 x->mv_col_max = tmp_col_max;
6251 x->mv_row_min = tmp_row_min;
6252 x->mv_row_max = tmp_row_max;
6253
6254 if (bestsme < INT_MAX) {
6255 int distortion;
6256 if (cpi->sf.use_upsampled_references) {
6257 int best_mv_var;
6258 const int try_second =
6259 x->second_best_mv.as_int != INVALID_MV &&
6260 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006261 const int pw = block_size_wide[bsize];
6262 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006263 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264 struct buf_2d backup_pred = pd->pre[0];
6265 const YV12_BUFFER_CONFIG *upsampled_ref =
6266 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6267
6268 // Set pred for Y plane
6269 setup_pred_plane(
6270 &pd->pre[0], upsampled_ref->y_buffer,
6271 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6272 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6273 pd->subsampling_x, pd->subsampling_y);
6274
6275 // adjust pred pointer for this block
6276 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006277 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006278 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 << 3];
6280
6281 best_mv_var = cpi->find_fractional_mv_step(
6282 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6283 x->errorperbit, &cpi->fn_ptr[bsize],
6284 cpi->sf.mv.subpel_force_stop,
6285 cpi->sf.mv.subpel_iters_per_step,
6286 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6287 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
6288 1);
6289
6290 if (try_second) {
6291 int this_var;
6292 MV best_mv = x->best_mv.as_mv;
6293 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07006294 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
6295 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
6296 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
6297 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298
6299 x->best_mv = x->second_best_mv;
6300 if (x->best_mv.as_mv.row * 8 <= maxr &&
6301 x->best_mv.as_mv.row * 8 >= minr &&
6302 x->best_mv.as_mv.col * 8 <= maxc &&
6303 x->best_mv.as_mv.col * 8 >= minc) {
6304 this_var = cpi->find_fractional_mv_step(
6305 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6306 x->errorperbit, &cpi->fn_ptr[bsize],
6307 cpi->sf.mv.subpel_force_stop,
6308 cpi->sf.mv.subpel_iters_per_step,
6309 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6310 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
6311 NULL, pw, ph, 1);
6312 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6313 x->best_mv.as_mv = best_mv;
6314 }
6315 }
6316
6317 // Restore the reference frames.
6318 pd->pre[0] = backup_pred;
6319 } else {
6320 cpi->find_fractional_mv_step(
6321 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6322 x->errorperbit, &cpi->fn_ptr[bsize],
6323 cpi->sf.mv.subpel_force_stop,
6324 cpi->sf.mv.subpel_iters_per_step,
6325 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6326 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
6327 }
6328
6329// save motion search result for use in compound prediction
6330#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006331 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006332#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006333 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006334#endif // CONFIG_EXT_INTER
6335 }
6336
6337 if (cpi->sf.adaptive_motion_search)
6338 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6339
6340#if CONFIG_EXT_INTER
6341 mode_mv[this_mode][0] = x->best_mv;
6342#else
6343 mode_mv[NEWMV][0] = x->best_mv;
6344#endif // CONFIG_EXT_INTER
6345
6346 // restore src pointers
6347 mi_buf_restore(x, orig_src, orig_pre);
6348 }
6349
6350 if (has_second_rf) {
6351#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006352 if (seg_mvs[index][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6353 seg_mvs[index][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006355 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6356 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006357#endif // CONFIG_EXT_INTER
6358 continue;
6359 }
6360
6361#if CONFIG_DUAL_FILTER
6362 (void)run_mv_search;
Fergus Simpson4063a682017-02-28 16:52:22 -08006363#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364
6365 if (has_second_rf &&
6366#if CONFIG_EXT_INTER
6367 this_mode == NEW_NEWMV &&
6368#else
6369 this_mode == NEWMV &&
6370#endif // CONFIG_EXT_INTER
6371#if CONFIG_DUAL_FILTER
6372 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6373#else
6374 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
Fergus Simpson4063a682017-02-28 16:52:22 -08006375#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006376 {
6377 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006378 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6380 int rate_mv;
6381 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6382 mi_col,
6383#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006384 bsi->ref_mv, seg_mvs[index][mv_idx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006385#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006386 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006387#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006388 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006389#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006390 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006391 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006392 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006393 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6394#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006395 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006396 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006397 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006398 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6399#endif // CONFIG_EXT_INTER
6400 }
6401 // restore src pointers
6402 mi_buf_restore(x, orig_src, orig_pre);
6403 }
6404
Urvang Joshi454280d2016-10-14 16:51:44 -07006405 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6406 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006407#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006408 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006409#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006410 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006411#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006412 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006413
6414 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006415 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006416 mode_mv[this_mode][ref].as_int;
6417 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006418 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006419 mode_mv[this_mode][ref].as_int;
6420 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006421 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006422 mode_mv[this_mode][ref].as_int;
6423#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006424 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6425 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006426 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006427 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6428 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006430 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6431 mi->bmi[index].pred_mv[ref].as_int;
Fergus Simpson4063a682017-02-28 16:52:22 -08006432#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006433#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006434 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006435 bsi->ref_mv[ref]->as_int;
6436 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006437 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006438 bsi->ref_mv[ref]->as_int;
6439 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006440 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006441 bsi->ref_mv[ref]->as_int;
6442#endif // CONFIG_EXT_INTER
6443 }
6444
6445 // Trap vectors that reach beyond the UMV borders
6446 if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
6447 (has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
6448 continue;
6449
6450 if (filter_idx > 0) {
6451 BEST_SEG_INFO *ref_bsi = bsi_buf;
6452 subpelmv = 0;
6453 have_ref = 1;
6454
6455 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6456 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6457#if CONFIG_EXT_INTER
6458 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006459 have_ref &=
6460 ((mode_mv[this_mode][ref].as_int ==
6461 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6462 (bsi->ref_mv[ref]->as_int ==
6463 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006464 else
6465#endif // CONFIG_EXT_INTER
6466 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006467 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006468 }
6469
Urvang Joshi454280d2016-10-14 16:51:44 -07006470 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006471
6472 if (filter_idx > 1 && !subpelmv && !have_ref) {
6473 ref_bsi = bsi_buf + 1;
6474 have_ref = 1;
6475 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6476#if CONFIG_EXT_INTER
6477 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006478 have_ref &=
6479 ((mode_mv[this_mode][ref].as_int ==
6480 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6481 (bsi->ref_mv[ref]->as_int ==
6482 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006483 else
6484#endif // CONFIG_EXT_INTER
6485 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006486 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006487
Urvang Joshi454280d2016-10-14 16:51:44 -07006488 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006489 }
6490
6491 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006492 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006493#if CONFIG_REF_MV
Urvang Joshi454280d2016-10-14 16:51:44 -07006494 bsi->rdstat[index][mode_idx].byrate =
6495 ref_bsi->rdstat[index][mode_idx].byrate;
6496 bsi->rdstat[index][mode_idx].bdist =
6497 ref_bsi->rdstat[index][mode_idx].bdist;
6498 bsi->rdstat[index][mode_idx].bsse =
6499 ref_bsi->rdstat[index][mode_idx].bsse;
6500 bsi->rdstat[index][mode_idx].brate +=
6501 ref_bsi->rdstat[index][mode_idx].byrate;
6502 bsi->rdstat[index][mode_idx].eobs =
6503 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006504
Urvang Joshi454280d2016-10-14 16:51:44 -07006505 bsi->rdstat[index][mode_idx].brdcost =
6506 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6507 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006508
Urvang Joshi454280d2016-10-14 16:51:44 -07006509 memcpy(bsi->rdstat[index][mode_idx].ta,
6510 ref_bsi->rdstat[index][mode_idx].ta,
6511 sizeof(bsi->rdstat[index][mode_idx].ta));
6512 memcpy(bsi->rdstat[index][mode_idx].tl,
6513 ref_bsi->rdstat[index][mode_idx].tl,
6514 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006515#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006516 memcpy(&bsi->rdstat[index][mode_idx],
6517 &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
Fergus Simpson4063a682017-02-28 16:52:22 -08006518#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006519 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006520 bsi->rdstat[index + 1][mode_idx].eobs =
6521 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006522 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006523 bsi->rdstat[index + 2][mode_idx].eobs =
6524 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006525
Urvang Joshi454280d2016-10-14 16:51:44 -07006526 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006527#if CONFIG_REF_MV
6528 // If the NEWMV mode is using the same motion vector as the
6529 // NEARESTMV mode, skip the rest rate-distortion calculations
6530 // and use the inferred motion vector modes.
6531 if (this_mode == NEWMV) {
6532 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006533 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006534 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006535 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006536 bsi->ref_mv[1]->as_int)
6537 continue;
6538 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006539 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540 bsi->ref_mv[0]->as_int)
6541 continue;
6542 }
6543 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006544#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006546 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006547#if CONFIG_PVQ
6548 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006549#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006550 }
6551 continue;
6552 }
6553 }
6554
Yushin Choab44fd12017-01-09 16:06:53 -08006555 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006556 cpi, x, bsi->segment_rd - this_segment_rd, index,
6557 &bsi->rdstat[index][mode_idx].byrate,
6558 &bsi->rdstat[index][mode_idx].bdist,
6559 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6560 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006561
Urvang Joshi454280d2016-10-14 16:51:44 -07006562 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6563 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6564 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6565 bsi->rdstat[index][mode_idx].brate +=
6566 bsi->rdstat[index][mode_idx].byrate;
6567 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006568 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006569 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006570 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006571 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006572 }
6573
Urvang Joshi454280d2016-10-14 16:51:44 -07006574 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006575#if CONFIG_REF_MV
6576 // If the NEWMV mode is using the same motion vector as the
6577 // NEARESTMV mode, skip the rest rate-distortion calculations
6578 // and use the inferred motion vector modes.
6579 if (this_mode == NEWMV) {
6580 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006581 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006582 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006583 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006584 bsi->ref_mv[1]->as_int)
6585 continue;
6586 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006587 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006588 bsi->ref_mv[0]->as_int)
6589 continue;
6590 }
6591 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006592#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006593 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006594 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006595
6596#if CONFIG_PVQ
6597 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006598#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006599 }
6600 } /*for each 4x4 mode*/
6601
Urvang Joshi454280d2016-10-14 16:51:44 -07006602 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006603 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006604 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006605#if CONFIG_EXT_INTER
6606 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6607#else
6608 for (midx = 0; midx < INTER_MODES; ++midx)
6609#endif // CONFIG_EXT_INTER
6610 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6611 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006612#if CONFIG_PVQ
6613 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006614#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006615 return INT64_MAX;
6616 }
6617
6618 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006619 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6620 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006621#if CONFIG_PVQ
6622 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006623#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006624
6625#if CONFIG_EXT_INTER
6626 mv_idx = (mode_selected == NEWFROMNEARMV) ? 1 : 0;
Urvang Joshi454280d2016-10-14 16:51:44 -07006627 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006628 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006629 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006630#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006631 set_and_cost_bmi_mvs(
6632 cpi, x, xd, index, mode_selected, mode_mv[mode_selected], frame_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006633#if CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006634 seg_mvs[index][mv_idx], compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006635#else
David Barker45390c12017-02-20 14:44:40 +00006636 seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006637#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006638 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006639
Urvang Joshi454280d2016-10-14 16:51:44 -07006640 br += bsi->rdstat[index][mode_idx].brate;
6641 bd += bsi->rdstat[index][mode_idx].bdist;
6642 block_sse += bsi->rdstat[index][mode_idx].bsse;
6643 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6644 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006645
6646 if (this_segment_rd > bsi->segment_rd) {
6647 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006648 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006649#if CONFIG_EXT_INTER
6650 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6651#else
6652 for (midx = 0; midx < INTER_MODES; ++midx)
6653#endif // CONFIG_EXT_INTER
6654 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6655 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006656#if CONFIG_PVQ
6657 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006658#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006659 return INT64_MAX;
6660 }
6661 }
6662 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006663#if CONFIG_PVQ
6664 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006665#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006666
6667 bsi->r = br;
6668 bsi->d = bd;
6669 bsi->segment_yrate = segmentyrate;
6670 bsi->segment_rd = this_segment_rd;
6671 bsi->sse = block_sse;
6672
6673 // update the coding decisions
6674 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6675
Yushin Cho7a428ba2017-01-12 16:28:49 -08006676#if CONFIG_DAALA_DIST
6677 {
6678 const int src_stride = p->src.stride;
6679 const int dst_stride = pd->dst.stride;
6680 uint8_t *src = p->src.buf;
6681 uint8_t pred[8 * 8];
6682 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
6683 int use_activity_masking = 0;
6684 int qm = OD_HVS_QM;
6685#if CONFIG_PVQ
6686 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08006687#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006688
6689 for (idy = 0; idy < 2; idy += num_4x4_blocks_high)
6690 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6691 int i = idy * 2 + idx;
6692 int j, m;
6693 uint8_t *dst_init = &pd->dst.buf[(idy * dst_stride + idx) * 4];
6694
6695 av1_build_inter_predictor_sub8x8(xd, 0, i, idy, idx, mi_row, mi_col);
6696 // Save predicted pixels for use later.
6697 for (j = 0; j < num_4x4_blocks_high * 4; j++)
6698 for (m = 0; m < num_4x4_blocks_wide * 4; m++)
6699 pred[(idy * 4 + j) * 8 + idx * 4 + m] =
6700 dst_init[j * dst_stride + m];
6701
6702 // Do xform and quant to get decoded pixels.
6703 {
6704 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6705 const int txb_height = max_block_high(xd, plane_bsize, 0);
6706 int idx_, idy_;
6707
6708 for (idy_ = 0; idy_ < txb_height; idy_++) {
6709 for (idx_ = 0; idx_ < txb_width; idx_++) {
6710 int block;
6711 int coeff_ctx = 0;
6712 const tran_low_t *dqcoeff;
6713 uint16_t eob;
6714 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6715 INV_TXFM_PARAM inv_txfm_param;
6716 uint8_t *dst = dst_init + (idy_ * dst_stride + idx_) * 4;
6717
6718 block = i + (idy_ * 2 + idx_);
6719
6720 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6721 eob = p->eobs[block];
6722
6723 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
6724 BLOCK_8X8, TX_4X4, coeff_ctx, AV1_XFORM_QUANT_FP);
6725
6726 inv_txfm_param.tx_type =
6727 get_tx_type(plane_type, xd, block, TX_4X4);
6728 inv_txfm_param.tx_size = TX_4X4;
6729 inv_txfm_param.eob = eob;
6730 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
6731
6732#if CONFIG_PVQ
6733 {
6734 int i2, j2;
6735
6736 for (j2 = 0; j2 < 4; j2++)
6737 for (i2 = 0; i2 < 4; i2++) dst[j2 * dst_stride + i2] = 0;
6738 }
Fergus Simpson4063a682017-02-28 16:52:22 -08006739#endif // CONFIG_PVQ
hui subb9c73b2017-03-17 15:51:02 -07006740 av1_inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006741 }
6742 }
6743 }
6744 }
6745
6746 // Daala-defined distortion computed for 1) predicted pixels and
6747 // 2) decoded pixels of the block of 8x8 pixels
6748 bsi->sse = av1_daala_dist(src, src_stride, pred, 8, TX_8X8, qm,
6749 use_activity_masking, x->qindex)
6750 << 4;
6751
6752 bsi->d = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, TX_8X8,
6753 qm, use_activity_masking, x->qindex)
6754 << 4;
6755 }
6756#endif // CONFIG_DAALA_DIST
6757
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758 if (bsi->segment_rd > best_rd) return INT64_MAX;
6759 /* set it to the best */
6760 for (idx = 0; idx < 4; idx++) {
6761 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6762 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6763 if (has_second_ref(mbmi))
6764 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
6765#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006766 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006767 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006768 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08006769#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006770#if CONFIG_EXT_INTER
6771 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6772 if (has_second_rf)
6773 mi->bmi[idx].ref_mv[1].as_int =
6774 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6775#endif // CONFIG_EXT_INTER
6776 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6777 mi->bmi[idx].as_mode = bsi->modes[idx];
6778 }
6779
6780 /*
6781 * used to set mbmi->mv.as_int
6782 */
6783 *returntotrate = bsi->r;
6784 *returndistortion = bsi->d;
6785 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006786 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006787 *psse = bsi->sse;
6788 mbmi->mode = bsi->modes[3];
6789
6790 return bsi->segment_rd;
6791}
6792
Yaowu Xuf883b422016-08-30 14:01:10 -07006793static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006794 const MACROBLOCKD *xd, int segment_id,
6795 unsigned int *ref_costs_single,
6796 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006797 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006798 int seg_ref_active =
6799 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6800 if (seg_ref_active) {
6801 memset(ref_costs_single, 0,
6802 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6803 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6804 *comp_mode_p = 128;
6805 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006806 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6807 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006808
6809 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006810 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006811 *comp_mode_p = comp_inter_p;
6812 } else {
6813 *comp_mode_p = 128;
6814 }
6815
Yaowu Xuf883b422016-08-30 14:01:10 -07006816 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006817
6818 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006819 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6820 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006821#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006822 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6823 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6824 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006825#endif // CONFIG_EXT_REFS
6826
Yaowu Xuf883b422016-08-30 14:01:10 -07006827 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006828
6829 ref_costs_single[LAST_FRAME] =
6830#if CONFIG_EXT_REFS
6831 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6832 ref_costs_single[BWDREF_FRAME] =
6833#endif // CONFIG_EXT_REFS
6834 ref_costs_single[GOLDEN_FRAME] =
6835 ref_costs_single[ALTREF_FRAME] = base_cost;
6836
6837#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006838 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6839 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6840 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6841 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6842 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6843 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006844
Yaowu Xuf883b422016-08-30 14:01:10 -07006845 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6846 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6847 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6848 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006849
Yaowu Xuf883b422016-08-30 14:01:10 -07006850 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6851 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006852
Yaowu Xuf883b422016-08-30 14:01:10 -07006853 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6854 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006855
Yaowu Xuf883b422016-08-30 14:01:10 -07006856 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6857 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006858#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006859 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6860 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6861 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006862
Yaowu Xuf883b422016-08-30 14:01:10 -07006863 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6864 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006865#endif // CONFIG_EXT_REFS
6866 } else {
6867 ref_costs_single[LAST_FRAME] = 512;
6868#if CONFIG_EXT_REFS
6869 ref_costs_single[LAST2_FRAME] = 512;
6870 ref_costs_single[LAST3_FRAME] = 512;
6871 ref_costs_single[BWDREF_FRAME] = 512;
6872#endif // CONFIG_EXT_REFS
6873 ref_costs_single[GOLDEN_FRAME] = 512;
6874 ref_costs_single[ALTREF_FRAME] = 512;
6875 }
6876
6877 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006878 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006879#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006880 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6881 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6882 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006883#endif // CONFIG_EXT_REFS
6884
Yaowu Xuf883b422016-08-30 14:01:10 -07006885 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006886
6887 ref_costs_comp[LAST_FRAME] =
6888#if CONFIG_EXT_REFS
6889 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6890#endif // CONFIG_EXT_REFS
6891 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6892
6893#if CONFIG_EXT_REFS
6894 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6895#endif // CONFIG_EXT_REFS
6896
6897#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006898 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6899 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6900 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6901 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006902
Yaowu Xuf883b422016-08-30 14:01:10 -07006903 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6904 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006905
Yaowu Xuf883b422016-08-30 14:01:10 -07006906 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6907 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006908
6909 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6910 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006911 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6912 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006913#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006914 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6915 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006916#endif // CONFIG_EXT_REFS
6917 } else {
6918 ref_costs_comp[LAST_FRAME] = 512;
6919#if CONFIG_EXT_REFS
6920 ref_costs_comp[LAST2_FRAME] = 512;
6921 ref_costs_comp[LAST3_FRAME] = 512;
6922 ref_costs_comp[BWDREF_FRAME] = 512;
6923 ref_costs_comp[ALTREF_FRAME] = 512;
6924#endif // CONFIG_EXT_REFS
6925 ref_costs_comp[GOLDEN_FRAME] = 512;
6926 }
6927 }
6928}
6929
6930static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6931 int mode_index,
6932 int64_t comp_pred_diff[REFERENCE_MODES],
6933 int skippable) {
6934 MACROBLOCKD *const xd = &x->e_mbd;
6935
6936 // Take a snapshot of the coding context so it can be
6937 // restored if we decide to encode this way
6938 ctx->skip = x->skip;
6939 ctx->skippable = skippable;
6940 ctx->best_mode_index = mode_index;
6941 ctx->mic = *xd->mi[0];
6942 ctx->mbmi_ext = *x->mbmi_ext;
6943 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6944 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6945 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6946}
6947
clang-format55ce9e02017-02-15 22:27:12 -08006948static void setup_buffer_inter(
6949 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6950 BLOCK_SIZE block_size, int mi_row, int mi_col,
6951 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6952 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6953 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006954 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006955 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6956 MACROBLOCKD *const xd = &x->e_mbd;
6957 MODE_INFO *const mi = xd->mi[0];
6958 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6959 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6960 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6961
6962 assert(yv12 != NULL);
6963
6964 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6965 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006966 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006967
6968 // Gets an initial list of candidate vectors from neighbours and orders them
Yaowu Xuf883b422016-08-30 14:01:10 -07006969 av1_find_mv_refs(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006970 cm, xd, mi, ref_frame,
6971#if CONFIG_REF_MV
6972 &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
6973#if CONFIG_EXT_INTER
6974 mbmi_ext->compound_mode_context,
6975#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -08006976#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07006977 candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
6978
6979 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006980 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6981 &frame_nearest_mv[ref_frame],
6982 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006983
Jingning Han271bb2c2016-12-14 12:34:46 -08006984// Further refinement that is encode side only to test the top few candidates
6985// in full and choose the best as the centre point for subsequent searches.
6986// The current implementation doesn't support scaling.
6987#if CONFIG_CB4X4
6988 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6989 block_size);
6990#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006991 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6992 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6993 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006994#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006995}
6996
Urvang Joshi52648442016-10-13 17:27:51 -07006997static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6998 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006999#if CONFIG_EXT_INTER
7000 int ref_idx, int mv_idx,
7001#endif // CONFIG_EXT_INTER
7002 int *rate_mv) {
7003 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007004 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007005 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7006 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7007 int bestsme = INT_MAX;
7008 int step_param;
7009 int sadpb = x->sadperbit16;
7010 MV mvp_full;
7011#if CONFIG_EXT_INTER
7012 int ref = mbmi->ref_frame[ref_idx];
7013 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
7014#else
7015 int ref = mbmi->ref_frame[0];
7016 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7017 int ref_idx = 0;
7018#endif // CONFIG_EXT_INTER
7019
7020 int tmp_col_min = x->mv_col_min;
7021 int tmp_col_max = x->mv_col_max;
7022 int tmp_row_min = x->mv_row_min;
7023 int tmp_row_max = x->mv_row_max;
7024 int cost_list[5];
7025
7026 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007027 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007028
7029 MV pred_mv[3];
7030 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7031 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7032 pred_mv[2] = x->pred_mv[ref];
7033
Yaowu Xuc27fc142016-08-22 16:08:15 -07007034 if (scaled_ref_frame) {
7035 int i;
7036 // Swap out the reference frame for a version that's been scaled to
7037 // match the resolution of the current frame, allowing the existing
7038 // motion search code to be used without additional modifications.
7039 for (i = 0; i < MAX_MB_PLANE; i++)
7040 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7041
Yaowu Xuf883b422016-08-30 14:01:10 -07007042 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007043 }
7044
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007045 av1_set_mv_search_range(x, &ref_mv);
7046
7047#if CONFIG_REF_MV
7048 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08007049#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007050
Yaowu Xuc27fc142016-08-22 16:08:15 -07007051 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07007052 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07007053 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7054 // Take wtd average of the step_params based on the last frame's
7055 // max mv magnitude and that based on the best ref mvs of the current
7056 // block for the given reference.
7057 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007058 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007059 2;
7060 } else {
7061 step_param = cpi->mv_step_param;
7062 }
7063
7064 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
7065 int boffset =
7066 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007067 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7068 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007069 }
7070
7071 if (cpi->sf.adaptive_motion_search) {
7072 int bwl = b_width_log2_lookup[bsize];
7073 int bhl = b_height_log2_lookup[bsize];
7074 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7075
7076 if (tlevel < 5) step_param += 2;
7077
7078 // prev_mv_sad is not setup for dynamically scaled frames.
7079 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
7080 int i;
7081 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7082 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7083 x->pred_mv[ref].row = 0;
7084 x->pred_mv[ref].col = 0;
7085 x->best_mv.as_int = INVALID_MV;
7086
7087 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07007088 int j;
7089 for (j = 0; j < MAX_MB_PLANE; ++j)
7090 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007091 }
7092 return;
7093 }
7094 }
7095 }
7096 }
7097
Yaowu Xuf883b422016-08-30 14:01:10 -07007098 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007099
Yue Chene9638cc2016-10-10 12:37:54 -07007100#if CONFIG_MOTION_VAR
7101 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
7102 mvp_full = mbmi->mv[0].as_mv;
7103 else
7104#endif // CONFIG_MOTION_VAR
7105 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007106
7107 mvp_full.col >>= 3;
7108 mvp_full.row >>= 3;
7109
7110 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
7111
Yue Chene9638cc2016-10-10 12:37:54 -07007112#if CONFIG_MOTION_VAR
7113 switch (mbmi->motion_mode) {
7114 case SIMPLE_TRANSLATION:
7115#endif // CONFIG_MOTION_VAR
7116 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
7117 sadpb, cond_cost_list(cpi, cost_list),
7118 &ref_mv, INT_MAX, 1);
7119#if CONFIG_MOTION_VAR
7120 break;
7121 case OBMC_CAUSAL:
7122 bestsme = av1_obmc_full_pixel_diamond(
7123 cpi, x, &mvp_full, step_param, sadpb,
7124 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7125 &(x->best_mv.as_mv), 0);
7126 break;
7127 default: assert("Invalid motion mode!\n");
7128 }
7129#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007130
7131 x->mv_col_min = tmp_col_min;
7132 x->mv_col_max = tmp_col_max;
7133 x->mv_row_min = tmp_row_min;
7134 x->mv_row_max = tmp_row_max;
7135
7136 if (bestsme < INT_MAX) {
7137 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07007138#if CONFIG_MOTION_VAR
7139 switch (mbmi->motion_mode) {
7140 case SIMPLE_TRANSLATION:
7141#endif // CONFIG_MOTION_VAR
7142 if (cpi->sf.use_upsampled_references) {
7143 int best_mv_var;
7144 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
7145 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007146 const int pw = block_size_wide[bsize];
7147 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07007148 // Use up-sampled reference frames.
7149 struct macroblockd_plane *const pd = &xd->plane[0];
7150 struct buf_2d backup_pred = pd->pre[ref_idx];
7151 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007152
Yue Chene9638cc2016-10-10 12:37:54 -07007153 // Set pred for Y plane
7154 setup_pred_plane(
7155 &pd->pre[ref_idx], upsampled_ref->y_buffer,
7156 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
7157 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
7158 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007159
Yue Chene9638cc2016-10-10 12:37:54 -07007160 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007161 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7162 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7163 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7164 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
7165 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007166
Yue Chene9638cc2016-10-10 12:37:54 -07007167 if (try_second) {
7168 const int minc = AOMMAX(x->mv_col_min * 8, ref_mv.col - MV_MAX);
7169 const int maxc = AOMMIN(x->mv_col_max * 8, ref_mv.col + MV_MAX);
7170 const int minr = AOMMAX(x->mv_row_min * 8, ref_mv.row - MV_MAX);
7171 const int maxr = AOMMIN(x->mv_row_max * 8, ref_mv.row + MV_MAX);
7172 int this_var;
7173 MV best_mv = x->best_mv.as_mv;
7174
7175 x->best_mv = x->second_best_mv;
7176 if (x->best_mv.as_mv.row * 8 <= maxr &&
7177 x->best_mv.as_mv.row * 8 >= minr &&
7178 x->best_mv.as_mv.col * 8 <= maxc &&
7179 x->best_mv.as_mv.col * 8 >= minc) {
7180 this_var = cpi->find_fractional_mv_step(
7181 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7182 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7183 cpi->sf.mv.subpel_iters_per_step,
7184 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
7185 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
7186 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
7187 x->best_mv.as_mv = best_mv;
7188 }
7189 }
7190
7191 // Restore the reference frames.
7192 pd->pre[ref_idx] = backup_pred;
7193 } else {
7194 cpi->find_fractional_mv_step(
7195 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7196 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7197 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
7198 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
7199 0);
7200 }
7201#if CONFIG_MOTION_VAR
7202 break;
7203 case OBMC_CAUSAL:
7204 av1_find_best_obmc_sub_pixel_tree_up(
7205 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
7206 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7207 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7208 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
7209 cpi->sf.use_upsampled_references);
7210 break;
7211 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07007212 }
Yue Chene9638cc2016-10-10 12:37:54 -07007213#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007214 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007215 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
7216 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007217
Yue Chene9638cc2016-10-10 12:37:54 -07007218#if CONFIG_MOTION_VAR
7219 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
7220#else
7221 if (cpi->sf.adaptive_motion_search)
7222#endif // CONFIG_MOTION_VAR
7223 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007224
7225 if (scaled_ref_frame) {
7226 int i;
7227 for (i = 0; i < MAX_MB_PLANE; i++)
7228 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7229 }
7230}
7231
David Barkerac37fa32016-12-02 12:30:21 +00007232static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007233 int i;
7234 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007235 xd->plane[i].dst.buf = dst.plane[i];
7236 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007237 }
7238}
7239
Yaowu Xuc27fc142016-08-22 16:08:15 -07007240#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07007241static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007242 const uint8_t *mask, int mask_stride,
7243 BLOCK_SIZE bsize, int mi_row, int mi_col,
7244 int_mv *tmp_mv, int *rate_mv, int ref_idx,
7245 int mv_idx) {
7246 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007247 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007248 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7249 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7250 int bestsme = INT_MAX;
7251 int step_param;
7252 int sadpb = x->sadperbit16;
7253 MV mvp_full;
7254 int ref = mbmi->ref_frame[ref_idx];
7255 MV ref_mv = x->mbmi_ext->ref_mvs[ref][mv_idx].as_mv;
7256
7257 int tmp_col_min = x->mv_col_min;
7258 int tmp_col_max = x->mv_col_max;
7259 int tmp_row_min = x->mv_row_min;
7260 int tmp_row_max = x->mv_row_max;
7261
7262 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007263 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007264 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007265
7266 MV pred_mv[3];
7267 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7268 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7269 pred_mv[2] = x->pred_mv[ref];
7270
7271#if CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007272 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Fergus Simpson4063a682017-02-28 16:52:22 -08007273#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07007274
7275 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007276 // Swap out the reference frame for a version that's been scaled to
7277 // match the resolution of the current frame, allowing the existing
7278 // motion search code to be used without additional modifications.
7279 for (i = 0; i < MAX_MB_PLANE; i++)
7280 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7281
Yaowu Xuf883b422016-08-30 14:01:10 -07007282 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007283 }
7284
Yaowu Xuf883b422016-08-30 14:01:10 -07007285 av1_set_mv_search_range(x, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007286
7287 // Work out the size of the first step in the mv step search.
7288 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7289 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7290 // Take wtd average of the step_params based on the last frame's
7291 // max mv magnitude and that based on the best ref mvs of the current
7292 // block for the given reference.
7293 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007294 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007295 2;
7296 } else {
7297 step_param = cpi->mv_step_param;
7298 }
7299
7300 // TODO(debargha): is show_frame needed here?
7301 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7302 int boffset =
7303 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007304 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7305 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007306 }
7307
7308 if (cpi->sf.adaptive_motion_search) {
7309 int bwl = b_width_log2_lookup[bsize];
7310 int bhl = b_height_log2_lookup[bsize];
7311 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7312
7313 if (tlevel < 5) step_param += 2;
7314
7315 // prev_mv_sad is not setup for dynamically scaled frames.
7316 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007317 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7318 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7319 x->pred_mv[ref].row = 0;
7320 x->pred_mv[ref].col = 0;
7321 tmp_mv->as_int = INVALID_MV;
7322
7323 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007324 int j;
7325 for (j = 0; j < MAX_MB_PLANE; ++j)
7326 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007327 }
7328 return;
7329 }
7330 }
7331 }
7332 }
7333
7334 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7335
7336 mvp_full.col >>= 3;
7337 mvp_full.row >>= 3;
7338
Yaowu Xuf883b422016-08-30 14:01:10 -07007339 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007340 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7341 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7342 &tmp_mv->as_mv, ref_idx);
7343
7344 x->mv_col_min = tmp_col_min;
7345 x->mv_col_max = tmp_col_max;
7346 x->mv_row_min = tmp_row_min;
7347 x->mv_row_max = tmp_row_max;
7348
7349 if (bestsme < INT_MAX) {
7350 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007351 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007352 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7353 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7354 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7355 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7356 cpi->sf.use_upsampled_references);
7357 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007358 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7359 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007360
7361 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7362 x->pred_mv[ref] = tmp_mv->as_mv;
7363
7364 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007365 for (i = 0; i < MAX_MB_PLANE; i++)
7366 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7367 }
7368}
7369
Sarah Parker6fdc8532016-11-16 17:47:13 -08007370static void do_masked_motion_search_indexed(
7371 const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007372 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
7373 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int mv_idx[2],
7374 int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007375 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7376 MACROBLOCKD *xd = &x->e_mbd;
7377 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7378 BLOCK_SIZE sb_type = mbmi->sb_type;
7379 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007380 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007381
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007382 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007383
7384 if (which == 0 || which == 2)
7385 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7386 &tmp_mv[0], &rate_mv[0], 0, mv_idx[0]);
7387
7388 if (which == 1 || which == 2) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007389// get the negative mask
7390#if CONFIG_COMPOUND_SEGMENT
7391 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7392 const int h = block_size_high[bsize];
7393 mask = av1_get_compound_type_mask_inverse(
7394 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7395#else
7396 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
Fergus Simpson4063a682017-02-28 16:52:22 -08007397#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007398 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7399 &tmp_mv[1], &rate_mv[1], 1, mv_idx[1]);
7400 }
7401}
7402#endif // CONFIG_EXT_INTER
7403
7404// In some situations we want to discount tha pparent cost of a new motion
7405// vector. Where there is a subtle motion field and especially where there is
7406// low spatial complexity then it can be hard to cover the cost of a new motion
7407// vector in a single block, even if that motion vector reduces distortion.
7408// However, once established that vector may be usable through the nearest and
7409// near mv modes to reduce distortion in subsequent blocks and also improve
7410// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007411static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007412 int_mv this_mv,
7413 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7414 int ref_frame) {
7415 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7416 (this_mv.as_int != 0) &&
7417 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7418 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7419 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7420 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7421}
7422
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007423#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7424#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007425
7426// TODO(jingning): this mv clamping function should be block size dependent.
7427static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7428 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7429 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7430 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7431 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7432}
7433
7434#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007435static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007436 const BLOCK_SIZE bsize, const uint8_t *pred0,
7437 int stride0, const uint8_t *pred1, int stride1) {
7438 const struct macroblock_plane *const p = &x->plane[0];
7439 const uint8_t *src = p->src.buf;
7440 int src_stride = p->src.stride;
7441 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007442 const int bw = block_size_wide[bsize];
7443 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007444 uint32_t esq[2][4], var;
7445 int64_t tl, br;
7446
Yaowu Xuf883b422016-08-30 14:01:10 -07007447#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007448 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7449 pred0 = CONVERT_TO_BYTEPTR(pred0);
7450 pred1 = CONVERT_TO_BYTEPTR(pred1);
7451 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007452#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007453
7454 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7455 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7456 stride0, &esq[0][1]);
7457 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7458 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7459 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7460 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7461 &esq[0][3]);
7462 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7463 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7464 stride1, &esq[1][1]);
7465 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7466 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7467 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7468 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7469 &esq[1][3]);
7470 (void)var;
7471
7472 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7473 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7474 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7475 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7476 return (tl + br > 0);
7477}
7478#endif // CONFIG_EXT_INTER
7479
7480#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007481static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007482 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007483 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007484 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7485 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007486 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007487 const MACROBLOCKD *xd = &x->e_mbd;
7488 int bsl = mi_width_log2_lookup[bsize];
7489 int pred_filter_search =
7490 cpi->sf.cb_pred_filter_search
7491 ? (((mi_row + mi_col) >> bsl) +
7492 get_chessboard_index(cm->current_video_frame)) &
7493 0x1
7494 : 0;
7495 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7496 const int is_comp_pred = has_second_ref(mbmi);
7497 const int this_mode = mbmi->mode;
7498 int refs[2] = { mbmi->ref_frame[0],
7499 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007500 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007501 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007502 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7503 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7504
7505#if CONFIG_EXT_INTER
7506 if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
7507 this_mode != NEW_NEWMV) ||
7508 (af == lf))
7509#else
7510 if ((this_mode != NEWMV) || (af == lf))
7511#endif // CONFIG_EXT_INTER
7512 best_filter = af;
7513 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007514 if (is_comp_pred) {
7515 if (cpi->sf.adaptive_mode_search) {
7516#if CONFIG_EXT_INTER
7517 switch (this_mode) {
7518 case NEAREST_NEARESTMV:
7519 if (single_filter[NEARESTMV][refs[0]] ==
7520 single_filter[NEARESTMV][refs[1]])
7521 best_filter = single_filter[NEARESTMV][refs[0]];
7522 break;
7523 case NEAREST_NEARMV:
7524 if (single_filter[NEARESTMV][refs[0]] ==
7525 single_filter[NEARMV][refs[1]])
7526 best_filter = single_filter[NEARESTMV][refs[0]];
7527 break;
7528 case NEAR_NEARESTMV:
7529 if (single_filter[NEARMV][refs[0]] ==
7530 single_filter[NEARESTMV][refs[1]])
7531 best_filter = single_filter[NEARMV][refs[0]];
7532 break;
7533 case NEAR_NEARMV:
7534 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7535 best_filter = single_filter[NEARMV][refs[0]];
7536 break;
7537 case ZERO_ZEROMV:
7538 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7539 best_filter = single_filter[ZEROMV][refs[0]];
7540 break;
7541 case NEW_NEWMV:
7542 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7543 best_filter = single_filter[NEWMV][refs[0]];
7544 break;
7545 case NEAREST_NEWMV:
7546 if (single_filter[NEARESTMV][refs[0]] ==
7547 single_filter[NEWMV][refs[1]])
7548 best_filter = single_filter[NEARESTMV][refs[0]];
7549 break;
7550 case NEAR_NEWMV:
7551 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7552 best_filter = single_filter[NEARMV][refs[0]];
7553 break;
7554 case NEW_NEARESTMV:
7555 if (single_filter[NEWMV][refs[0]] ==
7556 single_filter[NEARESTMV][refs[1]])
7557 best_filter = single_filter[NEWMV][refs[0]];
7558 break;
7559 case NEW_NEARMV:
7560 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7561 best_filter = single_filter[NEWMV][refs[0]];
7562 break;
7563 default:
7564 if (single_filter[this_mode][refs[0]] ==
7565 single_filter[this_mode][refs[1]])
7566 best_filter = single_filter[this_mode][refs[0]];
7567 break;
7568 }
7569#else
7570 if (single_filter[this_mode][refs[0]] ==
7571 single_filter[this_mode][refs[1]])
7572 best_filter = single_filter[this_mode][refs[0]];
7573#endif // CONFIG_EXT_INTER
7574 }
7575 }
Angie Chiang75c22092016-10-25 12:19:16 -07007576 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7577 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007578 }
7579 return best_filter;
7580}
Fergus Simpson4063a682017-02-28 16:52:22 -08007581#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007582
7583#if CONFIG_EXT_INTER
7584// Choose the best wedge index and sign
Yaowu Xuf883b422016-08-30 14:01:10 -07007585static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007586 const BLOCK_SIZE bsize, const uint8_t *const p0,
7587 const uint8_t *const p1, int *const best_wedge_sign,
7588 int *const best_wedge_index) {
7589 const MACROBLOCKD *const xd = &x->e_mbd;
7590 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007591 const int bw = block_size_wide[bsize];
7592 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007593 const int N = bw * bh;
7594 int rate;
7595 int64_t dist;
7596 int64_t rd, best_rd = INT64_MAX;
7597 int wedge_index;
7598 int wedge_sign;
7599 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7600 const uint8_t *mask;
7601 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007602#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007603 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7604 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7605#else
7606 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007607#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007608
7609 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7610 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7611 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7612 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7613
7614 int64_t sign_limit;
7615
Yaowu Xuf883b422016-08-30 14:01:10 -07007616#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007617 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007618 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007619 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007620 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007621 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007622 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007623 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7624 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007625#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007626 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007627 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7628 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7629 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007630 }
7631
Yaowu Xuf883b422016-08-30 14:01:10 -07007632 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7633 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007634 (1 << WEDGE_WEIGHT_BITS) / 2;
7635
Jingning Han61418bb2017-01-23 17:12:48 -08007636 if (N < 64)
7637 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7638 else
7639 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007640
7641 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007642 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007643
7644 // TODO(jingning): Make sse2 functions support N = 16 case
7645 if (N < 64)
7646 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7647 else
7648 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007649
Yaowu Xuf883b422016-08-30 14:01:10 -07007650 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007651 if (N < 64)
7652 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7653 else
7654 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007655 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7656
7657 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7658 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7659
7660 if (rd < best_rd) {
7661 *best_wedge_index = wedge_index;
7662 *best_wedge_sign = wedge_sign;
7663 best_rd = rd;
7664 }
7665 }
7666
7667 return best_rd;
7668}
7669
7670// Choose the best wedge index the specified sign
7671static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007672 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007673 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7674 const int wedge_sign, int *const best_wedge_index) {
7675 const MACROBLOCKD *const xd = &x->e_mbd;
7676 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007677 const int bw = block_size_wide[bsize];
7678 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007679 const int N = bw * bh;
7680 int rate;
7681 int64_t dist;
7682 int64_t rd, best_rd = INT64_MAX;
7683 int wedge_index;
7684 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7685 const uint8_t *mask;
7686 uint64_t sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07007687#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007688 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7689 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7690#else
7691 const int bd_round = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07007692#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007693
7694 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7695 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7696
Yaowu Xuf883b422016-08-30 14:01:10 -07007697#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007698 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007699 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007700 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007701 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007702 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7703 } else // NOLINT
Yaowu Xuf883b422016-08-30 14:01:10 -07007704#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007705 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007706 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7707 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007708 }
7709
7710 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007711 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007712 if (N < 64)
7713 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7714 else
7715 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007716 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7717
7718 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7719 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7720
7721 if (rd < best_rd) {
7722 *best_wedge_index = wedge_index;
7723 best_rd = rd;
7724 }
7725 }
7726
7727 return best_rd;
7728}
7729
Yaowu Xuf883b422016-08-30 14:01:10 -07007730static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007731 const MACROBLOCK *const x,
7732 const BLOCK_SIZE bsize,
7733 const uint8_t *const p0,
7734 const uint8_t *const p1) {
7735 const MACROBLOCKD *const xd = &x->e_mbd;
7736 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007737 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007738
7739 int64_t rd;
7740 int wedge_index = -1;
7741 int wedge_sign = 0;
7742
Sarah Parker42d96102017-01-31 21:05:27 -08007743 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007744
7745 if (cpi->sf.fast_wedge_sign_estimate) {
7746 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7747 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7748 } else {
7749 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7750 }
7751
Sarah Parker6fdc8532016-11-16 17:47:13 -08007752 mbmi->interinter_compound_data.wedge_sign = wedge_sign;
7753 mbmi->interinter_compound_data.wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007754 return rd;
7755}
7756
Sarah Parker569edda2016-12-14 14:57:38 -08007757#if CONFIG_COMPOUND_SEGMENT
7758static int64_t pick_interinter_seg_mask(const AV1_COMP *const cpi,
7759 const MACROBLOCK *const x,
7760 const BLOCK_SIZE bsize,
7761 const uint8_t *const p0,
7762 const uint8_t *const p1) {
7763 const MACROBLOCKD *const xd = &x->e_mbd;
7764 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7765 const struct buf_2d *const src = &x->plane[0].src;
7766 const int bw = block_size_wide[bsize];
7767 const int bh = block_size_high[bsize];
7768 const int N = bw * bh;
7769 int rate;
7770 uint64_t sse;
7771 int64_t dist;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007772 int rd0;
7773 SEG_MASK_TYPE cur_mask_type;
7774 int64_t best_rd = INT64_MAX;
7775 SEG_MASK_TYPE best_mask_type = 0;
Sarah Parker569edda2016-12-14 14:57:38 -08007776#if CONFIG_AOM_HIGHBITDEPTH
7777 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7778 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7779#else
7780 const int bd_round = 0;
7781#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker409c0bb2017-01-04 11:29:07 -08007782 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Sarah Parker569edda2016-12-14 14:57:38 -08007783 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7784 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7785 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7786
7787#if CONFIG_AOM_HIGHBITDEPTH
7788 if (hbd) {
7789 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7790 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7791 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7792 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7793 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7794 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7795 } else // NOLINT
7796#endif // CONFIG_AOM_HIGHBITDEPTH
7797 {
7798 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7799 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7800 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7801 }
7802
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007803 // try each mask type and its inverse
7804 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007805// build mask and inverse
7806#if CONFIG_AOM_HIGHBITDEPTH
7807 if (hbd)
7808 build_compound_seg_mask_highbd(
7809 comp_data->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7810 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7811 else
7812#endif // CONFIG_AOM_HIGHBITDEPTH
7813 build_compound_seg_mask(comp_data->seg_mask, cur_mask_type, p0, bw, p1,
7814 bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007815
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007816 // compute rd for mask
7817 sse = av1_wedge_sse_from_residuals(r1, d10, comp_data->seg_mask, N);
7818 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007819
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007820 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7821 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007822
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007823 if (rd0 < best_rd) {
7824 best_mask_type = cur_mask_type;
7825 best_rd = rd0;
7826 }
7827 }
Sarah Parker569edda2016-12-14 14:57:38 -08007828
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007829 // make final mask
7830 comp_data->mask_type = best_mask_type;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007831#if CONFIG_AOM_HIGHBITDEPTH
7832 if (hbd)
7833 build_compound_seg_mask_highbd(
7834 comp_data->seg_mask, comp_data->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
7835 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7836 else
7837#endif // CONFIG_AOM_HIGHBITDEPTH
7838 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, p0, bw,
7839 p1, bw, bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007840
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007841 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007842}
7843#endif // CONFIG_COMPOUND_SEGMENT
7844
Yaowu Xuf883b422016-08-30 14:01:10 -07007845static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007846 const MACROBLOCK *const x,
7847 const BLOCK_SIZE bsize,
7848 const uint8_t *const p0,
7849 const uint8_t *const p1) {
7850 const MACROBLOCKD *const xd = &x->e_mbd;
7851 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7852
7853 int64_t rd;
7854 int wedge_index = -1;
7855
7856 assert(is_interintra_wedge_used(bsize));
7857
7858 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7859
7860 mbmi->interintra_wedge_sign = 0;
7861 mbmi->interintra_wedge_index = wedge_index;
7862 return rd;
7863}
Sarah Parker6fdc8532016-11-16 17:47:13 -08007864
7865static int interinter_compound_motion_search(const AV1_COMP *const cpi,
7866 MACROBLOCK *x,
7867 const BLOCK_SIZE bsize,
7868 const int this_mode, int mi_row,
7869 int mi_col) {
7870 const MACROBLOCKD *const xd = &x->e_mbd;
7871 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7872 int_mv tmp_mv[2];
7873 int rate_mvs[2], tmp_rate_mv = 0;
7874 if (this_mode == NEW_NEWMV) {
7875 int mv_idxs[2] = { 0, 0 };
7876 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7877 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7878 mv_idxs, 2);
7879 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7880 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7881 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7882 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
7883 int mv_idxs[2] = { 0, 0 };
7884 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7885 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7886 mv_idxs, 0);
7887 tmp_rate_mv = rate_mvs[0];
7888 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7889 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7890 int mv_idxs[2] = { 0, 0 };
7891 do_masked_motion_search_indexed(cpi, x, &mbmi->interinter_compound_data,
7892 bsize, mi_row, mi_col, tmp_mv, rate_mvs,
7893 mv_idxs, 1);
7894 tmp_rate_mv = rate_mvs[1];
7895 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7896 }
7897 return tmp_rate_mv;
7898}
7899
Sarah Parker569edda2016-12-14 14:57:38 -08007900#if CONFIG_COMPOUND_SEGMENT
7901// TODO(sarahparker) this and build_and_cost_compound_wedge can probably
7902// be combined in a refactor
7903static int64_t build_and_cost_compound_seg(
7904 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7905 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7906 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7907 int *strides, int mi_row, int mi_col) {
7908 MACROBLOCKD *xd = &x->e_mbd;
7909 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7910 int rate_sum;
7911 int64_t dist_sum;
7912 int64_t best_rd_cur = INT64_MAX;
7913 int64_t rd = INT64_MAX;
7914 int tmp_skip_txfm_sb;
7915 int64_t tmp_skip_sse_sb;
7916
7917 best_rd_cur = pick_interinter_seg_mask(cpi, x, bsize, *preds0, *preds1);
7918 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7919
Sarah Parker2e604882017-01-17 17:31:25 -08007920 if (have_newmv_in_inter_mode(this_mode) &&
7921 use_masked_motion_search(COMPOUND_SEG)) {
Sarah Parker569edda2016-12-14 14:57:38 -08007922 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7923 mi_row, mi_col);
7924 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
7925 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7926 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7927 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7928 if (rd < best_rd_cur) {
7929 best_rd_cur = rd;
7930 } else {
7931 mbmi->mv[0].as_int = cur_mv[0].as_int;
7932 mbmi->mv[1].as_int = cur_mv[1].as_int;
7933 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007934 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7935#if CONFIG_SUPERTX
7936 0, 0,
7937#endif // CONFIG_SUPERTX
7938 preds0, strides, preds1,
7939 strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007940 }
7941 av1_subtract_plane(x, bsize, 0);
7942 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7943 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7944 if (rd != INT64_MAX)
7945 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7946 best_rd_cur = rd;
7947
7948 } else {
David Barker426a9972017-01-27 11:03:11 +00007949 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7950#if CONFIG_SUPERTX
7951 0, 0,
7952#endif // CONFIG_SUPERTX
7953 preds0, strides, preds1, strides);
Sarah Parker569edda2016-12-14 14:57:38 -08007954 av1_subtract_plane(x, bsize, 0);
7955 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7956 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7957 if (rd != INT64_MAX)
7958 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7959 best_rd_cur = rd;
7960 }
7961 return best_rd_cur;
7962}
7963#endif // CONFIG_COMPOUND_SEGMENT
7964
Sarah Parker6fdc8532016-11-16 17:47:13 -08007965static int64_t build_and_cost_compound_wedge(
7966 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7967 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
David Barkerac37fa32016-12-02 12:30:21 +00007968 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7969 int *strides, int mi_row, int mi_col) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007970 MACROBLOCKD *xd = &x->e_mbd;
7971 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7972 int rate_sum;
7973 int64_t dist_sum;
7974 int64_t best_rd_cur = INT64_MAX;
7975 int64_t rd = INT64_MAX;
7976 int tmp_skip_txfm_sb;
7977 int64_t tmp_skip_sse_sb;
7978
7979 best_rd_cur = pick_interinter_wedge(cpi, x, bsize, *preds0, *preds1);
7980 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7981
Sarah Parker2e604882017-01-17 17:31:25 -08007982 if (have_newmv_in_inter_mode(this_mode) &&
7983 use_masked_motion_search(COMPOUND_WEDGE)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007984 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7985 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00007986 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007987 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7988 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7989 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007990 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007991 mbmi->mv[0].as_int = cur_mv[0].as_int;
7992 mbmi->mv[1].as_int = cur_mv[1].as_int;
7993 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007994 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7995#if CONFIG_SUPERTX
7996 0, 0,
7997#endif // CONFIG_SUPERTX
7998 preds0, strides, preds1,
7999 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008000 }
8001 av1_subtract_plane(x, bsize, 0);
8002 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8003 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8004 if (rd != INT64_MAX)
8005 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
8006 best_rd_cur = rd;
8007
8008 } else {
David Barker426a9972017-01-27 11:03:11 +00008009 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
8010#if CONFIG_SUPERTX
8011 0, 0,
8012#endif // CONFIG_SUPERTX
8013 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008014 av1_subtract_plane(x, bsize, 0);
8015 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8016 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8017 if (rd != INT64_MAX)
8018 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
8019 best_rd_cur = rd;
8020 }
8021 return best_rd_cur;
8022}
Yaowu Xuc27fc142016-08-22 16:08:15 -07008023#endif // CONFIG_EXT_INTER
8024
Fergus Simpson073c6f32017-02-17 12:13:48 -08008025typedef struct {
8026#if CONFIG_MOTION_VAR
8027 // Inter prediction buffers and respective strides
8028 uint8_t *above_pred_buf[MAX_MB_PLANE];
8029 int above_pred_stride[MAX_MB_PLANE];
8030 uint8_t *left_pred_buf[MAX_MB_PLANE];
8031 int left_pred_stride[MAX_MB_PLANE];
8032#endif // CONFIG_MOTION_VAR
8033#if CONFIG_EXT_INTER
8034 // Pointer to array of motion vectors to use for each ref and their rates
8035 // Should point to first of 2 arrays in 2D array
8036 int_mv (*single_newmvs)[TOTAL_REFS_PER_FRAME];
8037 int (*single_newmvs_rate)[TOTAL_REFS_PER_FRAME];
8038 // Pointers costs of compound inter-intra and inter-inter predictions
8039 int *compmode_interintra_cost;
8040 int *compmode_interinter_cost;
8041 // Pointer to array of predicted rate-distortion
8042 // Should point to first of 2 arrays in 2D array
8043 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
8044#else // CONFIG_EXT_INTER
8045 // The result motion vector for each ref from the single prediction mode
8046 // it is a local variable of handle_inter_mode if CONFIG_EXT_INTER
8047 int_mv *single_newmv;
8048#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008049 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08008050} HandleInterModeArgs;
8051
Fergus Simpson45509632017-02-22 15:30:50 -08008052static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
8053 const BLOCK_SIZE bsize,
8054 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
8055 const int mi_row, const int mi_col,
8056 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008057 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08008058 const MACROBLOCKD *const xd = &x->e_mbd;
8059 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8060 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8061 const int is_comp_pred = has_second_ref(mbmi);
8062 const PREDICTION_MODE this_mode = mbmi->mode;
8063#if CONFIG_EXT_INTER
8064 const int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
8065 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
8066#endif // CONFIG_EXT_INTER
8067 int_mv *const frame_mv = mode_mv[this_mode];
8068 const int refs[2] = { mbmi->ref_frame[0],
8069 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
8070 int i;
8071
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008072 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08008073
8074 if (is_comp_pred) {
8075#if CONFIG_EXT_INTER
8076 for (i = 0; i < 2; ++i) {
8077 single_newmv[refs[i]].as_int =
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008078 args->single_newmvs[mv_idx][refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08008079 }
8080
8081 if (this_mode == NEW_NEWMV) {
8082 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8083 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8084
8085 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
8086 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
8087 single_newmv, rate_mv, 0);
8088 } else {
8089 *rate_mv = 0;
8090 for (i = 0; i < 2; ++i) {
8091#if CONFIG_REF_MV
8092 av1_set_mvcost(x, mbmi->ref_frame[i], i, mbmi->ref_mv_idx);
8093#endif // CONFIG_REF_MV
8094 *rate_mv += av1_mv_bit_cost(
8095 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
8096 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8097 }
8098 }
8099 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
8100 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8101 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
8102 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
8103 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8104 } else {
8105 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8106 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
8107 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
8108 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8109 }
8110#else
8111 // Initialize mv using single prediction mode result.
8112 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
8113 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
8114
8115 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
8116 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, single_newmv,
8117 rate_mv, 0);
8118 } else {
8119 *rate_mv = 0;
8120 for (i = 0; i < 2; ++i) {
8121#if CONFIG_REF_MV
8122 av1_set_mvcost(x, mbmi->ref_frame[i], i, mbmi->ref_mv_idx);
8123#endif // CONFIG_REF_MV
8124 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
8125 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
8126 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
8127 }
8128 }
8129#endif // CONFIG_EXT_INTER
8130 } else {
8131#if CONFIG_EXT_INTER
8132 if (is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008133 x->best_mv = args->single_newmvs[mv_idx][refs[0]];
8134 *rate_mv = args->single_newmvs_rate[mv_idx][refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08008135 } else {
8136 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, mv_idx, rate_mv);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008137 args->single_newmvs[mv_idx][refs[0]] = x->best_mv;
8138 args->single_newmvs_rate[mv_idx][refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08008139 }
8140#else
8141 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
8142 single_newmv[refs[0]] = x->best_mv;
8143#endif // CONFIG_EXT_INTER
8144
8145 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
8146
8147 frame_mv[refs[0]] = x->best_mv;
8148 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
8149
8150 // Estimate the rate implications of a new mv but discount this
8151 // under certain circumstances where we want to help initiate a weak
8152 // motion field, where the distortion gain for a single block may not
8153 // be enough to overcome the cost of a new mv.
8154 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
8155 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
8156 }
8157 }
8158
8159 return 0;
8160}
8161
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008162int64_t interpolation_filter_search(
8163 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
8164 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
8165 BUFFER_SET *const orig_dst,
8166 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
8167 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
8168 int64_t *const skip_sse_sb) {
8169 const AV1_COMMON *cm = &cpi->common;
8170 MACROBLOCKD *const xd = &x->e_mbd;
8171 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8172 int i;
8173 int tmp_rate;
8174 int64_t tmp_dist;
8175
8176 (void)single_filter;
8177
8178 InterpFilter assign_filter = SWITCHABLE;
8179
8180 if (cm->interp_filter == SWITCHABLE) {
8181#if !CONFIG_DUAL_FILTER
8182 assign_filter =
8183 predict_interp_filter(cpi, x, bsize, mi_row, mi_col, single_filter);
8184#endif // !CONFIG_DUAL_FILTER
8185 } else {
8186 assign_filter = cm->interp_filter;
8187 }
8188
8189#if CONFIG_DUAL_FILTER
8190 mbmi->interp_filter[0] =
8191 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8192 mbmi->interp_filter[1] =
8193 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8194 mbmi->interp_filter[2] =
8195 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8196 mbmi->interp_filter[3] =
8197 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8198#else
8199 mbmi->interp_filter =
8200 assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
8201#endif // CONFIG_DUAL_FILTER
8202 *switchable_rate = av1_get_switchable_rate(cpi, xd);
8203 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8204 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
8205 skip_txfm_sb, skip_sse_sb);
8206 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
8207
8208 if (assign_filter == SWITCHABLE) {
8209 // do interp_filter search
8210 if (av1_is_interp_needed(xd)) {
8211#if CONFIG_DUAL_FILTER
8212 const int filter_set_size = DUAL_FILTER_SET_SIZE;
8213#else
8214 const int filter_set_size = SWITCHABLE_FILTERS;
8215#endif // CONFIG_DUAL_FILTER
8216 int best_in_temp = 0;
8217#if CONFIG_DUAL_FILTER
8218 InterpFilter best_filter[4];
8219 av1_copy(best_filter, mbmi->interp_filter);
8220#else
8221 InterpFilter best_filter = mbmi->interp_filter;
8222#endif // CONFIG_DUAL_FILTER
8223 restore_dst_buf(xd, *tmp_dst);
8224 // EIGHTTAP_REGULAR mode is calculated beforehand
8225 for (i = 1; i < filter_set_size; ++i) {
8226 int tmp_skip_sb = 0;
8227 int64_t tmp_skip_sse = INT64_MAX;
8228 int tmp_rs;
8229 int64_t tmp_rd;
8230#if CONFIG_DUAL_FILTER
8231 mbmi->interp_filter[0] = filter_sets[i][0];
8232 mbmi->interp_filter[1] = filter_sets[i][1];
8233 mbmi->interp_filter[2] = filter_sets[i][0];
8234 mbmi->interp_filter[3] = filter_sets[i][1];
8235#else
8236 mbmi->interp_filter = (InterpFilter)i;
8237#endif // CONFIG_DUAL_FILTER
8238 tmp_rs = av1_get_switchable_rate(cpi, xd);
8239 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8240 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8241 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
8242 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
8243
8244 if (tmp_rd < *rd) {
8245 *rd = tmp_rd;
8246 *switchable_rate = av1_get_switchable_rate(cpi, xd);
8247#if CONFIG_DUAL_FILTER
8248 av1_copy(best_filter, mbmi->interp_filter);
8249#else
8250 best_filter = mbmi->interp_filter;
8251#endif // CONFIG_DUAL_FILTER
8252 *skip_txfm_sb = tmp_skip_sb;
8253 *skip_sse_sb = tmp_skip_sse;
8254 best_in_temp = !best_in_temp;
8255 if (best_in_temp) {
8256 restore_dst_buf(xd, *orig_dst);
8257 } else {
8258 restore_dst_buf(xd, *tmp_dst);
8259 }
8260 }
8261 }
8262 if (best_in_temp) {
8263 restore_dst_buf(xd, *tmp_dst);
8264 } else {
8265 restore_dst_buf(xd, *orig_dst);
8266 }
8267#if CONFIG_DUAL_FILTER
8268 av1_copy(mbmi->interp_filter, best_filter);
8269#else
8270 mbmi->interp_filter = best_filter;
8271#endif // CONFIG_DUAL_FILTER
8272 } else {
8273#if CONFIG_DUAL_FILTER
8274 for (i = 0; i < 4; ++i)
8275 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
8276#else
8277 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
8278#endif // CONFIG_DUAL_FILTER
8279 }
8280 }
8281
8282 return 0;
8283}
8284
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008285// TODO(afergs): Refactor the MBMI references in here - there's four
8286// TODO(afergs): Refactor optional args - add them to a struct or remove
8287static int64_t motion_mode_rd(
8288 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
8289 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8290 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
8291 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
8292 const int *refs, int rate_mv,
8293#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8294#if CONFIG_EXT_INTER
8295 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
8296#if CONFIG_MOTION_VAR
8297 int rate_mv_bmc,
8298#endif // CONFIG_MOTION_VAR
8299#endif // CONFIG_EXT_INTER
8300#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8301 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
8302 const AV1_COMMON *const cm = &cpi->common;
8303 MACROBLOCKD *xd = &x->e_mbd;
8304 MODE_INFO *mi = xd->mi[0];
8305 MB_MODE_INFO *mbmi = &mi->mbmi;
8306 const int is_comp_pred = has_second_ref(mbmi);
8307 const PREDICTION_MODE this_mode = mbmi->mode;
8308
8309 (void)mode_mv;
8310 (void)mi_row;
8311 (void)mi_col;
8312 (void)args;
8313 (void)refs;
8314 (void)rate_mv;
8315 (void)is_comp_pred;
8316 (void)this_mode;
8317
8318#if CONFIG_EXT_INTER && CONFIG_MOTION_VAR
8319 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
8320#endif // CONFIG_EXT_INTER && CONFIG_MOTION_VAR
8321
8322#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8323 MOTION_MODE motion_mode, last_motion_mode_allowed;
8324 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
8325 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
8326 MB_MODE_INFO base_mbmi, best_mbmi;
8327#if CONFIG_VAR_TX
8328 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
8329#endif // CONFIG_VAR_TX
8330#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8331
8332#if CONFIG_WARPED_MOTION
8333 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
8334#endif // CONFIG_WARPED_MOTION
8335
8336#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8337 av1_invalid_rd_stats(&best_rd_stats);
8338#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8339
8340 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
8341#if CONFIG_WARPED_MOTION
8342 aom_clear_system_state();
8343 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
8344#if CONFIG_EXT_INTER
8345 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
8346#endif // CONFIG_EXT_INTER
8347#endif // CONFIG_WARPED_MOTION
8348#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8349 rate2_nocoeff = rd_stats->rate;
8350 last_motion_mode_allowed = motion_mode_allowed(
8351#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8352 0, xd->global_motion,
8353#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8354 mi);
8355 base_mbmi = *mbmi;
8356#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8357
8358#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8359 int64_t best_rd = INT64_MAX;
8360 for (motion_mode = SIMPLE_TRANSLATION;
8361 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8362 int64_t tmp_rd = INT64_MAX;
8363 int tmp_rate;
8364 int64_t tmp_dist;
8365#if CONFIG_EXT_INTER
8366 int tmp_rate2 =
8367 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
8368#else
8369 int tmp_rate2 = rate2_nocoeff;
8370#endif // CONFIG_EXT_INTER
8371
8372 *mbmi = base_mbmi;
8373 mbmi->motion_mode = motion_mode;
8374#if CONFIG_MOTION_VAR
8375 if (mbmi->motion_mode == OBMC_CAUSAL) {
8376 assert_motion_mode_valid(OBMC_CAUSAL,
8377#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8378 0, cm->global_motion,
8379#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8380 mi);
8381#if CONFIG_EXT_INTER
8382 *mbmi = *best_bmc_mbmi;
8383 mbmi->motion_mode = OBMC_CAUSAL;
8384#endif // CONFIG_EXT_INTER
8385 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
8386 int tmp_rate_mv = 0;
8387
8388 single_motion_search(cpi, x, bsize, mi_row, mi_col,
8389#if CONFIG_EXT_INTER
8390 0, mv_idx,
8391#endif // CONFIG_EXT_INTER
8392 &tmp_rate_mv);
8393 mbmi->mv[0].as_int = x->best_mv.as_int;
8394 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8395 refs[0])) {
8396 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
8397 }
8398#if CONFIG_EXT_INTER
8399 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8400#else
8401 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8402#endif // CONFIG_EXT_INTER
8403#if CONFIG_DUAL_FILTER
8404 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
8405 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
8406 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
8407 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
8408#endif // CONFIG_DUAL_FILTER
8409 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8410#if CONFIG_EXT_INTER
8411 } else {
8412 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8413#endif // CONFIG_EXT_INTER
8414 }
8415 av1_build_obmc_inter_prediction(
8416 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
8417 args->left_pred_buf, args->left_pred_stride);
8418 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8419 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8420 }
8421#endif // CONFIG_MOTION_VAR
8422
8423#if CONFIG_WARPED_MOTION
8424 if (mbmi->motion_mode == WARPED_CAUSAL) {
8425 assert_motion_mode_valid(WARPED_CAUSAL,
8426#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8427 0, xd->global_motion,
8428#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8429 mi);
8430#if CONFIG_EXT_INTER
8431 *mbmi = *best_bmc_mbmi;
8432 mbmi->motion_mode = WARPED_CAUSAL;
8433#endif // CONFIG_EXT_INTER
8434 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8435#if CONFIG_DUAL_FILTER
8436 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8437 ? EIGHTTAP_REGULAR
8438 : cm->interp_filter;
8439 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8440 ? EIGHTTAP_REGULAR
8441 : cm->interp_filter;
8442#else
8443 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8444 : cm->interp_filter;
8445#endif // CONFIG_DUAL_FILTER
8446
8447 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
8448 &mbmi->wm_params[0], mi_row, mi_col) == 0) {
8449 int plane;
8450 for (plane = 0; plane < 3; ++plane) {
8451 const struct macroblockd_plane *pd = &xd->plane[plane];
8452
8453 av1_warp_plane(&mbmi->wm_params[0],
8454#if CONFIG_AOM_HIGHBITDEPTH
8455 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
8456#endif // CONFIG_AOM_HIGHBITDEPTH
8457 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
8458 pd->pre[0].stride, pd->dst.buf,
8459 (mi_col * MI_SIZE) >> pd->subsampling_x,
8460 (mi_row * MI_SIZE) >> pd->subsampling_y,
8461 (xd->n8_w * MI_SIZE) >> pd->subsampling_x,
8462 (xd->n8_h * MI_SIZE) >> pd->subsampling_y,
8463 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
8464 16, 16, 0);
8465 }
8466
8467 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8468 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8469 } else {
8470 continue;
8471 }
8472 }
8473#endif // CONFIG_WARPED_MOTION
8474 x->skip = 0;
8475
8476 rd_stats->dist = 0;
8477 rd_stats->sse = 0;
8478 rd_stats->skip = 1;
8479 rd_stats->rate = tmp_rate2;
8480 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8481#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8482 if (last_motion_mode_allowed == WARPED_CAUSAL)
8483#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8484 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8485#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8486 else
8487 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8488#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8489 }
8490#if CONFIG_WARPED_MOTION
8491 if (mbmi->motion_mode == WARPED_CAUSAL) {
8492 rd_stats->rate -= rs;
8493 }
8494#endif // CONFIG_WARPED_MOTION
8495#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8496 if (!*skip_txfm_sb) {
8497 int64_t rdcosty = INT64_MAX;
8498 int is_cost_valid_uv = 0;
8499
8500 // cost and distortion
8501 av1_subtract_plane(x, bsize, 0);
8502#if CONFIG_VAR_TX
8503 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8504 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8505 } else {
8506 int idx, idy;
8507 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8508 for (idy = 0; idy < xd->n8_h; ++idy)
8509 for (idx = 0; idx < xd->n8_w; ++idx)
8510 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8511 memset(x->blk_skip[0], rd_stats_y->skip,
8512 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8513 }
8514#else
8515 /* clang-format off */
8516 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8517/* clang-format on */
8518#endif // CONFIG_VAR_TX
8519
8520 if (rd_stats_y->rate == INT_MAX) {
8521 av1_invalid_rd_stats(rd_stats);
8522#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8523 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8524 continue;
8525 } else {
8526#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8527 restore_dst_buf(xd, *orig_dst);
8528 return INT64_MAX;
8529#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8530 }
8531#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8532 }
8533
8534 av1_merge_rd_stats(rd_stats, rd_stats_y);
8535
8536 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8537 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
8538/* clang-format off */
8539#if CONFIG_VAR_TX
8540 is_cost_valid_uv =
8541 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8542#else
8543 is_cost_valid_uv =
8544 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8545#endif // CONFIG_VAR_TX
8546 if (!is_cost_valid_uv) {
8547#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8548 continue;
8549#else
8550 restore_dst_buf(xd, *orig_dst);
8551 return INT64_MAX;
8552#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8553 }
8554 /* clang-format on */
8555 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8556#if CONFIG_RD_DEBUG
8557 // record transform block coefficient cost
8558 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8559 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8560 // here because we already collect the coefficient cost. Move this part to
8561 // other place when we need to compare non-coefficient cost.
8562 mbmi->rd_stats = *rd_stats;
8563#endif // CONFIG_RD_DEBUG
8564#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8565 if (rd_stats->skip) {
8566 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8567 rd_stats_y->rate = 0;
8568 rd_stats_uv->rate = 0;
8569 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8570 mbmi->skip = 0;
8571 // here mbmi->skip temporarily plays a role as what this_skip2 does
8572 } else if (!xd->lossless[mbmi->segment_id] &&
8573 (RDCOST(x->rdmult, x->rddiv,
8574 rd_stats_y->rate + rd_stats_uv->rate +
8575 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8576 rd_stats->dist) >=
8577 RDCOST(x->rdmult, x->rddiv,
8578 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8579 rd_stats->sse))) {
8580 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8581 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8582 rd_stats->dist = rd_stats->sse;
8583 rd_stats_y->rate = 0;
8584 rd_stats_uv->rate = 0;
8585 mbmi->skip = 1;
8586 } else {
8587 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8588 mbmi->skip = 0;
8589 }
8590 *disable_skip = 0;
8591#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8592 } else {
8593 x->skip = 1;
8594 *disable_skip = 1;
8595 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8596
8597// The cost of skip bit needs to be added.
8598#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8599 mbmi->skip = 0;
8600#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8601 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8602
8603 rd_stats->dist = *skip_sse_sb;
8604 rd_stats->sse = *skip_sse_sb;
8605 rd_stats_y->rate = 0;
8606 rd_stats_uv->rate = 0;
8607 rd_stats->skip = 1;
8608 }
8609
8610#if CONFIG_GLOBAL_MOTION
8611 if (this_mode == ZEROMV
8612#if CONFIG_EXT_INTER
8613 || this_mode == ZERO_ZEROMV
8614#endif // CONFIG_EXT_INTER
8615 ) {
8616 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
8617 if (is_comp_pred)
8618 rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
8619 if (is_nontrans_global_motion(xd)) {
8620 rd_stats->rate -= rs;
8621#if CONFIG_DUAL_FILTER
8622 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8623 ? EIGHTTAP_REGULAR
8624 : cm->interp_filter;
8625 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8626 ? EIGHTTAP_REGULAR
8627 : cm->interp_filter;
8628#else
8629 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8630 ? EIGHTTAP_REGULAR
8631 : cm->interp_filter;
8632#endif // CONFIG_DUAL_FILTER
8633 }
8634 }
8635#endif // CONFIG_GLOBAL_MOTION
8636
8637#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8638 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8639 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8640 best_mbmi = *mbmi;
8641 best_rd = tmp_rd;
8642 best_rd_stats = *rd_stats;
8643 best_rd_stats_y = *rd_stats_y;
8644 best_rd_stats_uv = *rd_stats_uv;
8645#if CONFIG_VAR_TX
8646 for (int i = 0; i < MAX_MB_PLANE; ++i)
8647 memcpy(best_blk_skip[i], x->blk_skip[i],
8648 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8649#endif // CONFIG_VAR_TX
8650 best_xskip = x->skip;
8651 best_disable_skip = *disable_skip;
8652 }
8653 }
8654
8655 if (best_rd == INT64_MAX) {
8656 av1_invalid_rd_stats(rd_stats);
8657 restore_dst_buf(xd, *orig_dst);
8658 return INT64_MAX;
8659 }
8660 *mbmi = best_mbmi;
8661 *rd_stats = best_rd_stats;
8662 *rd_stats_y = best_rd_stats_y;
8663 *rd_stats_uv = best_rd_stats_uv;
8664#if CONFIG_VAR_TX
8665 for (int i = 0; i < MAX_MB_PLANE; ++i)
8666 memcpy(x->blk_skip[i], best_blk_skip[i],
8667 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8668#endif // CONFIG_VAR_TX
8669 x->skip = best_xskip;
8670 *disable_skip = best_disable_skip;
8671#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8672
8673 restore_dst_buf(xd, *orig_dst);
8674 return 0;
8675}
8676
Yaowu Xuc27fc142016-08-22 16:08:15 -07008677static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08008678 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
8679 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008680 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008681 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008682 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008683 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008684 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008685 MODE_INFO *mi = xd->mi[0];
8686 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008687 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8688 const int is_comp_pred = has_second_ref(mbmi);
8689 const int this_mode = mbmi->mode;
8690 int_mv *frame_mv = mode_mv[this_mode];
8691 int i;
8692 int refs[2] = { mbmi->ref_frame[0],
8693 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8694 int_mv cur_mv[2];
8695 int rate_mv = 0;
8696#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008697 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008698 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008699 int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
8700 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
8701 const unsigned int *const interintra_mode_cost =
8702 cpi->interintra_mode_cost[size_group_lookup[bsize]];
8703 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
8704#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07008705 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008706#endif // CONFIG_REF_MV
8707#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008708 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008709#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008710#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008711 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8712#else
8713 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07008714#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008715 uint8_t *tmp_buf;
8716
Yue Chencb60b182016-10-13 15:18:22 -07008717#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008718#if CONFIG_EXT_INTER
8719 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008720 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008721#if CONFIG_MOTION_VAR
8722 int rate_mv_bmc;
8723#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008724#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008725#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008726 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008727 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008728 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008729
8730 int skip_txfm_sb = 0;
8731 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008732 int16_t mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008733
8734#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008735 *args->compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008736 mbmi->use_wedge_interintra = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008737 *args->compmode_interinter_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008738 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008739
8740 // is_comp_interintra_pred implies !is_comp_pred
8741 assert(!is_comp_interintra_pred || (!is_comp_pred));
8742 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8743 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8744#endif // CONFIG_EXT_INTER
8745
8746#if CONFIG_REF_MV
8747#if CONFIG_EXT_INTER
8748 if (is_comp_pred)
8749 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8750 else
8751#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008752 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8753 mbmi->ref_frame, bsize, -1);
Yaowu Xub0d0d002016-11-22 09:26:43 -08008754#else // CONFIG_REF_MV
8755 mode_ctx = mbmi_ext->mode_context[refs[0]];
8756#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07008757
Yaowu Xuf883b422016-08-30 14:01:10 -07008758#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8760 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8761 else
Yaowu Xuf883b422016-08-30 14:01:10 -07008762#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008763 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008764 // Make sure that we didn't leave the plane destination buffers set
8765 // to tmp_buf at the end of the last iteration
8766 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008767
Yue Chen69f18e12016-09-08 14:48:15 -07008768#if CONFIG_WARPED_MOTION
8769 mbmi->num_proj_ref[0] = 0;
8770 mbmi->num_proj_ref[1] = 0;
8771#endif // CONFIG_WARPED_MOTION
8772
Yaowu Xuc27fc142016-08-22 16:08:15 -07008773 if (is_comp_pred) {
8774 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8775 frame_mv[refs[1]].as_int == INVALID_MV)
8776 return INT64_MAX;
8777 }
8778
Yue Chene9638cc2016-10-10 12:37:54 -07008779 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008780 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08008781 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008782 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008783 if (ret_val != 0)
8784 return ret_val;
8785 else
8786 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008787 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008788 for (i = 0; i < is_comp_pred + 1; ++i) {
8789 cur_mv[i] = frame_mv[refs[i]];
8790// Clip "next_nearest" so that it does not extend to far out of image
8791#if CONFIG_EXT_INTER
8792 if (this_mode != NEWMV && this_mode != NEWFROMNEARMV)
8793#else
8794 if (this_mode != NEWMV)
8795#endif // CONFIG_EXT_INTER
8796 clamp_mv2(&cur_mv[i].as_mv, xd);
8797
8798 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8799 mbmi->mv[i].as_int = cur_mv[i].as_int;
8800 }
8801
8802#if CONFIG_REF_MV
8803#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008804 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008805#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008806 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008807#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008808 {
8809#if !CONFIG_EXT_INTER
8810 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008811#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008812 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8813 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8814 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8815
8816 for (i = 0; i < 2; ++i) {
8817 clamp_mv2(&cur_mv[i].as_mv, xd);
8818 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8819 mbmi->mv[i].as_int = cur_mv[i].as_int;
8820 }
8821 }
8822 }
8823
8824#if CONFIG_EXT_INTER
8825 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8826 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
8827 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8828
8829 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8830 clamp_mv2(&cur_mv[0].as_mv, xd);
8831 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8832 mbmi->mv[0].as_int = cur_mv[0].as_int;
8833 }
8834
8835 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
8836 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8837
8838 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8839 clamp_mv2(&cur_mv[1].as_mv, xd);
8840 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8841 mbmi->mv[1].as_int = cur_mv[1].as_int;
8842 }
8843 }
8844
8845 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8846 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
8847 this_mode == NEAR_NEARMV) {
8848 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
8849
8850 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8851 clamp_mv2(&cur_mv[0].as_mv, xd);
8852 if (mv_check_bounds(x, &cur_mv[0].as_mv)) return INT64_MAX;
8853 mbmi->mv[0].as_int = cur_mv[0].as_int;
8854 }
8855
8856 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
8857 this_mode == NEAR_NEARMV) {
8858 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
8859
8860 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8861 clamp_mv2(&cur_mv[1].as_mv, xd);
8862 if (mv_check_bounds(x, &cur_mv[1].as_mv)) return INT64_MAX;
8863 mbmi->mv[1].as_int = cur_mv[1].as_int;
8864 }
8865 }
8866#else
8867 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008868 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008869 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8870 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8871 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8872 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8873
8874 for (i = 0; i < 2; ++i) {
8875 clamp_mv2(&cur_mv[i].as_mv, xd);
8876 if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
8877 mbmi->mv[i].as_int = cur_mv[i].as_int;
8878 }
8879 }
8880 }
8881#endif // CONFIG_EXT_INTER
8882#endif // CONFIG_REF_MV
8883
8884 // do first prediction into the destination buffer. Do the next
8885 // prediction into a temporary buffer. Then keep track of which one
8886 // of these currently holds the best predictor, and use the other
8887 // one for future predictions. In the end, copy from tmp_buf to
8888 // dst if necessary.
8889 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008890 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8891 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008892 }
8893 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008894 orig_dst.plane[i] = xd->plane[i].dst.buf;
8895 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008896 }
8897
8898 // We don't include the cost of the second reference here, because there
8899 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8900 // words if you present them in that order, the second one is always known
8901 // if the first is known.
8902 //
8903 // Under some circumstances we discount the cost of new mv mode to encourage
8904 // initiation of a motion field.
8905 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8906 refs[0])) {
8907#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008908 rd_stats->rate +=
8909 AOMMIN(cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx),
8910 cost_mv_ref(cpi, NEARESTMV, is_comp_pred, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008911#else
Angie Chiang76159122016-11-09 12:13:22 -08008912 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8913 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008914#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8915 } else {
8916#if CONFIG_REF_MV && CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008917 rd_stats->rate += cost_mv_ref(cpi, this_mode, is_comp_pred, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008918#else
Angie Chiang76159122016-11-09 12:13:22 -08008919 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008920#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
8921 }
8922
Angie Chiang76159122016-11-09 12:13:22 -08008923 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008924#if CONFIG_EXT_INTER
8925 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8926#else
8927 mbmi->mode != NEARESTMV
8928#endif // CONFIG_EXT_INTER
8929 )
8930 return INT64_MAX;
8931
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008932 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008933 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8934 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008935 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008936
Yaowu Xuc27fc142016-08-22 16:08:15 -07008937#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008938#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008939 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008940 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008941 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008942#if CONFIG_MOTION_VAR
8943 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008944#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008945#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008946
Sarah Parker6fdc8532016-11-16 17:47:13 -08008947 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008948 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008949 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008950 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8951 INTERINTER_COMPOUND_DATA best_compound_data;
8952 int_mv best_mv[2];
8953 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008954 int tmp_skip_txfm_sb;
8955 int64_t tmp_skip_sse_sb;
Sarah Parker6fddd182016-11-10 20:57:20 -08008956 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008957 uint8_t pred0[2 * MAX_SB_SQUARE];
8958 uint8_t pred1[2 * MAX_SB_SQUARE];
8959 uint8_t *preds0[1] = { pred0 };
8960 uint8_t *preds1[1] = { pred1 };
8961 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008962 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008963 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008964 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008965
Sarah Parker6fdc8532016-11-16 17:47:13 -08008966 best_mv[0].as_int = cur_mv[0].as_int;
8967 best_mv[1].as_int = cur_mv[1].as_int;
8968 memset(&best_compound_data, 0, sizeof(INTERINTER_COMPOUND_DATA));
Sarah Parker6fddd182016-11-10 20:57:20 -08008969 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8970 av1_compound_type_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008971
Sarah Parker42d96102017-01-31 21:05:27 -08008972 if (masked_compound_used) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008973 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008974 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008975 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008976 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008977 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008978 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008979
Sarah Parker6fdc8532016-11-16 17:47:13 -08008980 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008981 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008982 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008983 best_rd_cur = INT64_MAX;
8984 mbmi->interinter_compound_data.type = cur_type;
8985 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
8986 bsize, mbmi->interinter_compound_data.type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008987 (masked_compound_used
8988 ? compound_type_cost[mbmi->interinter_compound_data.type]
8989 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008990
Sarah Parker6fdc8532016-11-16 17:47:13 -08008991 switch (cur_type) {
8992 case COMPOUND_AVERAGE:
David Barkerac37fa32016-12-02 12:30:21 +00008993 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008994 av1_subtract_plane(x, bsize, 0);
8995 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8996 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8997 INT64_MAX);
8998 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008999 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08009000 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08009001 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009002 break;
9003 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08009004 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
9005 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08009006 best_rd_cur = build_and_cost_compound_wedge(
David Barkerac37fa32016-12-02 12:30:21 +00009007 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
9008 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08009009 }
9010 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08009011#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08009012 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08009013 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
9014 best_rd_compound / 3 < ref_best_rd) {
Sarah Parker569edda2016-12-14 14:57:38 -08009015 best_rd_cur = build_and_cost_compound_seg(
9016 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
9017 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08009018 }
9019 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08009020#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08009021 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009022 }
Sarah Parker2e604882017-01-17 17:31:25 -08009023
9024 if (best_rd_cur < best_rd_compound) {
9025 best_rd_compound = best_rd_cur;
9026 memcpy(&best_compound_data, &mbmi->interinter_compound_data,
9027 sizeof(best_compound_data));
9028 if (have_newmv_in_inter_mode(this_mode)) {
9029 if (use_masked_motion_search(cur_type)) {
9030 best_tmp_rate_mv = tmp_rate_mv;
9031 best_mv[0].as_int = mbmi->mv[0].as_int;
9032 best_mv[1].as_int = mbmi->mv[1].as_int;
9033 } else {
9034 best_mv[0].as_int = cur_mv[0].as_int;
9035 best_mv[1].as_int = cur_mv[1].as_int;
9036 }
9037 }
9038 }
9039 // reset to original mvs for next iteration
9040 mbmi->mv[0].as_int = cur_mv[0].as_int;
9041 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009042 }
Sarah Parker6fdc8532016-11-16 17:47:13 -08009043 memcpy(&mbmi->interinter_compound_data, &best_compound_data,
9044 sizeof(INTERINTER_COMPOUND_DATA));
9045 if (have_newmv_in_inter_mode(this_mode)) {
9046 mbmi->mv[0].as_int = best_mv[0].as_int;
9047 mbmi->mv[1].as_int = best_mv[1].as_int;
9048 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
9049 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2e604882017-01-17 17:31:25 -08009050 if (use_masked_motion_search(mbmi->interinter_compound_data.type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08009051 rd_stats->rate += best_tmp_rate_mv - rate_mv;
9052 rate_mv = best_tmp_rate_mv;
9053 }
9054 }
9055
9056 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00009057 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009058 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00009059 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009060
9061 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009062
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009063 *args->compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08009064 compound_type_cost[mbmi->interinter_compound_data.type] +
9065 av1_cost_literal(get_interinter_compound_type_bits(
9066 bsize, mbmi->interinter_compound_data.type));
Yaowu Xuc27fc142016-08-22 16:08:15 -07009067 }
9068
9069 if (is_comp_interintra_pred) {
9070 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
9071 int64_t best_interintra_rd = INT64_MAX;
9072 int rmode, rate_sum;
9073 int64_t dist_sum;
9074 int j;
9075 int64_t best_interintra_rd_nowedge = INT64_MAX;
9076 int64_t best_interintra_rd_wedge = INT64_MAX;
9077 int rwedge;
9078 int_mv tmp_mv;
9079 int tmp_rate_mv = 0;
9080 int tmp_skip_txfm_sb;
9081 int64_t tmp_skip_sse_sb;
9082 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
9083 uint8_t *intrapred;
9084
Yaowu Xuf883b422016-08-30 14:01:10 -07009085#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009086 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
9087 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
9088 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009089#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009090 intrapred = intrapred_;
9091
Emil Keyder01770b32017-01-20 18:03:11 -05009092 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009093 for (j = 0; j < MAX_MB_PLANE; j++) {
9094 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
9095 xd->plane[j].dst.stride = bw;
9096 }
David Barkerac37fa32016-12-02 12:30:21 +00009097 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
9098 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009099 mbmi->ref_frame[1] = INTRA_FRAME;
9100 mbmi->use_wedge_interintra = 0;
9101
9102 for (j = 0; j < INTERINTRA_MODES; ++j) {
9103 mbmi->interintra_mode = (INTERINTRA_MODE)j;
9104 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00009105 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
9106 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07009107 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009108 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
9109 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
9110 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
9111 if (rd < best_interintra_rd) {
9112 best_interintra_rd = rd;
9113 best_interintra_mode = mbmi->interintra_mode;
9114 }
9115 }
9116 mbmi->interintra_mode = best_interintra_mode;
9117 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00009118 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
9119 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07009120 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
9121 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009122 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
9123 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
9124 if (rd != INT64_MAX)
9125 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
9126 best_interintra_rd = rd;
9127
9128 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00009129 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07009130 return INT64_MAX;
9131 }
9132 if (is_interintra_wedge_used(bsize)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009133 rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009134 if (rd != INT64_MAX)
9135 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
9136 dist_sum);
9137 best_interintra_rd_nowedge = rd;
9138
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009139 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07009140 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
9141 mbmi->use_wedge_interintra = 1;
9142
Yaowu Xuf883b422016-08-30 14:01:10 -07009143 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
9144 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009145
9146 best_interintra_rd_wedge =
9147 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
9148
9149 best_interintra_rd_wedge +=
9150 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
9151 // Refine motion vector.
9152 if (have_newmv_in_inter_mode(this_mode)) {
9153 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07009154 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009155 mbmi->interintra_wedge_index, 1, bsize);
9156 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
9157 &tmp_mv, &tmp_rate_mv, 0, mv_idx);
9158 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00009159 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009160 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
9161 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
9162 rd = RDCOST(x->rdmult, x->rddiv,
9163 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
9164 if (rd < best_interintra_rd_wedge) {
9165 best_interintra_rd_wedge = rd;
9166 } else {
9167 tmp_mv.as_int = cur_mv[0].as_int;
9168 tmp_rate_mv = rate_mv;
9169 }
9170 } else {
9171 tmp_mv.as_int = cur_mv[0].as_int;
9172 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009173 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009174 }
9175 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07009176 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009177 rd =
9178 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
9179 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
9180 if (rd != INT64_MAX)
9181 rd = RDCOST(x->rdmult, x->rddiv,
9182 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
9183 best_interintra_rd_wedge = rd;
9184 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
9185 mbmi->use_wedge_interintra = 1;
9186 best_interintra_rd = best_interintra_rd_wedge;
9187 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08009188 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009189 rate_mv = tmp_rate_mv;
9190 } else {
9191 mbmi->use_wedge_interintra = 0;
9192 best_interintra_rd = best_interintra_rd_nowedge;
9193 mbmi->mv[0].as_int = cur_mv[0].as_int;
9194 }
9195 } else {
9196 mbmi->use_wedge_interintra = 0;
9197 best_interintra_rd = best_interintra_rd_nowedge;
9198 }
9199 }
9200
9201 pred_exists = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009202 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07009203 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009204 *args->compmode_interintra_cost +=
Fergus Simpson073c6f32017-02-17 12:13:48 -08009205 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009206 if (is_interintra_wedge_used(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009207 *args->compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009208 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
9209 if (mbmi->use_wedge_interintra) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009210 *args->compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07009211 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07009212 }
9213 }
9214 } else if (is_interintra_allowed(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009215 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07009216 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009217 }
9218
Angie Chiang75c22092016-10-25 12:19:16 -07009219 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009220 int tmp_rate;
9221 int64_t tmp_dist;
David Barkerac37fa32016-12-02 12:30:21 +00009222 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009223 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
9224 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
9225 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
9226 }
Angie Chiang75c22092016-10-25 12:19:16 -07009227#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009228
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009229 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009230#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009231 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009232#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009233 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08009234#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009235
9236#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009237 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009238 if (is_comp_pred) {
9239 const int mode0 = compound_ref0_mode(this_mode);
9240 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009241 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
9242 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009243 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00009244 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009245 return INT64_MAX;
9246 }
9247 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009248 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009249 }
9250 }
9251#endif // CONFIG_EXT_INTER
9252
9253 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
9254 // if current pred_error modeled rd is substantially more than the best
9255 // so far, do not bother doing full rd
9256 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00009257 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009258 return INT64_MAX;
9259 }
9260 }
9261
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009262 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
9263 disable_skip, mode_mv, mi_row, mi_col, args,
9264 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07009265#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009266#if CONFIG_EXT_INTER
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009267 rate2_bmc_nocoeff, &best_bmc_mbmi,
Yue Chencb60b182016-10-13 15:18:22 -07009268#if CONFIG_MOTION_VAR
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009269 rate_mv_bmc,
Yue Chencb60b182016-10-13 15:18:22 -07009270#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07009271#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07009272#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009273 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
9274 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08009275
Yaowu Xuc27fc142016-08-22 16:08:15 -07009276 return 0; // The rate-distortion cost will be re-calculated by caller.
9277}
9278
Urvang Joshi52648442016-10-13 17:27:51 -07009279void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
9280 RD_COST *rd_cost, BLOCK_SIZE bsize,
9281 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9282 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009283 MACROBLOCKD *const xd = &x->e_mbd;
9284 struct macroblockd_plane *const pd = xd->plane;
9285 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9286 int y_skip = 0, uv_skip = 0;
9287 int64_t dist_y = 0, dist_uv = 0;
9288 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009289 const int unify_bsize = CONFIG_CB4X4;
9290
Yaowu Xuc27fc142016-08-22 16:08:15 -07009291 ctx->skip = 0;
9292 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009293 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009294
Jingning Han271bb2c2016-12-14 12:34:46 -08009295 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009296 if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9297 &y_skip, bsize, best_rd) >= best_rd) {
9298 rd_cost->rate = INT_MAX;
9299 return;
9300 }
9301 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009302 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07009303 &dist_y, &y_skip, best_rd) >= best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009304 rd_cost->rate = INT_MAX;
9305 return;
9306 }
9307 }
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009308 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9309 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009310
9311#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009312#if !CONFIG_CHROMA_2X2
Jingning Han8efdbc82017-02-19 14:40:03 -08009313 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08009314#endif // !CONFIG_CHROMA_2X2
Jingning Han8efdbc82017-02-19 14:40:03 -08009315 if (!x->skip_chroma_rd)
9316 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9317 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009318#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009319 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009320 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009321#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009322
9323 if (y_skip && uv_skip) {
9324 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
Yaowu Xuf883b422016-08-30 14:01:10 -07009325 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009326 rd_cost->dist = dist_y + dist_uv;
9327 } else {
9328 rd_cost->rate =
Yaowu Xuf883b422016-08-30 14:01:10 -07009329 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009330 rd_cost->dist = dist_y + dist_uv;
9331 }
9332
9333 ctx->mic = *xd->mi[0];
9334 ctx->mbmi_ext = *x->mbmi_ext;
9335 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9336}
9337
Yaowu Xuc27fc142016-08-22 16:08:15 -07009338// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009339int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009340 return (cpi->oxcf.pass == 2) &&
9341 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9342 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9343}
9344
9345// Checks to see if a super block is on a horizontal image edge.
9346// In most cases this is the "real" edge unless there are formatting
9347// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009348int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009349 int top_edge = 0;
9350 int bottom_edge = cpi->common.mi_rows;
9351 int is_active_h_edge = 0;
9352
9353 // For two pass account for any formatting bars detected.
9354 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009355 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009356
9357 // The inactive region is specified in MBs not mi units.
9358 // The image edge is in the following MB row.
9359 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9360
9361 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009362 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009363 }
9364
9365 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9366 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9367 is_active_h_edge = 1;
9368 }
9369 return is_active_h_edge;
9370}
9371
9372// Checks to see if a super block is on a vertical image edge.
9373// In most cases this is the "real" edge unless there are formatting
9374// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009375int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009376 int left_edge = 0;
9377 int right_edge = cpi->common.mi_cols;
9378 int is_active_v_edge = 0;
9379
9380 // For two pass account for any formatting bars detected.
9381 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009382 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009383
9384 // The inactive region is specified in MBs not mi units.
9385 // The image edge is in the following MB row.
9386 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9387
9388 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009389 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009390 }
9391
9392 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9393 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9394 is_active_v_edge = 1;
9395 }
9396 return is_active_v_edge;
9397}
9398
9399// Checks to see if a super block is at the edge of the active image.
9400// In most cases this is the "real" edge unless there are formatting
9401// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009402int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009403 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9404 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009405}
9406
Urvang Joshib100db72016-10-12 16:28:56 -07009407#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009408static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009409 MACROBLOCKD *const xd = &x->e_mbd;
9410 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9411 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9412 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009413 int src_stride = x->plane[1].src.stride;
9414 const uint8_t *const src_u = x->plane[1].src.buf;
9415 const uint8_t *const src_v = x->plane[2].src.buf;
9416 float *const data = x->palette_buffer->kmeans_data_buf;
9417 float centroids[2 * PALETTE_MAX_SIZE];
9418 uint8_t *const color_map = xd->plane[1].color_index_map;
9419 int r, c;
Yaowu Xuf883b422016-08-30 14:01:10 -07009420#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009421 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9422 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Yaowu Xuf883b422016-08-30 14:01:10 -07009423#endif // CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009424 int plane_block_width, plane_block_height, rows, cols;
9425 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9426 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009427 (void)cpi;
9428
9429 for (r = 0; r < rows; ++r) {
9430 for (c = 0; c < cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009431#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009432 if (cpi->common.use_highbitdepth) {
9433 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9434 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9435 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009436#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009437 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9438 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -07009439#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009440 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009441#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009442 }
9443 }
9444
9445 for (r = 1; r < 3; ++r) {
9446 for (c = 0; c < pmi->palette_size[1]; ++c) {
9447 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9448 }
9449 }
9450
Yaowu Xuf883b422016-08-30 14:01:10 -07009451 av1_calc_indices(data, centroids, color_map, rows * cols,
9452 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009453 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9454 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009455}
Urvang Joshib100db72016-10-12 16:28:56 -07009456#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009457
hui su5db97432016-10-14 16:10:14 -07009458#if CONFIG_FILTER_INTRA
9459static void pick_filter_intra_interframe(
9460 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009461 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9462 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9463 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009464#if CONFIG_EXT_INTRA
9465 int8_t *uv_angle_delta,
9466#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009467#if CONFIG_PALETTE
9468 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9469#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009470 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9471 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9472 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9473#if CONFIG_SUPERTX
9474 int *returnrate_nocoef,
9475#endif // CONFIG_SUPERTX
9476 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_COST *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009477 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009478 MACROBLOCKD *const xd = &x->e_mbd;
9479 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009480#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009481 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009482#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009483 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9484 int dc_mode_index;
9485 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009486 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9487 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009488 TX_SIZE uv_tx;
9489
9490 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009491 if (av1_mode_order[i].mode == DC_PRED &&
9492 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009493 break;
9494 dc_mode_index = i;
9495 assert(i < MAX_MODES);
9496
9497 // TODO(huisu): use skip_mask for further speedup.
9498 (void)skip_mask;
9499 mbmi->mode = DC_PRED;
9500 mbmi->uv_mode = DC_PRED;
9501 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009502 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009503 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9504 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009505 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009506 return;
hui su5db97432016-10-14 16:10:14 -07009507 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009508 if (rate_y == INT_MAX) return;
9509
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009510 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9511 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009512 if (rate_uv_intra[uv_tx] == INT_MAX) {
9513 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9514 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9515 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009516#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009517 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009518#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009519 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9520#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009521 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009522#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009523 }
9524
9525 rate_uv = rate_uv_tokenonly[uv_tx];
9526 distortion_uv = dist_uv[uv_tx];
9527 skippable = skippable && skip_uv[uv_tx];
9528 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009529#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009530 if (cm->allow_screen_content_tools) {
9531 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9532 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9533 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9534 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9535 }
Urvang Joshib100db72016-10-12 16:28:56 -07009536#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009537#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009538 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009539#endif // CONFIG_EXT_INTRA
9540 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9541 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9542 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9543 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9544 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009545 }
9546
9547 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9548 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009549#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009550 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07009551 rate2 += av1_cost_bit(
9552 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009553#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009554
9555 if (!xd->lossless[mbmi->segment_id]) {
9556 // super_block_yrd above includes the cost of the tx_size in the
9557 // tokenonly rate, but for intra blocks, tx_size is always coded
9558 // (prediction granularity), so we account for it in the full rate,
9559 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009560 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009561 }
9562
hui su5db97432016-10-14 16:10:14 -07009563 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9564 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9565 rate2 += write_uniform_cost(
9566 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9567#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009568 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
9569 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
9570 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009571 }
hui su5db97432016-10-14 16:10:14 -07009572#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009573 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009574 rate2 +=
9575 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9576 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9577 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9578 rate2 +=
9579 write_uniform_cost(FILTER_INTRA_MODES,
9580 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009581 }
9582 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009583 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9584 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009585
9586 rate2 += ref_costs_single[INTRA_FRAME];
9587
9588 if (skippable) {
9589 rate2 -= (rate_y + rate_uv);
9590 rate_y = 0;
9591 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009592 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009593 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009594 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009595 }
9596 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009597
9598 if (this_rd < *best_intra_rd) {
9599 *best_intra_rd = this_rd;
9600 *best_intra_mode = mbmi->mode;
9601 }
9602 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009603 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009604
9605 if (this_rd < *best_rd) {
9606 *best_mode_index = dc_mode_index;
9607 mbmi->mv[0].as_int = 0;
9608 rd_cost->rate = rate2;
9609#if CONFIG_SUPERTX
9610 if (x->skip)
9611 *returnrate_nocoef = rate2;
9612 else
9613 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009614 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9615 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9616 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009617#endif // CONFIG_SUPERTX
9618 rd_cost->dist = distortion2;
9619 rd_cost->rdcost = this_rd;
9620 *best_rd = this_rd;
9621 *best_mbmode = *mbmi;
9622 *best_skip2 = 0;
9623 *best_mode_skippable = skippable;
9624 }
9625}
hui su5db97432016-10-14 16:10:14 -07009626#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009627
Yue Chencb60b182016-10-13 15:18:22 -07009628#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009629static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9630 const MACROBLOCKD *xd, int mi_row,
9631 int mi_col, const uint8_t *above,
9632 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009633 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009634#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009635
Urvang Joshi52648442016-10-13 17:27:51 -07009636void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009637 MACROBLOCK *x, int mi_row, int mi_col,
9638 RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009639#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009640 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009641#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009642 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9643 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009644 const AV1_COMMON *const cm = &cpi->common;
9645 const RD_OPT *const rd_opt = &cpi->rd;
9646 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009647 MACROBLOCKD *const xd = &x->e_mbd;
9648 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009649#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009650 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009651#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009652 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9653 const struct segmentation *const seg = &cm->seg;
9654 PREDICTION_MODE this_mode;
9655 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9656 unsigned char segment_id = mbmi->segment_id;
9657 int comp_pred, i, k;
9658 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9659 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
9660#if CONFIG_EXT_INTER
9661 int_mv single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } }, { { 0 } } };
9662 int single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 }, { 0 } };
9663 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9664#else
9665 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
9666#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009667 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9668 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009669 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009670#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009671 AOM_LAST2_FLAG,
9672 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009673#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009674 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009675#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009676 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009677#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009678 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009679 };
9680 int64_t best_rd = best_rd_so_far;
9681 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9682 int64_t best_pred_diff[REFERENCE_MODES];
9683 int64_t best_pred_rd[REFERENCE_MODES];
9684 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009685#if CONFIG_REF_MV
9686 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9687 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Fergus Simpson4063a682017-02-28 16:52:22 -08009688#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -07009689 int best_mode_skippable = 0;
9690 int midx, best_mode_index = -1;
9691 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9692 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009693 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009694 int64_t best_intra_rd = INT64_MAX;
9695 unsigned int best_pred_sse = UINT_MAX;
9696 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009697 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9698 int64_t dist_uvs[TX_SIZES_ALL];
9699 int skip_uvs[TX_SIZES_ALL];
9700 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009701#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009702 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009703#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009704#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009705 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009706 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009707 uint8_t directional_mode_skip_mask[INTRA_MODES];
9708#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009709#if CONFIG_FILTER_INTRA
9710 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009711 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009712#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009713 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009714 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9715 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9716 int best_skip2 = 0;
9717 uint8_t ref_frame_skip_mask[2] = { 0 };
9718#if CONFIG_EXT_INTER
9719 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9720 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9721 int64_t best_single_inter_rd = INT64_MAX;
9722#else
9723 uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
9724#endif // CONFIG_EXT_INTER
9725 int mode_skip_start = sf->mode_skip_start + 1;
9726 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9727 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9728 int64_t mode_threshold[MAX_MODES];
9729 int *mode_map = tile_data->mode_map[bsize];
9730 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009731#if CONFIG_PVQ
9732 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009733#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009734
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009735 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009736#if CONFIG_MOTION_VAR
9737 { NULL },
9738 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9739 { NULL },
9740 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9741#endif // CONFIG_MOTION_VAR
9742#if CONFIG_EXT_INTER
9743 NULL,
9744 NULL,
9745 NULL,
9746 NULL,
9747 NULL,
9748#else // CONFIG_EXT_INTER
9749 NULL,
9750#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009751 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009752 };
9753
Urvang Joshib100db72016-10-12 16:28:56 -07009754#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009755 const int rows = block_size_high[bsize];
9756 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009757#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9758#if CONFIG_PALETTE
9759 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009760 const MODE_INFO *above_mi = xd->above_mi;
9761 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009762#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009763#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009764#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009765 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9766 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9767#else
9768 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9769 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07009770#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009771 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9772 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009773 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9774 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9775 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9776 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009777
Yaowu Xuf883b422016-08-30 14:01:10 -07009778#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009779 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9780 int len = sizeof(uint16_t);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009781 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9782 args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9783 args.above_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009784 CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009785 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9786 args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9787 args.left_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009788 CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009789 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009790#endif // CONFIG_AOM_HIGHBITDEPTH
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009791 args.above_pred_buf[0] = tmp_buf1;
9792 args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
9793 args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9794 args.left_pred_buf[0] = tmp_buf2;
9795 args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
9796 args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07009797#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009798 }
Yaowu Xuf883b422016-08-30 14:01:10 -07009799#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009800#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009801
Yaowu Xuf883b422016-08-30 14:01:10 -07009802 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009803
Urvang Joshib100db72016-10-12 16:28:56 -07009804#if CONFIG_PALETTE
9805 av1_zero(pmi_uv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009806 if (cm->allow_screen_content_tools) {
9807 if (above_mi)
9808 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9809 if (left_mi)
9810 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9811 }
Urvang Joshib100db72016-10-12 16:28:56 -07009812#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009813
9814#if CONFIG_EXT_INTRA
9815 memset(directional_mode_skip_mask, 0,
9816 sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
9817#endif // CONFIG_EXT_INTRA
9818
9819 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9820 &comp_mode_p);
9821
9822 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009823 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009824 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9825 for (i = 0; i < MB_MODE_COUNT; ++i) {
9826 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009827 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009828 }
9829 }
9830
9831 rd_cost->rate = INT_MAX;
9832#if CONFIG_SUPERTX
9833 *returnrate_nocoef = INT_MAX;
9834#endif // CONFIG_SUPERTX
9835
9836 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9837 x->pred_mv_sad[ref_frame] = INT_MAX;
9838 x->mbmi_ext->mode_context[ref_frame] = 0;
9839#if CONFIG_REF_MV && CONFIG_EXT_INTER
9840 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
9841#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
9842 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9843 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9844 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9845 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9846 }
9847 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009848#if CONFIG_GLOBAL_MOTION
9849 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009850 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009851 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9852 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009853 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009854#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009855 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009856#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009857#if CONFIG_EXT_INTER
9858 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
9859 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009860#if CONFIG_GLOBAL_MOTION
9861 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009862 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009863 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9864 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009865 .as_int;
9866#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009867 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009868#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009869#endif // CONFIG_EXT_INTER
9870 }
9871
9872#if CONFIG_REF_MV
9873 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9874 MODE_INFO *const mi = xd->mi[0];
9875 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9876 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009877 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9878 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009879#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009880 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009881#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009882 candidates, mi_row, mi_col, NULL, NULL,
9883 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009884 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9885 MV_REFERENCE_FRAME rf[2];
9886 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009887 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9888 frame_mv[ZEROMV][rf[0]].as_int ||
9889 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9890 frame_mv[ZEROMV][rf[0]].as_int ||
9891 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9892 frame_mv[ZEROMV][rf[1]].as_int ||
9893 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009894 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9895 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009896 }
9897#endif // CONFIG_REF_MV
9898
Yue Chencb60b182016-10-13 15:18:22 -07009899#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009900 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
9901 if (check_num_overlappable_neighbors(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009902 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9903 args.above_pred_buf, dst_width1,
9904 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009905 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009906 args.left_pred_buf, dst_width2,
9907 dst_height2, args.left_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009908 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
9909 x->mask_buf = mask2d_buf;
9910 x->wsrc_buf = weighted_src_buf;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009911 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9912 args.above_pred_stride[0], args.left_pred_buf[0],
9913 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009914 }
Yue Chencb60b182016-10-13 15:18:22 -07009915#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009916
9917 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9918 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9919// Skip checking missing references in both single and compound reference
9920// modes. Note that a mode will be skipped iff both reference frames
9921// are masked out.
9922#if CONFIG_EXT_REFS
9923 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9924 ref_frame_skip_mask[0] |= (1 << ref_frame);
9925 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9926 } else {
9927#endif // CONFIG_EXT_REFS
9928 ref_frame_skip_mask[0] |= (1 << ref_frame);
9929 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9930#if CONFIG_EXT_REFS
9931 }
9932#endif // CONFIG_EXT_REFS
9933 } else {
9934 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9935 // Skip fixed mv modes for poor references
9936 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9937 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9938 break;
9939 }
9940 }
9941 }
9942 // If the segment reference frame feature is enabled....
9943 // then do nothing if the current ref frame is not allowed..
9944 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9945 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9946 ref_frame_skip_mask[0] |= (1 << ref_frame);
9947 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9948 }
9949 }
9950
9951 // Disable this drop out case if the ref frame
9952 // segment level feature is enabled for this segment. This is to
9953 // prevent the possibility that we end up unable to pick any mode.
9954 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9955 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9956 // unless ARNR filtering is enabled in which case we want
9957 // an unfiltered alternative. We allow near/nearest as well
9958 // because they may result in zero-zero MVs but be cheaper.
9959 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009960 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009961 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9962#if CONFIG_EXT_REFS
9963 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9964 (1 << BWDREF_FRAME) |
9965#endif // CONFIG_EXT_REFS
9966 (1 << GOLDEN_FRAME);
9967 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9968 // TODO(zoeliu): To further explore whether following needs to be done for
9969 // BWDREF_FRAME as well.
9970 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009971#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009972 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009973 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009974 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009975 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009976#else
9977 zeromv.as_int = 0;
9978#endif // CONFIG_GLOBAL_MOTION
9979 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009980 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009981 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009982 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9983#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009984 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009985 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009986 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009987 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009988 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009989 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009990 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009991 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9992#endif // CONFIG_EXT_INTER
9993 }
9994 }
9995
9996 if (cpi->rc.is_src_frame_alt_ref) {
9997 if (sf->alt_ref_search_fp) {
9998 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9999 mode_skip_mask[ALTREF_FRAME] = 0;
10000 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
10001 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
10002 }
10003 }
10004
10005 if (sf->alt_ref_search_fp)
10006 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
10007 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
10008 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
10009
10010 if (sf->adaptive_mode_search) {
10011 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
10012 cpi->rc.frames_since_golden >= 3)
10013 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
10014 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
10015 }
10016
10017 if (bsize > sf->max_intra_bsize) {
10018 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
10019 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
10020 }
10021
10022 mode_skip_mask[INTRA_FRAME] |=
10023 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
10024
10025 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
10026 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
10027 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
10028
10029 midx = sf->schedule_mode_search ? mode_skip_start : 0;
10030 while (midx > 4) {
10031 uint8_t end_pos = 0;
10032 for (i = 5; i < midx; ++i) {
10033 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
10034 uint8_t tmp = mode_map[i];
10035 mode_map[i] = mode_map[i - 1];
10036 mode_map[i - 1] = tmp;
10037 end_pos = i;
10038 }
10039 }
10040 midx = end_pos;
10041 }
10042
10043 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
10044 x->use_default_intra_tx_type = 1;
10045 else
10046 x->use_default_intra_tx_type = 0;
10047
10048 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
10049 x->use_default_inter_tx_type = 1;
10050 else
10051 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -070010052#if CONFIG_PVQ
10053 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080010054#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070010055#if CONFIG_EXT_INTER
10056 for (i = 0; i < MB_MODE_COUNT; ++i)
10057 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
10058 modelled_rd[i][ref_frame] = INT64_MAX;
10059#endif // CONFIG_EXT_INTER
10060
10061 for (midx = 0; midx < MAX_MODES; ++midx) {
10062 int mode_index;
10063 int mode_excluded = 0;
10064 int64_t this_rd = INT64_MAX;
10065 int disable_skip = 0;
10066 int compmode_cost = 0;
10067#if CONFIG_EXT_INTER
10068 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -080010069 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010070#endif // CONFIG_EXT_INTER
10071 int rate2 = 0, rate_y = 0, rate_uv = 0;
10072 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
10073 int skippable = 0;
10074 int this_skip2 = 0;
10075 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010076#if CONFIG_REF_MV
10077 uint8_t ref_frame_type;
Fergus Simpson4063a682017-02-28 16:52:22 -080010078#endif // CONFIG_REF_MV
Yushin Cho77bba8d2016-11-04 16:36:56 -070010079#if CONFIG_PVQ
10080 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080010081#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070010082 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -070010083 this_mode = av1_mode_order[mode_index].mode;
10084 ref_frame = av1_mode_order[mode_index].ref_frame[0];
10085 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010086#if CONFIG_REF_MV
10087 mbmi->ref_mv_idx = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010088#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010089
10090#if CONFIG_EXT_INTER
10091 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
10092 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080010093 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010094 if (!is_interintra_allowed_bsize(bsize)) continue;
10095 }
10096
10097 if (is_inter_compound_mode(this_mode)) {
10098 frame_mv[this_mode][ref_frame].as_int =
10099 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
10100 frame_mv[this_mode][second_ref_frame].as_int =
10101 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
10102 }
10103#endif // CONFIG_EXT_INTER
10104
10105 // Look at the reference frame of the best mode so far and set the
10106 // skip mask to look at a subset of the remaining modes.
10107 if (midx == mode_skip_start && best_mode_index >= 0) {
10108 switch (best_mbmode.ref_frame[0]) {
10109 case INTRA_FRAME: break;
10110 case LAST_FRAME:
10111 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
10112 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10113 break;
10114#if CONFIG_EXT_REFS
10115 case LAST2_FRAME:
10116 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
10117 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10118 break;
10119 case LAST3_FRAME:
10120 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
10121 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10122 break;
10123#endif // CONFIG_EXT_REFS
10124 case GOLDEN_FRAME:
10125 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
10126 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10127 break;
10128#if CONFIG_EXT_REFS
10129 case BWDREF_FRAME:
10130 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
10131 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10132 break;
10133#endif // CONFIG_EXT_REFS
10134 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
10135#if CONFIG_EXT_REFS
10136 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10137#endif // CONFIG_EXT_REFS
10138 break;
Emil Keyder01770b32017-01-20 18:03:11 -050010139 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070010140 case TOTAL_REFS_PER_FRAME:
10141 assert(0 && "Invalid Reference frame");
10142 break;
10143 }
10144 }
10145
10146 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010147 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010148 continue;
10149
10150 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
10151
10152 // Test best rd so far against threshold for trying this mode.
10153 if (best_mode_skippable && sf->schedule_mode_search)
10154 mode_threshold[mode_index] <<= 1;
10155
10156 if (best_rd < mode_threshold[mode_index]) continue;
10157
10158 comp_pred = second_ref_frame > INTRA_FRAME;
10159 if (comp_pred) {
10160 if (!cpi->allow_comp_inter_inter) continue;
10161
10162 // Skip compound inter modes if ARF is not available.
10163 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10164
10165 // Do not allow compound prediction if the segment level reference frame
10166 // feature is in use as in this case there can only be one reference.
10167 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10168
10169 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10170 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10171 continue;
10172
10173 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10174 } else {
10175 if (ref_frame != INTRA_FRAME)
10176 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10177 }
10178
10179 if (ref_frame == INTRA_FRAME) {
10180 if (sf->adaptive_mode_search)
10181 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10182 continue;
10183
10184 if (this_mode != DC_PRED) {
10185 // Disable intra modes other than DC_PRED for blocks with low variance
10186 // Threshold for intra skipping based on source variance
10187 // TODO(debargha): Specialize the threshold for super block sizes
10188 const unsigned int skip_intra_var_thresh = 64;
10189 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10190 x->source_variance < skip_intra_var_thresh)
10191 continue;
10192 // Only search the oblique modes if the best so far is
10193 // one of the neighboring directional modes
10194 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10195 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10196 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10197 continue;
10198 }
10199 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10200 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10201 }
10202 }
Sarah Parkere5299862016-08-16 14:57:37 -070010203#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010204 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010205 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010206 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010207#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010208 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010209#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010210 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10211 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
10212#if CONFIG_REF_MV && CONFIG_EXT_INTER
10213 mbmi_ext->compound_mode_context,
10214#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010215 frame_mv, this_mode, ref_frames, bsize, -1,
10216 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010217 continue;
10218 }
10219
10220 mbmi->mode = this_mode;
10221 mbmi->uv_mode = DC_PRED;
10222 mbmi->ref_frame[0] = ref_frame;
10223 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010224#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010225 pmi->palette_size[0] = 0;
10226 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010227#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010228#if CONFIG_FILTER_INTRA
10229 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10230 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10231#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010232 // Evaluate all sub-pel filters irrespective of whether we can use
10233 // them for this frame.
10234#if CONFIG_DUAL_FILTER
10235 for (i = 0; i < 4; ++i) {
10236 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
10237 ? EIGHTTAP_REGULAR
10238 : cm->interp_filter;
10239 }
10240#else
10241 mbmi->interp_filter =
10242 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080010243#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010244 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010245 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010246
10247 x->skip = 0;
10248 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10249
10250 // Select prediction reference frames.
10251 for (i = 0; i < MAX_MB_PLANE; i++) {
10252 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10253 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10254 }
10255
10256#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010257 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010258#endif // CONFIG_EXT_INTER
10259
10260 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010261 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010262 TX_SIZE uv_tx;
10263 struct macroblockd_plane *const pd = &xd->plane[1];
10264#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010265 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010266 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010267 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010268 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010269 if (!angle_stats_ready) {
10270 const int src_stride = x->plane[0].src.stride;
10271 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuf883b422016-08-30 14:01:10 -070010272#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010273 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
10274 highbd_angle_estimation(src, src_stride, rows, cols,
10275 directional_mode_skip_mask);
10276 else
Fergus Simpson4063a682017-02-28 16:52:22 -080010277#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010278 angle_estimation(src, src_stride, rows, cols,
10279 directional_mode_skip_mask);
10280 angle_stats_ready = 1;
10281 }
10282 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010283 rd_stats_y.rate = INT_MAX;
hui su9a416f52017-01-13 11:37:53 -080010284 this_rd = rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y,
10285 bsize, intra_mode_cost[mbmi->mode],
10286 best_rd, &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010287 } else {
10288 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010289 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010290 }
10291#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010292 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010293#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010294 rate_y = rd_stats_y.rate;
10295 distortion_y = rd_stats_y.dist;
10296 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010297
10298 if (rate_y == INT_MAX) continue;
10299
hui su5db97432016-10-14 16:10:14 -070010300#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010301 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010302#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010303
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010304 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10305 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010306 if (rate_uv_intra[uv_tx] == INT_MAX) {
10307 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010308 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10309 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010310#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010311 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010312#endif // CONFIG_PALETTE
10313
Yaowu Xuc27fc142016-08-22 16:08:15 -070010314#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010315 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10316#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010317#if CONFIG_FILTER_INTRA
10318 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10319#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010320 }
10321
10322 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010323 distortion_uv = dist_uvs[uv_tx];
10324 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010325 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010326#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010327 if (cm->allow_screen_content_tools) {
10328 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10329 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10330 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10331 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10332 }
Urvang Joshib100db72016-10-12 16:28:56 -070010333#endif // CONFIG_PALETTE
10334
Yaowu Xuc27fc142016-08-22 16:08:15 -070010335#if CONFIG_EXT_INTRA
10336 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010337#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010338#if CONFIG_FILTER_INTRA
10339 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10340 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10341 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10342 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10343 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10344 }
10345#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010346
Jingning Han36fe3202017-02-20 22:31:49 -080010347#if CONFIG_CB4X4
10348 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10349 if (!x->skip_chroma_rd)
10350 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10351#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010352 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10353 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010354#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010355
Urvang Joshib100db72016-10-12 16:28:56 -070010356#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010357 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -070010358 rate2 += av1_cost_bit(
10359 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -070010360#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010361
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010362 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010363 // super_block_yrd above includes the cost of the tx_size in the
10364 // tokenonly rate, but for intra blocks, tx_size is always coded
10365 // (prediction granularity), so we account for it in the full rate,
10366 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010367 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010368 }
10369#if CONFIG_EXT_INTRA
10370 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010371 const int max_angle_delta = av1_get_max_angle_delta(bsize, 0);
hui sueda3d762016-12-06 16:58:23 -080010372#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010373 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -070010374 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -080010375 p_angle = mode_to_angle_map[mbmi->mode] +
10376 mbmi->angle_delta[0] * av1_get_angle_step(bsize, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -070010377 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010378 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010379#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -080010380 rate2 += write_uniform_cost(2 * max_angle_delta + 1,
10381 max_angle_delta + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010382 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010383 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su45dc5972016-12-08 17:42:50 -080010384 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA_UV + 1,
10385 MAX_ANGLE_DELTA_UV + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010386 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010387#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010388#if CONFIG_FILTER_INTRA
10389 if (mbmi->mode == DC_PRED) {
10390 rate2 +=
10391 av1_cost_bit(cm->fc->filter_intra_probs[0],
10392 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10393 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10394 rate2 += write_uniform_cost(
10395 FILTER_INTRA_MODES,
10396 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10397 }
10398 }
10399 if (mbmi->uv_mode == DC_PRED) {
10400 rate2 +=
10401 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10402 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10403 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10404 rate2 += write_uniform_cost(
10405 FILTER_INTRA_MODES,
10406 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10407 }
10408#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010409 if (this_mode != DC_PRED && this_mode != TM_PRED)
10410 rate2 += intra_cost_penalty;
10411 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010412 } else {
10413#if CONFIG_REF_MV
10414 int_mv backup_ref_mv[2];
10415
Jingning Hanc41a5492017-02-24 11:18:52 -080010416#if !SUB8X8_COMP_REF
10417 if (bsize < BLOCK_8X8 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010418#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010419
Yaowu Xuc27fc142016-08-22 16:08:15 -070010420 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10421 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Fergus Simpson4063a682017-02-28 16:52:22 -080010422#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010423#if CONFIG_EXT_INTER
10424 if (second_ref_frame == INTRA_FRAME) {
10425 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010426 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010427// TODO(debargha|geza.lore):
10428// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010429#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010430 mbmi->angle_delta[0] = 0;
10431 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010432#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010433 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010434#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010435#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010436#if CONFIG_FILTER_INTRA
10437 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10438 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10439#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010440 }
10441#endif // CONFIG_EXT_INTER
10442#if CONFIG_REF_MV
10443 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010444 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010445
10446 if (this_mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
10447 int ref;
10448 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10449 int_mv this_mv =
10450 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10451 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010452 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10453 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010454 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10455 }
10456 }
Fergus Simpson4063a682017-02-28 16:52:22 -080010457#endif // CONFIG_REF_MV
Angie Chiang76159122016-11-09 12:13:22 -080010458 {
10459 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10460 av1_init_rd_stats(&rd_stats);
10461 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010462
10463// Point to variables that are maintained between loop iterations
10464#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010465 args.single_newmvs = single_newmvs;
10466 args.single_newmvs_rate = single_newmvs_rate;
10467 args.compmode_interintra_cost = &compmode_interintra_cost;
10468 args.compmode_interinter_cost = &compmode_interinter_cost;
10469 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010470#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010471 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010472#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010473 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10474 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010475 mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010476// Prevent pointers from escaping local scope
Yaowu Xuc27fc142016-08-22 16:08:15 -070010477#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010478 args.compmode_interintra_cost = NULL;
10479 args.compmode_interinter_cost = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010480#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010481
10482 rate2 = rd_stats.rate;
10483 skippable = rd_stats.skip;
10484 distortion2 = rd_stats.dist;
10485 total_sse = rd_stats.sse;
10486 rate_y = rd_stats_y.rate;
10487 rate_uv = rd_stats_uv.rate;
10488 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010489
10490#if CONFIG_REF_MV
Yue Chen6e601e92016-12-05 18:19:00 -080010491// TODO(jingning): This needs some refactoring to improve code quality
10492// and reduce redundant steps.
10493#if CONFIG_EXT_INTER
10494 if (((mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) &&
10495 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10496 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10497 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10498#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010499 if ((mbmi->mode == NEARMV &&
10500 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10501 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Yue Chen6e601e92016-12-05 18:19:00 -080010502#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010503 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10504 MB_MODE_INFO backup_mbmi = *mbmi;
10505 int backup_skip = x->skip;
10506 int64_t tmp_ref_rd = this_rd;
10507 int ref_idx;
10508
Yue Chen6e601e92016-12-05 18:19:00 -080010509// TODO(jingning): This should be deprecated shortly.
10510#if CONFIG_EXT_INTER
10511 int idx_offset =
10512 (mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) ? 1 : 0;
10513#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010514 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010515#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010516 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010517 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010518
10519 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010520 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010521 // Dummy
10522 int_mv backup_fmv[2];
10523 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10524 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10525
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010526 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010527
10528 if (this_rd < INT64_MAX) {
10529 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10530 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10531 tmp_ref_rd =
10532 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010533 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010534 distortion2);
10535 else
10536 tmp_ref_rd =
10537 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010538 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010539 rate_y - rate_uv,
10540 total_sse);
10541 }
10542#if CONFIG_VAR_TX
10543 for (i = 0; i < MAX_MB_PLANE; ++i)
10544 memcpy(x->blk_skip_drl[i], x->blk_skip[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 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10549 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010550 int dummy_disable_skip = 0;
10551 int ref;
10552 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010553 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010554#if CONFIG_EXT_INTER
10555 int tmp_compmode_interintra_cost = 0;
10556 int tmp_compmode_interinter_cost = 0;
10557#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010558
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010559 av1_invalid_rd_stats(&tmp_rd_stats);
10560
Yaowu Xuc27fc142016-08-22 16:08:15 -070010561 mbmi->ref_mv_idx = 1 + ref_idx;
10562
10563 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10564 int_mv this_mv =
10565 (ref == 0)
10566 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10567 .this_mv
10568 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10569 .comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010570 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10571 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010572 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10573 }
10574
10575 cur_mv =
10576 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10577 .this_mv;
10578 clamp_mv2(&cur_mv.as_mv, xd);
10579
10580 if (!mv_check_bounds(x, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010581#if CONFIG_EXT_INTER
10582 int_mv dummy_single_newmvs[2][TOTAL_REFS_PER_FRAME] = { { { 0 } },
10583 { { 0 } } };
10584 int dummy_single_newmvs_rate[2][TOTAL_REFS_PER_FRAME] = { { 0 },
10585 { 0 } };
Yaowu Xuc27fc142016-08-22 16:08:15 -070010586#else
10587 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Fergus Simpson4063a682017-02-28 16:52:22 -080010588#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010589
10590 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010591 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010592
10593// Point to variables that are not maintained between iterations
10594#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010595 args.single_newmvs = dummy_single_newmvs;
10596 args.single_newmvs_rate = dummy_single_newmvs_rate;
10597 args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
10598 args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
10599 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010600#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010601 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010602#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010603 tmp_alt_rd = handle_inter_mode(
10604 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10605 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010606// Prevent pointers from escaping local scope
10607#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010608 args.single_newmvs = NULL;
10609 args.single_newmvs_rate = NULL;
10610 args.compmode_interintra_cost = NULL;
10611 args.compmode_interinter_cost = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010612#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010613 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010614#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010615 }
10616
10617 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10618 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010619 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10620 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010621 tmp_rd_stats.rate +=
10622 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10623 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010624 }
10625
10626 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10627 mbmi->ref_mv_idx + idx_offset + 1 &&
10628 ref_idx < ref_set - 1) {
10629 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010630 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10631 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010632 tmp_rd_stats.rate +=
10633 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10634 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010635 }
10636
10637 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010638#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010639 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10640 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010641#else
Angie Chiang76159122016-11-09 12:13:22 -080010642 if (RDCOST(x->rdmult, x->rddiv,
10643 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10644 tmp_rd_stats.dist) <
10645 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010646 tmp_alt_rd =
10647 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010648 tmp_rd_stats.rate +
10649 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10650 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010651 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010652 tmp_alt_rd =
10653 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010654 tmp_rd_stats.rate +
10655 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10656 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10657 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010658#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010659 }
10660
10661 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010662 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010663 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010664 distortion2 = tmp_rd_stats.dist;
10665 skippable = tmp_rd_stats.skip;
10666 rate_y = tmp_rd_stats_y.rate;
10667 rate_uv = tmp_rd_stats_uv.rate;
10668 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010669 this_rd = tmp_alt_rd;
10670 tmp_ref_rd = tmp_alt_rd;
10671 backup_mbmi = *mbmi;
10672 backup_skip = x->skip;
10673#if CONFIG_VAR_TX
10674 for (i = 0; i < MAX_MB_PLANE; ++i)
10675 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10676 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010677#endif // CONFIG_VAR_TX
Yue Chen6e601e92016-12-05 18:19:00 -080010678#if CONFIG_EXT_INTER
10679 compmode_interintra_cost = tmp_compmode_interintra_cost;
10680 compmode_interinter_cost = tmp_compmode_interinter_cost;
Fergus Simpson4063a682017-02-28 16:52:22 -080010681#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010682 } else {
10683 *mbmi = backup_mbmi;
10684 x->skip = backup_skip;
10685 }
10686 }
10687
10688 frame_mv[NEARMV][ref_frame] = backup_mv;
10689 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10690 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10691#if CONFIG_VAR_TX
10692 for (i = 0; i < MAX_MB_PLANE; ++i)
10693 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10694 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010695#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010696 }
10697 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10698 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
10699#endif // CONFIG_REF_MV
10700
10701 if (this_rd == INT64_MAX) continue;
10702
Jingning Hanc41a5492017-02-24 11:18:52 -080010703#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010704 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010705#else
10706 if (mbmi->sb_type >= BLOCK_8X8)
10707 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010708#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010709
10710 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10711 }
10712
10713#if CONFIG_EXT_INTER
10714 rate2 += compmode_interintra_cost;
10715 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010716#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10717 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10718#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010719 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010720#endif // CONFIG_EXT_INTER
10721
10722 // Estimate the reference frame signaling cost and add it
10723 // to the rolling cost variable.
10724 if (comp_pred) {
10725 rate2 += ref_costs_comp[ref_frame];
10726#if CONFIG_EXT_REFS
10727 rate2 += ref_costs_comp[second_ref_frame];
10728#endif // CONFIG_EXT_REFS
10729 } else {
10730 rate2 += ref_costs_single[ref_frame];
10731 }
10732
Yue Chen69f18e12016-09-08 14:48:15 -070010733#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010734 if (ref_frame == INTRA_FRAME) {
10735#else
10736 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010737#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010738 if (skippable) {
10739 // Back out the coefficient coding costs
10740 rate2 -= (rate_y + rate_uv);
10741 rate_y = 0;
10742 rate_uv = 0;
10743 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010744 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010745 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010746#if CONFIG_REF_MV
10747 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10748 distortion2) <
10749 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
10750#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010751 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10752 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
Fergus Simpson4063a682017-02-28 16:52:22 -080010753#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010754 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010755 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010756 } else {
10757 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010758 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010759 distortion2 = total_sse;
10760 assert(total_sse >= 0);
10761 rate2 -= (rate_y + rate_uv);
10762 this_skip2 = 1;
10763 rate_y = 0;
10764 rate_uv = 0;
10765 }
10766 } else {
10767 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010768 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010769 }
10770
10771 // Calculate the final RD estimate for this mode.
10772 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010773#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010774 } else {
10775 this_skip2 = mbmi->skip;
10776 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10777 if (this_skip2) {
10778 rate_y = 0;
10779 rate_uv = 0;
10780 }
Yue Chen69f18e12016-09-08 14:48:15 -070010781#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010782 }
10783
Yaowu Xuc27fc142016-08-22 16:08:15 -070010784 if (ref_frame == INTRA_FRAME) {
10785 // Keep record of best intra rd
10786 if (this_rd < best_intra_rd) {
10787 best_intra_rd = this_rd;
10788 best_intra_mode = mbmi->mode;
10789 }
10790#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -050010791 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010792 if (this_rd < best_single_inter_rd) {
10793 best_single_inter_rd = this_rd;
10794 best_single_inter_ref = mbmi->ref_frame[0];
10795 }
10796#endif // CONFIG_EXT_INTER
10797 }
10798
10799 if (!disable_skip && ref_frame == INTRA_FRAME) {
10800 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010801 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010802 }
10803
10804 // Did this mode help.. i.e. is it the new best mode
10805 if (this_rd < best_rd || x->skip) {
10806 if (!mode_excluded) {
10807 // Note index of best mode so far
10808 best_mode_index = mode_index;
10809
10810 if (ref_frame == INTRA_FRAME) {
10811 /* required for left and above block mv */
10812 mbmi->mv[0].as_int = 0;
10813 } else {
10814 best_pred_sse = x->pred_sse[ref_frame];
10815 }
10816
10817 rd_cost->rate = rate2;
10818#if CONFIG_SUPERTX
10819 if (x->skip)
10820 *returnrate_nocoef = rate2;
10821 else
10822 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010823 *returnrate_nocoef -= av1_cost_bit(
10824 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10825 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10826 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010827#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010828 const MOTION_MODE motion_allowed = motion_mode_allowed(
10829#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10830 0, xd->global_motion,
10831#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10832 mi);
Yue Chen69f18e12016-09-08 14:48:15 -070010833#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010834 if (motion_allowed == WARPED_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010835#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010836 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010837#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Sarah Parker19234cc2017-03-10 16:43:25 -080010838 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010839 *returnrate_nocoef -=
10840 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
10841#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010842#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010843#endif // CONFIG_SUPERTX
10844 rd_cost->dist = distortion2;
10845 rd_cost->rdcost = this_rd;
10846 best_rd = this_rd;
10847 best_mbmode = *mbmi;
10848 best_skip2 = this_skip2;
10849 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010850 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10851 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010852 best_rate_uv = rate_uv;
10853
10854#if CONFIG_VAR_TX
10855 for (i = 0; i < MAX_MB_PLANE; ++i)
10856 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10857 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010858#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010859 }
10860 }
10861
10862 /* keep record of best compound/single-only prediction */
10863 if (!disable_skip && ref_frame != INTRA_FRAME) {
10864 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10865
10866 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10867 single_rate = rate2 - compmode_cost;
10868 hybrid_rate = rate2;
10869 } else {
10870 single_rate = rate2;
10871 hybrid_rate = rate2 + compmode_cost;
10872 }
10873
10874 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10875 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10876
10877 if (!comp_pred) {
10878 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10879 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10880 } else {
10881 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10882 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10883 }
10884 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10885 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10886 }
10887
Yaowu Xuc27fc142016-08-22 16:08:15 -070010888 if (x->skip && !comp_pred) break;
10889 }
10890
10891 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10892 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10893 is_inter_mode(best_mbmode.mode)) ||
10894 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10895 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010896 int skip_blk = 0;
10897 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010898
10899 x->use_default_inter_tx_type = 0;
10900 x->use_default_intra_tx_type = 0;
10901
10902 *mbmi = best_mbmode;
10903
10904 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10905
10906 // Select prediction reference frames.
10907 for (i = 0; i < MAX_MB_PLANE; i++) {
10908 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10909 if (has_second_ref(mbmi))
10910 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10911 }
10912
10913 if (is_inter_mode(mbmi->mode)) {
Yue Chen69f18e12016-09-08 14:48:15 -070010914#if CONFIG_WARPED_MOTION
10915 if (mbmi->motion_mode == WARPED_CAUSAL) {
Sarah Parker19234cc2017-03-10 16:43:25 -080010916 assert_motion_mode_valid(WARPED_CAUSAL,
10917#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10918 0, xd->global_motion,
10919#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10920 xd->mi[0]);
Yue Chen69f18e12016-09-08 14:48:15 -070010921 assert(!has_second_ref(mbmi));
10922
Fergus Simpsonf80a0582017-03-08 10:09:50 -080010923 int plane;
Yue Chen69f18e12016-09-08 14:48:15 -070010924 for (plane = 0; plane < 3; ++plane) {
10925 const struct macroblockd_plane *pd = &xd->plane[plane];
10926
10927 av1_warp_plane(&mbmi->wm_params[0],
10928#if CONFIG_AOM_HIGHBITDEPTH
10929 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
10930#endif // CONFIG_AOM_HIGHBITDEPTH
10931 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
10932 pd->pre[0].stride, pd->dst.buf,
10933 ((mi_col * MI_SIZE) >> pd->subsampling_x),
10934 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010935 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
10936 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
10937 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
10938 16, 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -070010939 }
10940 } else {
10941#endif // CONFIG_WARPED_MOTION
David Barkerac37fa32016-12-02 12:30:21 +000010942 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Yue Chen69f18e12016-09-08 14:48:15 -070010943#if CONFIG_WARPED_MOTION
10944 }
10945#endif // CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010946#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010947 if (mbmi->motion_mode == OBMC_CAUSAL) {
10948 assert_motion_mode_valid(OBMC_CAUSAL,
10949#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10950 0, cm->global_motion,
10951#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10952 xd->mi[0]);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010953 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010954 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10955 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010956 }
Yue Chencb60b182016-10-13 15:18:22 -070010957#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010958 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010959#if CONFIG_VAR_TX
10960 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010961 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010962 } else {
10963 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010964 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010965 for (idy = 0; idy < xd->n8_h; ++idy)
10966 for (idx = 0; idx < xd->n8_w; ++idx)
10967 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010968 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010969 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10970 }
10971
Angie Chiangb5dda482016-11-02 16:19:58 -070010972 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010973#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010974 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010975 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010976#endif // CONFIG_VAR_TX
10977 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010978 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010979 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010980 }
10981
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010982 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10983 (rd_stats_y.dist + rd_stats_uv.dist)) >
10984 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010985 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010986 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10987 rd_stats_uv.rate = 0;
10988 rd_stats_y.dist = rd_stats_y.sse;
10989 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010990 } else {
10991 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010992 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010993 }
10994
10995 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010996 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10997 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010998#if CONFIG_VAR_TX
10999 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080011000#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011001 best_mbmode.tx_type = mbmi->tx_type;
11002 best_mbmode.tx_size = mbmi->tx_size;
11003#if CONFIG_VAR_TX
11004 for (idy = 0; idy < xd->n8_h; ++idy)
11005 for (idx = 0; idx < xd->n8_w; ++idx)
11006 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
11007
11008 for (i = 0; i < MAX_MB_PLANE; ++i)
11009 memcpy(ctx->blk_skip[i], x->blk_skip[i],
11010 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070011011
11012 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080011013#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011014 rd_cost->rate +=
11015 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
11016 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011017 rd_cost->rdcost =
11018 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
11019 best_skip2 = skip_blk;
11020 }
11021 }
11022
Urvang Joshib100db72016-10-12 16:28:56 -070011023#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011024 // Only try palette mode when the best mode so far is an intra mode.
11025 if (cm->allow_screen_content_tools && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011026 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011027#if CONFIG_SUPERTX
11028 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011029#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080011030 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
11031 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070011032 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011033 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080011034 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011035 uint8_t *const best_palette_color_map =
11036 x->palette_buffer->best_palette_color_map;
11037 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080011038 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011039
11040 mbmi->mode = DC_PRED;
11041 mbmi->uv_mode = DC_PRED;
11042 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011043 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070011044 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080011045 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
11046 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
11047 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080011048 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
11049 memcpy(color_map, best_palette_color_map,
11050 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011051 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
11052 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070011053 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
11054 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011055 if (rate_uv_intra[uv_tx] == INT_MAX) {
11056 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070011057 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
11058 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011059 pmi_uv[uv_tx] = *pmi;
11060#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011061 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
11062#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011063#if CONFIG_FILTER_INTRA
11064 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
11065#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011066 }
11067 mbmi->uv_mode = mode_uv[uv_tx];
11068 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080011069 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011070 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
11071 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
11072 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080011073 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011074#if CONFIG_EXT_INTRA
11075 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011076#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011077#if CONFIG_FILTER_INTRA
11078 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
11079 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
11080 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
11081 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
11082 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
11083 }
11084#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011085 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
11086 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
11087 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011088 rate2 += ref_costs_single[INTRA_FRAME];
11089
11090 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011091 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011092#if CONFIG_SUPERTX
11093 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080011094#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011095 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011096 } else {
11097#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011098 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080011099#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011100 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011101 }
11102 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11103 if (this_rd < best_rd) {
11104 best_mode_index = 3;
11105 mbmi->mv[0].as_int = 0;
11106 rd_cost->rate = rate2;
11107#if CONFIG_SUPERTX
11108 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011109#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011110 rd_cost->dist = distortion2;
11111 rd_cost->rdcost = this_rd;
11112 best_rd = this_rd;
11113 best_mbmode = *mbmi;
11114 best_skip2 = 0;
11115 best_mode_skippable = skippable;
11116 }
11117 }
11118PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070011119#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011120
hui su5db97432016-10-14 16:10:14 -070011121#if CONFIG_FILTER_INTRA
11122 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070011123 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070011124 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070011125#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080011126 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070011127#endif // CONFIG_PALETTE
11128 !dc_skipped && best_mode_index >= 0 &&
11129 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070011130 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080011131 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
11132 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070011133#if CONFIG_EXT_INTRA
11134 uv_angle_delta,
11135#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070011136#if CONFIG_PALETTE
11137 pmi_uv, palette_ctx,
11138#endif // CONFIG_PALETTE
11139 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011140 &best_mode_index, &best_skip2, &best_mode_skippable,
11141#if CONFIG_SUPERTX
11142 returnrate_nocoef,
11143#endif // CONFIG_SUPERTX
11144 best_pred_rd, &best_mbmode, rd_cost);
11145 }
hui su5db97432016-10-14 16:10:14 -070011146#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011147
11148 // The inter modes' rate costs are not calculated precisely in some cases.
11149 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11150 // ZEROMV. Here, checks are added for those cases, and the mode decisions
11151 // are corrected.
11152 if (best_mbmode.mode == NEWMV
11153#if CONFIG_EXT_INTER
11154 || best_mbmode.mode == NEWFROMNEARMV || best_mbmode.mode == NEW_NEWMV
11155#endif // CONFIG_EXT_INTER
11156 ) {
11157 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11158 best_mbmode.ref_frame[1] };
11159 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011160 int_mv zeromv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011161#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -070011162 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011163#endif // CONFIG_REF_MV
11164#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011165 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11166 cm->allow_high_precision_mv, bsize,
11167 mi_col, mi_row, 0)
11168 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011169 zeromv[1].as_int = comp_pred_mode
11170 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11171 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011172 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011173 .as_int
11174 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011175#else
11176 zeromv[0].as_int = 0;
11177 zeromv[1].as_int = 0;
11178#endif // CONFIG_GLOBAL_MOTION
11179#if CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011180 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011181 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011182 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011183 : INT_MAX;
11184
11185 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11186 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11187 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11188 best_mbmode.mode = NEARMV;
11189 best_mbmode.ref_mv_idx = i;
11190 }
11191 }
11192
11193 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11194 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011195 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011196 best_mbmode.mode = ZEROMV;
11197 } else {
11198 int_mv nearestmv[2];
11199 int_mv nearmv[2];
11200
11201#if CONFIG_EXT_INTER
11202 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11203 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11204 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11205 } else {
11206 nearmv[0] = frame_mv[NEARMV][refs[0]];
11207 nearmv[1] = frame_mv[NEARMV][refs[1]];
11208 }
11209#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011210 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011211 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011212 : INT_MAX;
11213
11214 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11215 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11216 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11217
11218 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11219 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11220 best_mbmode.mode = NEARMV;
11221 best_mbmode.ref_mv_idx = i;
11222 }
11223 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011224#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011225 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11226 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11227 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11228 } else {
11229 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11230 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11231 }
11232
11233 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
11234 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
11235#if CONFIG_EXT_INTER
11236 best_mbmode.mode = NEAREST_NEARESTMV;
11237 else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
11238 nearmv[1].as_int == best_mbmode.mv[1].as_int)
11239 best_mbmode.mode = NEAREST_NEARMV;
11240 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11241 nearestmv[1].as_int == best_mbmode.mv[1].as_int)
11242 best_mbmode.mode = NEAR_NEARESTMV;
11243 else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11244 nearmv[1].as_int == best_mbmode.mv[1].as_int)
11245 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011246 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11247 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011248 best_mbmode.mode = ZERO_ZEROMV;
11249#else
11250 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011251 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11252 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011253 best_mbmode.mode = ZEROMV;
11254#endif // CONFIG_EXT_INTER
11255 }
11256#else
11257#if CONFIG_EXT_INTER
11258 if (!comp_pred_mode) {
11259#endif // CONFIG_EXT_INTER
11260 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
11261 ((comp_pred_mode &&
11262 frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
11263 !comp_pred_mode))
11264 best_mbmode.mode = NEARESTMV;
11265 else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
11266 ((comp_pred_mode &&
11267 frame_mv[NEARMV][refs[1]].as_int ==
11268 best_mbmode.mv[1].as_int) ||
11269 !comp_pred_mode))
11270 best_mbmode.mode = NEARMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011271 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11272 ((comp_pred_mode &&
11273 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -070011274 !comp_pred_mode))
11275 best_mbmode.mode = ZEROMV;
11276#if CONFIG_EXT_INTER
11277 } else {
Sarah Parkerc2d38712017-01-24 15:15:41 -080011278 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11279 best_mbmode.ref_frame[1] };
11280 int_mv zeromv[2];
11281#if CONFIG_GLOBAL_MOTION
11282 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011283 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011284 bsize, mi_col, mi_row, 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -080011285 .as_int;
Sarah Parkerae7c4582017-02-28 16:30:30 -080011286 zeromv[1].as_int = comp_pred_mode
11287 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11288 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011289 bsize, mi_col, mi_row, 0)
Sarah Parkerae7c4582017-02-28 16:30:30 -080011290 .as_int
11291 : 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011292#else
11293 zeromv[0].as_int = 0;
11294 zeromv[1].as_int = 0;
11295#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011296 if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
11297 best_mbmode.mv[0].as_int &&
11298 frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
11299 best_mbmode.mv[1].as_int)
11300 best_mbmode.mode = NEAREST_NEARESTMV;
11301 else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
11302 best_mbmode.mv[0].as_int &&
11303 frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
11304 best_mbmode.mv[1].as_int)
11305 best_mbmode.mode = NEAREST_NEARMV;
11306 else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
11307 best_mbmode.mv[0].as_int &&
11308 frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
11309 best_mbmode.mv[1].as_int)
11310 best_mbmode.mode = NEAR_NEARESTMV;
11311 else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
11312 best_mbmode.mv[0].as_int &&
11313 frame_mv[NEAR_NEARMV][refs[1]].as_int ==
11314 best_mbmode.mv[1].as_int)
11315 best_mbmode.mode = NEAR_NEARMV;
Sarah Parkerc2d38712017-01-24 15:15:41 -080011316 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11317 best_mbmode.mv[1].as_int == zeromv[1].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011318 best_mbmode.mode = ZERO_ZEROMV;
11319 }
11320#endif // CONFIG_EXT_INTER
Fergus Simpson4063a682017-02-28 16:52:22 -080011321#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011322 }
11323
11324#if CONFIG_REF_MV
David Barkercdcac6d2016-12-01 17:04:16 +000011325 {
Jingning Han731af492016-11-17 11:53:23 -080011326 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11327 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011328 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011329 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011330#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011331 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11332 best_mbmode.ref_frame[1] };
11333 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011334 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011335 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011336 .as_int;
11337 zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
David Barker45390c12017-02-20 14:44:40 +000011338 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011339 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011340 .as_int;
11341 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11342 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11343#else
11344 zeromv[0].as_int = zeromv[1].as_int = 0;
11345#endif // CONFIG_GLOBAL_MOTION
11346 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11347 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11348#if CONFIG_EXT_INTER
11349 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11350#else
Emil Keyder01770b32017-01-20 18:03:11 -050011351 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011352 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11353#endif // CONFIG_EXT_INTER
11354 ) {
11355 best_mbmode.mode = ZEROMV;
11356 }
David Barker68e6e862016-11-24 15:10:15 +000011357 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011358 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011359#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011360
11361 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11362 rd_cost->rate = INT_MAX;
11363 rd_cost->rdcost = INT64_MAX;
11364 return;
11365 }
11366
Yaowu Xuc27fc142016-08-22 16:08:15 -070011367#if CONFIG_DUAL_FILTER
11368 assert((cm->interp_filter == SWITCHABLE) ||
11369 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11370 !is_inter_block(&best_mbmode));
11371 assert((cm->interp_filter == SWITCHABLE) ||
11372 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11373 !is_inter_block(&best_mbmode));
11374 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11375 assert((cm->interp_filter == SWITCHABLE) ||
11376 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11377 !is_inter_block(&best_mbmode));
11378 assert((cm->interp_filter == SWITCHABLE) ||
11379 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11380 !is_inter_block(&best_mbmode));
11381 }
11382#else
11383 assert((cm->interp_filter == SWITCHABLE) ||
11384 (cm->interp_filter == best_mbmode.interp_filter) ||
11385 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011386#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011387
11388 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011389 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11390 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011391
11392 // macroblock modes
11393 *mbmi = best_mbmode;
11394 x->skip |= best_skip2;
11395
Yue Chen19e7aa82016-11-30 14:05:39 -080011396// Note: this section is needed since the mode may have been forced to
11397// ZEROMV by the all-zero mode handling of ref-mv.
11398#if CONFIG_GLOBAL_MOTION
11399 if (mbmi->mode == ZEROMV
11400#if CONFIG_EXT_INTER
11401 || mbmi->mode == ZERO_ZEROMV
11402#endif // CONFIG_EXT_INTER
11403 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011404#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11405 // Correct the motion mode for ZEROMV
11406 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11407#if SEPARATE_GLOBAL_MOTION
11408 0, xd->global_motion,
11409#endif // SEPARATE_GLOBAL_MOTION
11410 xd->mi[0]);
11411 if (mbmi->motion_mode > last_motion_mode_allowed)
11412 mbmi->motion_mode = last_motion_mode_allowed;
11413#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11414
11415 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011416 if (is_nontrans_global_motion(xd)) {
11417#if CONFIG_DUAL_FILTER
11418 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11419 ? EIGHTTAP_REGULAR
11420 : cm->interp_filter;
11421 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11422 ? EIGHTTAP_REGULAR
11423 : cm->interp_filter;
11424#else
11425 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11426 : cm->interp_filter;
11427#endif // CONFIG_DUAL_FILTER
11428 }
11429 }
11430#endif // CONFIG_GLOBAL_MOTION
11431
Yaowu Xuc27fc142016-08-22 16:08:15 -070011432#if CONFIG_REF_MV
11433 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11434 if (mbmi->mode != NEWMV)
11435 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11436 else
11437 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11438 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011439#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011440
11441 for (i = 0; i < REFERENCE_MODES; ++i) {
11442 if (best_pred_rd[i] == INT64_MAX)
11443 best_pred_diff[i] = INT_MIN;
11444 else
11445 best_pred_diff[i] = best_rd - best_pred_rd[i];
11446 }
11447
11448 x->skip |= best_mode_skippable;
11449
11450 assert(best_mode_index >= 0);
11451
11452 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11453 best_mode_skippable);
11454
Urvang Joshib100db72016-10-12 16:28:56 -070011455#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011456 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11457 restore_uv_color_map(cpi, x);
11458 }
Urvang Joshib100db72016-10-12 16:28:56 -070011459#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011460}
11461
Urvang Joshi52648442016-10-13 17:27:51 -070011462void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11463 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011464 int mi_row, int mi_col,
Urvang Joshi52648442016-10-13 17:27:51 -070011465 RD_COST *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011466 PICK_MODE_CONTEXT *ctx,
11467 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011468 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011469 MACROBLOCKD *const xd = &x->e_mbd;
11470 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11471 unsigned char segment_id = mbmi->segment_id;
11472 const int comp_pred = 0;
11473 int i;
11474 int64_t best_pred_diff[REFERENCE_MODES];
11475 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11476 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011477 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011478 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011479 int64_t this_rd = INT64_MAX;
11480 int rate2 = 0;
11481 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011482 (void)mi_row;
11483 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011484
11485 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11486 &comp_mode_p);
11487
11488 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11489 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11490 x->pred_mv_sad[i] = INT_MAX;
11491
11492 rd_cost->rate = INT_MAX;
11493
11494 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11495
Urvang Joshib100db72016-10-12 16:28:56 -070011496#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011497 mbmi->palette_mode_info.palette_size[0] = 0;
11498 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011499#endif // CONFIG_PALETTE
11500
hui su5db97432016-10-14 16:10:14 -070011501#if CONFIG_FILTER_INTRA
11502 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11503 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11504#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011505 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011506 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011507 mbmi->uv_mode = DC_PRED;
11508 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011509 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011510#if CONFIG_GLOBAL_MOTION
11511 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011512 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011513 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11514 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011515 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011516#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011517 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011518#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011519 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011520 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011521
Yaowu Xuc27fc142016-08-22 16:08:15 -070011522#if CONFIG_REF_MV
11523 mbmi->ref_mv_idx = 0;
11524 mbmi->pred_mv[0].as_int = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011525#endif // CONFIG_REF_MV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011526
11527 if (cm->interp_filter != BILINEAR) {
11528 best_filter = EIGHTTAP_REGULAR;
11529 if (cm->interp_filter == SWITCHABLE &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011530 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11531 int rs;
11532 int best_rs = INT_MAX;
11533 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11534#if CONFIG_DUAL_FILTER
11535 int k;
11536 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11537#else
11538 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011539#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011540 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011541 if (rs < best_rs) {
11542 best_rs = rs;
11543#if CONFIG_DUAL_FILTER
11544 best_filter = mbmi->interp_filter[0];
11545#else
11546 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011547#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011548 }
11549 }
11550 }
11551 }
11552 // Set the appropriate filter
11553 if (cm->interp_filter == SWITCHABLE) {
11554#if CONFIG_DUAL_FILTER
11555 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
11556#else
11557 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011558#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011559 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011560 } else {
11561#if CONFIG_DUAL_FILTER
11562 for (i = 0; i < 4; ++i) mbmi->interp_filter[0] = cm->interp_filter;
11563#else
11564 mbmi->interp_filter = cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011565#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011566 }
11567
11568 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011569 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011570
11571 // Estimate the reference frame signaling cost and add it
11572 // to the rolling cost variable.
11573 rate2 += ref_costs_single[LAST_FRAME];
11574 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11575
11576 rd_cost->rate = rate2;
11577 rd_cost->dist = distortion2;
11578 rd_cost->rdcost = this_rd;
11579
11580 if (this_rd >= best_rd_so_far) {
11581 rd_cost->rate = INT_MAX;
11582 rd_cost->rdcost = INT64_MAX;
11583 return;
11584 }
11585
11586#if CONFIG_DUAL_FILTER
11587 assert((cm->interp_filter == SWITCHABLE) ||
11588 (cm->interp_filter == mbmi->interp_filter[0]));
11589#else
11590 assert((cm->interp_filter == SWITCHABLE) ||
11591 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011592#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011593
Yaowu Xuf883b422016-08-30 14:01:10 -070011594 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11595 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011596
Yaowu Xuf883b422016-08-30 14:01:10 -070011597 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011598
11599 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11600}
11601
Urvang Joshi52648442016-10-13 17:27:51 -070011602void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11603 TileDataEnc *tile_data, struct macroblock *x,
11604 int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -070011605 struct RD_COST *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011606#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011607 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011608#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011609 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11610 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011611 const AV1_COMMON *const cm = &cpi->common;
11612 const RD_OPT *const rd_opt = &cpi->rd;
11613 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011614 MACROBLOCKD *const xd = &x->e_mbd;
11615 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11616 const struct segmentation *const seg = &cm->seg;
11617 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11618 unsigned char segment_id = mbmi->segment_id;
11619 int comp_pred, i;
11620 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11621 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11622 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11623 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011624 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011625#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011626 AOM_LAST2_FLAG,
11627 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011628#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011629 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011630#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011631 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011632#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011633 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011634 };
11635 int64_t best_rd = best_rd_so_far;
11636 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11637 int64_t best_pred_diff[REFERENCE_MODES];
11638 int64_t best_pred_rd[REFERENCE_MODES];
11639 MB_MODE_INFO best_mbmode;
11640 int ref_index, best_ref_index = 0;
11641 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11642 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011643 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011644#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011645 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011646#else
James Zern7b9407a2016-05-18 23:48:05 -070011647 InterpFilter tmp_best_filter = SWITCHABLE;
Fergus Simpson4063a682017-02-28 16:52:22 -080011648#endif // CONFIG_DUAL_FILTER
Jingning Han3f167252016-06-07 16:11:42 -070011649 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11650 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011651 int skip_uv;
11652 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011653 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011654 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
11655#if CONFIG_EXT_INTER
11656 int_mv seg_mvs[4][2][TOTAL_REFS_PER_FRAME];
11657#else
11658 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
11659#endif // CONFIG_EXT_INTER
11660 b_mode_info best_bmodes[4];
11661 int best_skip2 = 0;
11662 int ref_frame_skip_mask[2] = { 0 };
11663 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011664 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011665#if CONFIG_PVQ
11666 od_rollback_buffer pre_buf;
11667
11668 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011669#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070011670
11671#if CONFIG_SUPERTX
11672 best_rd_so_far = INT64_MAX;
11673 best_rd = best_rd_so_far;
11674 best_yrd = best_rd_so_far;
11675#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011676 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011677
hui su5db97432016-10-14 16:10:14 -070011678#if CONFIG_FILTER_INTRA
11679 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11680 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11681#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011682 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011683#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -080011684 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011685 mbmi->use_wedge_interintra = 0;
11686#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011687#if CONFIG_WARPED_MOTION
11688 mbmi->num_proj_ref[0] = 0;
11689 mbmi->num_proj_ref[1] = 0;
11690#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011691
11692 for (i = 0; i < 4; i++) {
11693 int j;
11694#if CONFIG_EXT_INTER
11695 int k;
11696
11697 for (k = 0; k < 2; k++)
11698 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11699 seg_mvs[i][k][j].as_int = INVALID_MV;
11700#else
11701 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11702 seg_mvs[i][j].as_int = INVALID_MV;
11703#endif // CONFIG_EXT_INTER
11704 }
11705
11706 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11707 &comp_mode_p);
11708
11709 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11710 rate_uv_intra = INT_MAX;
11711
11712 rd_cost->rate = INT_MAX;
11713#if CONFIG_SUPERTX
11714 *returnrate_nocoef = INT_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -080011715#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011716
11717 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11718 x->mbmi_ext->mode_context[ref_frame] = 0;
11719#if CONFIG_REF_MV && CONFIG_EXT_INTER
11720 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
11721#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
11722 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11723 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11724 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11725 } else {
11726 ref_frame_skip_mask[0] |= (1 << ref_frame);
11727 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11728 }
11729 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11730#if CONFIG_EXT_INTER
11731 frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
11732#endif // CONFIG_EXT_INTER
11733 frame_mv[ZEROMV][ref_frame].as_int = 0;
11734 }
11735
Urvang Joshib100db72016-10-12 16:28:56 -070011736#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011737 mbmi->palette_mode_info.palette_size[0] = 0;
11738 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011739#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011740
11741 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11742 int mode_excluded = 0;
11743 int64_t this_rd = INT64_MAX;
11744 int disable_skip = 0;
11745 int compmode_cost = 0;
11746 int rate2 = 0, rate_y = 0, rate_uv = 0;
11747 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11748 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011749 int this_skip2 = 0;
11750 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011751
Yushin Cho77bba8d2016-11-04 16:36:56 -070011752#if CONFIG_PVQ
11753 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011754#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -070011755
Yaowu Xuf883b422016-08-30 14:01:10 -070011756 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11757 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011758
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011759#if CONFIG_REF_MV
11760 mbmi->ref_mv_idx = 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011761#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011762
Yaowu Xuc27fc142016-08-22 16:08:15 -070011763 // Look at the reference frame of the best mode so far and set the
11764 // skip mask to look at a subset of the remaining modes.
11765 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11766 if (ref_index == 3) {
11767 switch (best_mbmode.ref_frame[0]) {
11768 case INTRA_FRAME: break;
11769 case LAST_FRAME:
11770 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11771#if CONFIG_EXT_REFS
11772 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11773 (1 << BWDREF_FRAME) |
11774#endif // CONFIG_EXT_REFS
11775 (1 << ALTREF_FRAME);
11776 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11777 break;
11778#if CONFIG_EXT_REFS
11779 case LAST2_FRAME:
11780 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11781 (1 << GOLDEN_FRAME) |
11782 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11783 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11784 break;
11785 case LAST3_FRAME:
11786 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11787 (1 << GOLDEN_FRAME) |
11788 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11789 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11790 break;
11791#endif // CONFIG_EXT_REFS
11792 case GOLDEN_FRAME:
11793 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11794#if CONFIG_EXT_REFS
11795 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11796 (1 << BWDREF_FRAME) |
11797#endif // CONFIG_EXT_REFS
11798 (1 << ALTREF_FRAME);
11799 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11800 break;
11801#if CONFIG_EXT_REFS
11802 case BWDREF_FRAME:
11803 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11804 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11805 (1 << ALTREF_FRAME);
11806 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11807 break;
11808#endif // CONFIG_EXT_REFS
11809 case ALTREF_FRAME:
11810 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11811#if CONFIG_EXT_REFS
11812 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11813 (1 << BWDREF_FRAME) |
11814#endif // CONFIG_EXT_REFS
11815 (1 << GOLDEN_FRAME);
11816#if CONFIG_EXT_REFS
11817 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11818#endif // CONFIG_EXT_REFS
11819 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011820 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011821 case TOTAL_REFS_PER_FRAME:
11822 assert(0 && "Invalid Reference frame");
11823 break;
11824 }
11825 }
11826 }
11827
11828 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011829 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011830 continue;
11831
11832 // Test best rd so far against threshold for trying this mode.
11833 if (!internal_active_edge &&
11834 rd_less_than_thresh(best_rd,
11835 rd_opt->threshes[segment_id][bsize][ref_index],
11836 tile_data->thresh_freq_fact[bsize][ref_index]))
11837 continue;
11838
11839 comp_pred = second_ref_frame > INTRA_FRAME;
11840 if (comp_pred) {
11841 if (!cpi->allow_comp_inter_inter) continue;
11842 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11843 // Do not allow compound prediction if the segment level reference frame
11844 // feature is in use as in this case there can only be one reference.
11845 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11846
11847 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11848 best_mbmode.ref_frame[0] == INTRA_FRAME)
11849 continue;
11850 }
11851
11852 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11853 // sub8x8 blocks.
11854 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011855 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011856 continue;
11857
11858 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011859 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011860 continue;
11861
11862 if (comp_pred)
11863 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11864 else if (ref_frame != INTRA_FRAME)
11865 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11866
11867 // If the segment reference frame feature is enabled....
11868 // then do nothing if the current ref frame is not allowed..
11869 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11870 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11871 continue;
11872 // Disable this drop out case if the ref frame
11873 // segment level feature is enabled for this segment. This is to
11874 // prevent the possibility that we end up unable to pick any mode.
11875 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11876 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11877 // unless ARNR filtering is enabled in which case we want
11878 // an unfiltered alternative. We allow near/nearest as well
11879 // because they may result in zero-zero MVs but be cheaper.
11880 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11881 continue;
11882 }
11883
11884 mbmi->tx_size = TX_4X4;
11885 mbmi->uv_mode = DC_PRED;
11886 mbmi->ref_frame[0] = ref_frame;
11887 mbmi->ref_frame[1] = second_ref_frame;
11888// Evaluate all sub-pel filters irrespective of whether we can use
11889// them for this frame.
11890#if CONFIG_DUAL_FILTER
11891 for (i = 0; i < 4; ++i)
11892 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11893 ? EIGHTTAP_REGULAR
11894 : cm->interp_filter;
11895#else
11896 mbmi->interp_filter =
11897 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011898#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011899 x->skip = 0;
11900 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11901
11902 // Select prediction reference frames.
11903 for (i = 0; i < MAX_MB_PLANE; i++) {
11904 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11905 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11906 }
11907
11908#if CONFIG_VAR_TX
11909 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011910 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -080011911#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011912
11913 if (ref_frame == INTRA_FRAME) {
11914 int rate;
11915 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011916 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011917 continue;
11918 rate2 += rate;
11919 rate2 += intra_cost_penalty;
11920 distortion2 += distortion_y;
11921
11922 if (rate_uv_intra == INT_MAX) {
11923 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11924 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11925 }
11926 rate2 += rate_uv_intra;
11927 rate_uv = rate_uv_tokenonly;
11928 distortion2 += dist_uv;
11929 distortion_uv = dist_uv;
11930 mbmi->uv_mode = mode_uv;
11931 } else {
11932 int rate;
11933 int64_t distortion;
11934 int64_t this_rd_thresh;
11935 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11936 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11937 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11938 int tmp_best_skippable = 0;
11939 int switchable_filter_index;
11940 int_mv *second_ref =
11941 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11942 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11943 MB_MODE_INFO tmp_best_mbmode;
11944#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011945 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011946#else
11947 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
Fergus Simpson4063a682017-02-28 16:52:22 -080011948#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011949 int pred_exists = 0;
11950 int uv_skippable;
11951#if CONFIG_EXT_INTER
11952 int_mv compound_seg_newmvs[4][2];
11953 for (i = 0; i < 4; i++) {
11954 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11955 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11956 }
11957#endif // CONFIG_EXT_INTER
11958
11959 this_rd_thresh = (ref_frame == LAST_FRAME)
11960 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11961 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11962#if CONFIG_EXT_REFS
11963 this_rd_thresh = (ref_frame == LAST2_FRAME)
11964 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11965 : this_rd_thresh;
11966 this_rd_thresh = (ref_frame == LAST3_FRAME)
11967 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11968 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011969 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11970 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11971 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011972#endif // CONFIG_EXT_REFS
11973 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11974 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11975 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011976
11977 // TODO(any): Add search of the tx_type to improve rd performance at the
11978 // expense of speed.
11979 mbmi->tx_type = DCT_DCT;
11980
11981 if (cm->interp_filter != BILINEAR) {
11982#if CONFIG_DUAL_FILTER
11983 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11984 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11985 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11986 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11987#else
11988 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011989#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011990 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11991#if CONFIG_DUAL_FILTER
11992 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11993#else
11994 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011995#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011996 } else if (sf->adaptive_pred_interp_filter == 1 &&
11997 ctx->pred_interp_filter < SWITCHABLE) {
11998#if CONFIG_DUAL_FILTER
11999 tmp_best_filter[0] = ctx->pred_interp_filter;
12000#else
12001 tmp_best_filter = ctx->pred_interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080012002#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012003 } else if (sf->adaptive_pred_interp_filter == 2) {
12004#if CONFIG_DUAL_FILTER
12005 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
12006 ? ctx->pred_interp_filter
12007 : 0;
12008#else
12009 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
12010 ? ctx->pred_interp_filter
12011 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080012012#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012013 } else {
12014#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080012015 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012016#else
Angie Chiang5678ad92016-11-21 09:38:40 -080012017 const int filter_set_size = SWITCHABLE_FILTERS;
Fergus Simpson4063a682017-02-28 16:52:22 -080012018#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012019 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080012020 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012021 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012022 int newbest, rs;
12023 int64_t rs_rd;
12024 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
12025#if CONFIG_DUAL_FILTER
12026 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
12027 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
12028 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
12029 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
12030#else
12031 mbmi->interp_filter = switchable_filter_index;
Fergus Simpson4063a682017-02-28 16:52:22 -080012032#endif // CONFIG_DUAL_FILTER
Yushin Cho482016d2017-01-06 14:06:13 -080012033 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070012034 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
12035 &rate, &rate_y, &distortion, &skippable, &total_sse,
12036 (int)this_rd_thresh, seg_mvs,
12037#if CONFIG_EXT_INTER
12038 compound_seg_newmvs,
12039#endif // CONFIG_EXT_INTER
12040 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012041 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070012042 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012043 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
12044 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
12045
12046 newbest = (tmp_rd < tmp_best_rd);
12047 if (newbest) {
12048#if CONFIG_DUAL_FILTER
12049 tmp_best_filter[0] = mbmi->interp_filter[0];
12050 tmp_best_filter[1] = mbmi->interp_filter[1];
12051 tmp_best_filter[2] = mbmi->interp_filter[2];
12052 tmp_best_filter[3] = mbmi->interp_filter[3];
12053#else
12054 tmp_best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080012055#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012056 tmp_best_rd = tmp_rd;
12057 }
12058 if ((newbest && cm->interp_filter == SWITCHABLE) ||
12059 (
12060#if CONFIG_DUAL_FILTER
12061 mbmi->interp_filter[0] == cm->interp_filter
12062#else
12063 mbmi->interp_filter == cm->interp_filter
Fergus Simpson4063a682017-02-28 16:52:22 -080012064#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012065 && cm->interp_filter != SWITCHABLE)) {
12066 tmp_best_rdu = tmp_rd;
12067 tmp_best_rate = rate;
12068 tmp_best_ratey = rate_y;
12069 tmp_best_distortion = distortion;
12070 tmp_best_sse = total_sse;
12071 tmp_best_skippable = skippable;
12072 tmp_best_mbmode = *mbmi;
12073 for (i = 0; i < 4; i++) {
12074 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
12075 }
12076 pred_exists = 1;
12077 }
12078 } // switchable_filter_index loop
12079 }
12080 }
12081
12082 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
12083
12084#if CONFIG_DUAL_FILTER
12085 mbmi->interp_filter[0] =
12086 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
12087 : cm->interp_filter);
12088 mbmi->interp_filter[1] =
12089 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
12090 : cm->interp_filter);
12091 mbmi->interp_filter[2] =
12092 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
12093 : cm->interp_filter);
12094 mbmi->interp_filter[3] =
12095 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
12096 : cm->interp_filter);
12097#else
12098 mbmi->interp_filter =
12099 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
12100 : cm->interp_filter);
Fergus Simpson4063a682017-02-28 16:52:22 -080012101#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012102
12103 if (!pred_exists) {
12104 // Handles the special case when a filter that is not in the
12105 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080012106 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070012107 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
12108 &rate, &rate_y, &distortion, &skippable, &total_sse,
12109 (int)this_rd_thresh, seg_mvs,
12110#if CONFIG_EXT_INTER
12111 compound_seg_newmvs,
12112#endif // CONFIG_EXT_INTER
12113 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012114 if (tmp_rd == INT64_MAX) continue;
12115 } else {
12116 total_sse = tmp_best_sse;
12117 rate = tmp_best_rate;
12118 rate_y = tmp_best_ratey;
12119 distortion = tmp_best_distortion;
12120 skippable = tmp_best_skippable;
12121 *mbmi = tmp_best_mbmode;
12122 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
12123 }
12124 // Add in the cost of the transform type
12125 if (!xd->lossless[mbmi->segment_id]) {
12126 int rate_tx_type = 0;
12127#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080012128 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
12129 1) {
12130 const int eset =
12131 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012132 rate_tx_type =
12133 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
12134 }
12135#else
12136 if (mbmi->tx_size < TX_32X32) {
12137 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
12138 }
Fergus Simpson4063a682017-02-28 16:52:22 -080012139#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012140 rate += rate_tx_type;
12141 rate_y += rate_tx_type;
12142 }
12143
12144 rate2 += rate;
12145 distortion2 += distortion;
12146
12147 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070012148 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012149
12150 if (!mode_excluded)
12151 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
12152 : cm->reference_mode == COMPOUND_REFERENCE;
12153
Yaowu Xuf883b422016-08-30 14:01:10 -070012154 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012155
12156 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070012157 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012158 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
12159
12160 if (tmp_best_rdu > 0) {
12161 // If even the 'Y' rd value of split is higher than best so far
12162 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070012163 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070012164 RD_STATS rd_stats_uv;
David Barkerac37fa32016-12-02 12:30:21 +000012165 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
12166 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012167#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012168 is_cost_valid_uv =
12169 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080012170#else
12171 is_cost_valid_uv =
12172 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Fergus Simpson4063a682017-02-28 16:52:22 -080012173#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012174 rate_uv = rd_stats_uv.rate;
12175 distortion_uv = rd_stats_uv.dist;
12176 uv_skippable = rd_stats_uv.skip;
12177 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080012178
Angie Chiangb5dda482016-11-02 16:19:58 -070012179 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012180 rate2 += rate_uv;
12181 distortion2 += distortion_uv;
12182 skippable = skippable && uv_skippable;
12183 total_sse += uv_sse;
12184 } else {
12185 continue;
12186 }
12187 }
12188
12189 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
12190
12191 // Estimate the reference frame signaling cost and add it
12192 // to the rolling cost variable.
12193 if (second_ref_frame > INTRA_FRAME) {
12194 rate2 += ref_costs_comp[ref_frame];
12195#if CONFIG_EXT_REFS
12196 rate2 += ref_costs_comp[second_ref_frame];
12197#endif // CONFIG_EXT_REFS
12198 } else {
12199 rate2 += ref_costs_single[ref_frame];
12200 }
12201
12202 if (!disable_skip) {
12203 // Skip is never coded at the segment level for sub8x8 blocks and instead
12204 // always coded in the bitstream at the mode info level.
12205
12206 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
12207 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
12208 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
12209 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012210 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012211 } else {
12212 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070012213 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012214 distortion2 = total_sse;
12215 assert(total_sse >= 0);
12216 rate2 -= (rate_y + rate_uv);
12217 rate_y = 0;
12218 rate_uv = 0;
12219 this_skip2 = 1;
12220 }
12221 } else {
12222 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012223 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012224 }
12225
12226 // Calculate the final RD estimate for this mode.
12227 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
12228 }
12229
12230 if (!disable_skip && ref_frame == INTRA_FRAME) {
12231 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070012232 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012233 }
12234
12235 // Did this mode help.. i.e. is it the new best mode
12236 if (this_rd < best_rd || x->skip) {
12237 if (!mode_excluded) {
12238 // Note index of best mode so far
12239 best_ref_index = ref_index;
12240
12241 if (ref_frame == INTRA_FRAME) {
12242 /* required for left and above block mv */
12243 mbmi->mv[0].as_int = 0;
12244 }
12245
12246 rd_cost->rate = rate2;
12247#if CONFIG_SUPERTX
12248 *returnrate_nocoef = rate2 - rate_y - rate_uv;
12249 if (!disable_skip)
12250 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070012251 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
12252 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
12253 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012254 assert(*returnrate_nocoef > 0);
12255#endif // CONFIG_SUPERTX
12256 rd_cost->dist = distortion2;
12257 rd_cost->rdcost = this_rd;
12258 best_rd = this_rd;
12259 best_yrd =
12260 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
12261 best_mbmode = *mbmi;
12262 best_skip2 = this_skip2;
12263
12264#if CONFIG_VAR_TX
12265 for (i = 0; i < MAX_MB_PLANE; ++i)
12266 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080012267#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012268
12269 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070012270 }
12271 }
12272
12273 /* keep record of best compound/single-only prediction */
12274 if (!disable_skip && ref_frame != INTRA_FRAME) {
12275 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
12276
12277 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
12278 single_rate = rate2 - compmode_cost;
12279 hybrid_rate = rate2;
12280 } else {
12281 single_rate = rate2;
12282 hybrid_rate = rate2 + compmode_cost;
12283 }
12284
12285 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
12286 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
12287
12288 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
12289 best_pred_rd[SINGLE_REFERENCE] = single_rd;
12290 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
12291 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
12292
12293 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
12294 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
12295 }
12296
Yaowu Xuc27fc142016-08-22 16:08:15 -070012297 if (x->skip && !comp_pred) break;
12298 }
12299
12300 if (best_rd >= best_rd_so_far) {
12301 rd_cost->rate = INT_MAX;
12302 rd_cost->rdcost = INT64_MAX;
12303#if CONFIG_SUPERTX
12304 *returnrate_nocoef = INT_MAX;
12305#endif // CONFIG_SUPERTX
12306 return;
12307 }
12308
Yaowu Xuc27fc142016-08-22 16:08:15 -070012309 if (best_rd == INT64_MAX) {
12310 rd_cost->rate = INT_MAX;
12311 rd_cost->dist = INT64_MAX;
12312 rd_cost->rdcost = INT64_MAX;
12313#if CONFIG_SUPERTX
12314 *returnrate_nocoef = INT_MAX;
12315#endif // CONFIG_SUPERTX
12316 return;
12317 }
12318
12319#if CONFIG_DUAL_FILTER
12320 assert((cm->interp_filter == SWITCHABLE) ||
12321 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12322 !is_inter_block(&best_mbmode));
12323#else
12324 assert((cm->interp_filter == SWITCHABLE) ||
12325 (cm->interp_filter == best_mbmode.interp_filter) ||
12326 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080012327#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012328
Yaowu Xuf883b422016-08-30 14:01:10 -070012329 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12330 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012331
12332 // macroblock modes
12333 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012334#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012335 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080012336#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012337
12338 x->skip |= best_skip2;
12339 if (!is_inter_block(&best_mbmode)) {
12340 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12341 } else {
12342 for (i = 0; i < 4; ++i)
12343 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12344
Yaowu Xuc27fc142016-08-22 16:08:15 -070012345#if CONFIG_REF_MV
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012346 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12347 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Fergus Simpson4063a682017-02-28 16:52:22 -080012348#endif // CONFIG_REF_MV
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012349 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12350 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012351 }
12352
Yue Chen19e7aa82016-11-30 14:05:39 -080012353// Note: this section is needed since the mode may have been forced to ZEROMV
12354#if CONFIG_GLOBAL_MOTION
12355 if (mbmi->mode == ZEROMV
12356#if CONFIG_EXT_INTER
12357 || mbmi->mode == ZERO_ZEROMV
12358#endif // CONFIG_EXT_INTER
12359 ) {
12360 if (is_nontrans_global_motion(xd)) {
12361#if CONFIG_DUAL_FILTER
12362 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12363 ? EIGHTTAP_REGULAR
12364 : cm->interp_filter;
12365 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12366 ? EIGHTTAP_REGULAR
12367 : cm->interp_filter;
12368#else
12369 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12370 : cm->interp_filter;
12371#endif // CONFIG_DUAL_FILTER
12372 }
12373 }
12374#endif // CONFIG_GLOBAL_MOTION
12375
Yaowu Xuc27fc142016-08-22 16:08:15 -070012376 for (i = 0; i < REFERENCE_MODES; ++i) {
12377 if (best_pred_rd[i] == INT64_MAX)
12378 best_pred_diff[i] = INT_MIN;
12379 else
12380 best_pred_diff[i] = best_rd - best_pred_rd[i];
12381 }
12382
12383 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12384}
12385
Yue Chencb60b182016-10-13 15:18:22 -070012386#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012387// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012388//
12389// The OBMC predictor is computed as:
12390//
12391// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012392// AOM_BLEND_A64(Mh(x),
12393// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012394// PLeft(x, y))
12395//
Yaowu Xuf883b422016-08-30 14:01:10 -070012396// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012397// rounding, this can be written as:
12398//
Yaowu Xuf883b422016-08-30 14:01:10 -070012399// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012400// Mh(x) * Mv(y) * P(x,y) +
12401// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012402// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012403//
12404// Where :
12405//
Yaowu Xuf883b422016-08-30 14:01:10 -070012406// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12407// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012408//
12409// This function computes 'wsrc' and 'mask' as:
12410//
12411// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012412// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012413// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012414// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012415//
12416// mask(x, y) = Mh(x) * Mv(y)
12417//
12418// These can then be used to efficiently approximate the error for any
12419// predictor P in the context of the provided neighbouring predictors by
12420// computing:
12421//
12422// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012423// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012424//
Yaowu Xuf883b422016-08-30 14:01:10 -070012425static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012426 const MACROBLOCKD *xd, int mi_row,
12427 int mi_col, const uint8_t *above,
12428 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012429 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012430 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12431 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012432 const int bw = xd->n8_w << MI_SIZE_LOG2;
12433 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012434 int32_t *mask_buf = x->mask_buf;
12435 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012436 const int wsrc_stride = bw;
12437 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012438 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
12439#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012440 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12441#else
12442 const int is_hbd = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070012443#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012444
12445 // plane 0 should not be subsampled
12446 assert(xd->plane[0].subsampling_x == 0);
12447 assert(xd->plane[0].subsampling_y == 0);
12448
Yaowu Xuf883b422016-08-30 14:01:10 -070012449 av1_zero_array(wsrc_buf, bw * bh);
12450 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012451
12452 // handle above row
12453 if (xd->up_available) {
12454 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012455 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012456 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012457 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012458
12459 assert(miw > 0);
12460
12461 i = 0;
12462 do { // for each mi in the above row
12463 const int mi_col_offset = i;
12464 const MB_MODE_INFO *const above_mbmi =
12465 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12466 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012467 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012468 const int neighbor_bw = mi_step * MI_SIZE;
12469
12470 if (is_neighbor_overlappable(above_mbmi)) {
12471 const int tmp_stride = above_stride;
12472 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12473 int32_t *mask = mask_buf + (i * MI_SIZE);
12474
12475 if (!is_hbd) {
12476 const uint8_t *tmp = above;
12477
12478 for (row = 0; row < overlap; ++row) {
12479 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012480 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012481 for (col = 0; col < neighbor_bw; ++col) {
12482 wsrc[col] = m1 * tmp[col];
12483 mask[col] = m0;
12484 }
12485 wsrc += wsrc_stride;
12486 mask += mask_stride;
12487 tmp += tmp_stride;
12488 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012489#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012490 } else {
12491 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12492
12493 for (row = 0; row < overlap; ++row) {
12494 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012495 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012496 for (col = 0; col < neighbor_bw; ++col) {
12497 wsrc[col] = m1 * tmp[col];
12498 mask[col] = m0;
12499 }
12500 wsrc += wsrc_stride;
12501 mask += mask_stride;
12502 tmp += tmp_stride;
12503 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012504#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012505 }
12506 }
12507
12508 above += neighbor_bw;
12509 i += mi_step;
12510 } while (i < miw);
12511 }
12512
12513 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012514 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12515 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012516 }
12517
12518 // handle left column
12519 if (xd->left_available) {
12520 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012521 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012522 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012523 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012524
12525 assert(mih > 0);
12526
12527 i = 0;
12528 do { // for each mi in the left column
12529 const int mi_row_offset = i;
12530 const MB_MODE_INFO *const left_mbmi =
12531 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
12532 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -070012533 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012534 const int neighbor_bh = mi_step * MI_SIZE;
12535
12536 if (is_neighbor_overlappable(left_mbmi)) {
12537 const int tmp_stride = left_stride;
12538 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12539 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12540
12541 if (!is_hbd) {
12542 const uint8_t *tmp = left;
12543
12544 for (row = 0; row < neighbor_bh; ++row) {
12545 for (col = 0; col < overlap; ++col) {
12546 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012547 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12548 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12549 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12550 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012551 }
12552 wsrc += wsrc_stride;
12553 mask += mask_stride;
12554 tmp += tmp_stride;
12555 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012556#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012557 } else {
12558 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
12559
12560 for (row = 0; row < neighbor_bh; ++row) {
12561 for (col = 0; col < overlap; ++col) {
12562 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012563 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12564 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12565 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12566 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012567 }
12568 wsrc += wsrc_stride;
12569 mask += mask_stride;
12570 tmp += tmp_stride;
12571 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012572#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012573 }
12574 }
12575
12576 left += neighbor_bh * left_stride;
12577 i += mi_step;
12578 } while (i < mih);
12579 }
12580
12581 if (!is_hbd) {
12582 const uint8_t *src = x->plane[0].src.buf;
12583
12584 for (row = 0; row < bh; ++row) {
12585 for (col = 0; col < bw; ++col) {
12586 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12587 }
12588 wsrc_buf += wsrc_stride;
12589 src += x->plane[0].src.stride;
12590 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012591#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012592 } else {
12593 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12594
12595 for (row = 0; row < bh; ++row) {
12596 for (col = 0; col < bw; ++col) {
12597 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12598 }
12599 wsrc_buf += wsrc_stride;
12600 src += x->plane[0].src.stride;
12601 }
Yaowu Xuf883b422016-08-30 14:01:10 -070012602#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012603 }
12604}
Yue Chenf27b1602017-01-13 11:11:43 -080012605
12606#if CONFIG_NCOBMC
12607void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12608 int mi_row, int mi_col) {
12609 const AV1_COMMON *const cm = &cpi->common;
12610 MACROBLOCKD *const xd = &x->e_mbd;
12611 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12612 MB_MODE_INFO backup_mbmi;
12613 BLOCK_SIZE bsize = mbmi->sb_type;
12614 int ref, skip_blk, backup_skip = x->skip;
12615 int64_t rd_causal;
12616 RD_STATS rd_stats_y, rd_stats_uv;
12617 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12618 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12619
12620 // Recompute the best causal predictor and rd
12621 mbmi->motion_mode = SIMPLE_TRANSLATION;
12622 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12623 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12624 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12625 assert(cfg != NULL);
12626 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12627 &xd->block_refs[ref]->sf);
12628 }
12629 av1_setup_dst_planes(x->e_mbd.plane, get_frame_new_buffer(&cpi->common),
12630 mi_row, mi_col);
12631
12632 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
12633
12634 av1_subtract_plane(x, bsize, 0);
12635 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12636 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12637 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12638 if (rd_stats_y.skip && rd_stats_uv.skip) {
12639 rd_stats_y.rate = rate_skip1;
12640 rd_stats_uv.rate = 0;
12641 rd_stats_y.dist = rd_stats_y.sse;
12642 rd_stats_uv.dist = rd_stats_uv.sse;
12643 skip_blk = 0;
12644 } else if (RDCOST(x->rdmult, x->rddiv,
12645 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12646 (rd_stats_y.dist + rd_stats_uv.dist)) >
12647 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12648 (rd_stats_y.sse + rd_stats_uv.sse))) {
12649 rd_stats_y.rate = rate_skip1;
12650 rd_stats_uv.rate = 0;
12651 rd_stats_y.dist = rd_stats_y.sse;
12652 rd_stats_uv.dist = rd_stats_uv.sse;
12653 skip_blk = 1;
12654 } else {
12655 rd_stats_y.rate += rate_skip0;
12656 skip_blk = 0;
12657 }
12658 backup_skip = skip_blk;
12659 backup_mbmi = *mbmi;
12660 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12661 (rd_stats_y.dist + rd_stats_uv.dist));
12662 rd_causal += RDCOST(x->rdmult, x->rddiv,
12663 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12664
12665 // Check non-causal mode
12666 mbmi->motion_mode = OBMC_CAUSAL;
Sarah Parker19234cc2017-03-10 16:43:25 -080012667 assert_motion_mode_valid(OBMC_CAUSAL,
12668#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
12669 0, cm->global_motion,
12670#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
12671 mi);
Yue Chenf27b1602017-01-13 11:11:43 -080012672 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12673
12674 av1_subtract_plane(x, bsize, 0);
12675 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12676 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12677 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12678 if (rd_stats_y.skip && rd_stats_uv.skip) {
12679 rd_stats_y.rate = rate_skip1;
12680 rd_stats_uv.rate = 0;
12681 rd_stats_y.dist = rd_stats_y.sse;
12682 rd_stats_uv.dist = rd_stats_uv.sse;
12683 skip_blk = 0;
12684 } else if (RDCOST(x->rdmult, x->rddiv,
12685 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12686 (rd_stats_y.dist + rd_stats_uv.dist)) >
12687 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12688 (rd_stats_y.sse + rd_stats_uv.sse))) {
12689 rd_stats_y.rate = rate_skip1;
12690 rd_stats_uv.rate = 0;
12691 rd_stats_y.dist = rd_stats_y.sse;
12692 rd_stats_uv.dist = rd_stats_uv.sse;
12693 skip_blk = 1;
12694 } else {
12695 rd_stats_y.rate += rate_skip0;
12696 skip_blk = 0;
12697 }
12698
12699 if (rd_causal >
12700 RDCOST(x->rdmult, x->rddiv,
12701 rd_stats_y.rate + rd_stats_uv.rate +
12702 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12703 (rd_stats_y.dist + rd_stats_uv.dist))) {
12704 x->skip = skip_blk;
12705 } else {
12706 *mbmi = backup_mbmi;
12707 x->skip = backup_skip;
12708 }
12709}
Fergus Simpson4063a682017-02-28 16:52:22 -080012710#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070012711#endif // CONFIG_MOTION_VAR