blob: 63e594ad36df1d4a61ba7e9eb079957fb5ea186c [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"
Angie Chiang47e4b362017-03-24 11:25:10 -070036#if CONFIG_LV_MAP
37#include "av1/common/txb_common.h"
38#endif
Yue Chen69f18e12016-09-08 14:48:15 -070039#if CONFIG_WARPED_MOTION
40#include "av1/common/warped_motion.h"
41#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070042
Jingning Han1aab8182016-06-03 11:09:06 -070043#include "av1/encoder/aq_variance.h"
Tom Finegan17ce8b12017-02-08 12:46:31 -080044#include "av1/encoder/av1_quantize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070045#include "av1/encoder/cost.h"
46#include "av1/encoder/encodemb.h"
47#include "av1/encoder/encodemv.h"
48#include "av1/encoder/encoder.h"
Angie Chiang47e4b362017-03-24 11:25:10 -070049#if CONFIG_LV_MAP
50#include "av1/encoder/encodetxb.h"
51#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070052#include "av1/encoder/hybrid_fwd_txfm.h"
53#include "av1/encoder/mcomp.h"
Urvang Joshib100db72016-10-12 16:28:56 -070054#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070055#include "av1/encoder/palette.h"
Urvang Joshib100db72016-10-12 16:28:56 -070056#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070057#include "av1/encoder/ratectrl.h"
58#include "av1/encoder/rd.h"
59#include "av1/encoder/rdopt.h"
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070060#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070061#if CONFIG_PVQ
62#include "av1/encoder/pvq_encoder.h"
Fergus Simpson4063a682017-02-28 16:52:22 -080063#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -080064#if CONFIG_PVQ || CONFIG_DAALA_DIST
65#include "av1/common/pvq.h"
Fergus Simpson4063a682017-02-28 16:52:22 -080066#endif // CONFIG_PVQ || CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -070067#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080068#define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS)
Angie Chiang5678ad92016-11-21 09:38:40 -080069static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
Angie Chiangd91ab372016-11-21 18:16:49 -080070 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 0 }, { 1, 1 },
71 { 1, 2 }, { 1, 3 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
72 { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070073};
Angie Chiang5678ad92016-11-21 09:38:40 -080074#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070075
76#if CONFIG_EXT_REFS
77
78#define LAST_FRAME_MODE_MASK \
79 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
80 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
81#define LAST2_FRAME_MODE_MASK \
82 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
83 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
84#define LAST3_FRAME_MODE_MASK \
85 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
86 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
87#define GOLDEN_FRAME_MODE_MASK \
88 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
89 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
90#define BWDREF_FRAME_MODE_MASK \
91 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
92 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
93#define ALTREF_FRAME_MODE_MASK \
94 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
95 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
96
97#else
98
99#define LAST_FRAME_MODE_MASK \
100 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
101#define GOLDEN_FRAME_MODE_MASK \
102 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
103#define ALTREF_FRAME_MODE_MASK \
104 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
105
106#endif // CONFIG_EXT_REFS
107
108#if CONFIG_EXT_REFS
109#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
110#else
111#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
112#endif // CONFIG_EXT_REFS
113
114#define MIN_EARLY_TERM_INDEX 3
115#define NEW_MV_DISCOUNT_FACTOR 8
116
117#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700118#define ANGLE_SKIP_THRESH 10
119#define FILTER_FAST_SEARCH 1
120#endif // CONFIG_EXT_INTRA
121
122const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
123 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
124
125typedef struct {
126 PREDICTION_MODE mode;
127 MV_REFERENCE_FRAME ref_frame[2];
128} MODE_DEFINITION;
129
130typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
131
132struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700133 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700134 MACROBLOCK *x;
135 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
136 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800137 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138 int64_t this_rd;
139 int64_t best_rd;
140 int exit_early;
141 int use_fast_coef_costing;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700142};
143
144#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700145static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500146 { NEARESTMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500148 { NEARESTMV, { LAST2_FRAME, NONE_FRAME } },
149 { NEARESTMV, { LAST3_FRAME, NONE_FRAME } },
150 { NEARESTMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700151#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500152 { NEARESTMV, { ALTREF_FRAME, NONE_FRAME } },
153 { NEARESTMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154
Emil Keyder01770b32017-01-20 18:03:11 -0500155 { DC_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156
Emil Keyder01770b32017-01-20 18:03:11 -0500157 { NEWMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700158#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500159 { NEWMV, { LAST2_FRAME, NONE_FRAME } },
160 { NEWMV, { LAST3_FRAME, NONE_FRAME } },
161 { NEWMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700162#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500163 { NEWMV, { ALTREF_FRAME, NONE_FRAME } },
164 { NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165
Emil Keyder01770b32017-01-20 18:03:11 -0500166 { NEARMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700167#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500168 { NEARMV, { LAST2_FRAME, NONE_FRAME } },
169 { NEARMV, { LAST3_FRAME, NONE_FRAME } },
170 { NEARMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700171#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500172 { NEARMV, { ALTREF_FRAME, NONE_FRAME } },
173 { NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700174
Emil Keyder01770b32017-01-20 18:03:11 -0500175 { ZEROMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500177 { ZEROMV, { LAST2_FRAME, NONE_FRAME } },
178 { ZEROMV, { LAST3_FRAME, NONE_FRAME } },
179 { ZEROMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700180#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500181 { ZEROMV, { GOLDEN_FRAME, NONE_FRAME } },
182 { ZEROMV, { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183
184// TODO(zoeliu): May need to reconsider the order on the modes to check
185
186#if CONFIG_EXT_INTER
187 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
188#if CONFIG_EXT_REFS
189 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
190 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
191#endif // CONFIG_EXT_REFS
192 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
193#if CONFIG_EXT_REFS
194 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
195 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
196 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
197 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
198#endif // CONFIG_EXT_REFS
199
200#else // CONFIG_EXT_INTER
201
202 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
203#if CONFIG_EXT_REFS
204 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
205 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
206#endif // CONFIG_EXT_REFS
207 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
208#if CONFIG_EXT_REFS
209 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
210 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
211 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
212 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
213#endif // CONFIG_EXT_REFS
214#endif // CONFIG_EXT_INTER
215
Emil Keyder01770b32017-01-20 18:03:11 -0500216 { TM_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700217
Urvang Joshi6be4a542016-11-03 15:24:05 -0700218#if CONFIG_ALT_INTRA
Emil Keyder01770b32017-01-20 18:03:11 -0500219 { SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
Urvang Joshie6ca8e82017-03-15 14:57:41 -0700220#if CONFIG_SMOOTH_HV
221 { SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
222 { SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
223#endif // CONFIG_SMOOTH_HV
Urvang Joshi6be4a542016-11-03 15:24:05 -0700224#endif // CONFIG_ALT_INTRA
225
Yaowu Xuc27fc142016-08-22 16:08:15 -0700226#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700227 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
228 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
229 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
230 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
231 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
232 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
233 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
234
235#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700236 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
237 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
238 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
239 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
240 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
241 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
242 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
243
Yaowu Xuc27fc142016-08-22 16:08:15 -0700244 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
245 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
246 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
247 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
248 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
249 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
250 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
251#endif // CONFIG_EXT_REFS
252
Yaowu Xuc27fc142016-08-22 16:08:15 -0700253 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
254 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
255 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
256 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
257 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
258 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
259 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
260
261#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
263 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
264 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
265 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
266 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
267 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
268 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
269
Yaowu Xuc27fc142016-08-22 16:08:15 -0700270 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
271 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
272 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
273 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
274 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
275 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
276 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
277
Yaowu Xuc27fc142016-08-22 16:08:15 -0700278 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
279 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
280 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
281 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
282 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
283 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
284 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
285
Yaowu Xuc27fc142016-08-22 16:08:15 -0700286 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
287 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
288 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
289 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
290 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
291 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
292 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
293#endif // CONFIG_EXT_REFS
294
295#else // CONFIG_EXT_INTER
296
297 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
298 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
299#if CONFIG_EXT_REFS
300 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
301 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
302 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
303 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
304#endif // CONFIG_EXT_REFS
305 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
306 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
307
308#if CONFIG_EXT_REFS
309 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
310 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
311 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
312 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
313 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
314 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
315 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
316 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
317#endif // CONFIG_EXT_REFS
318
319 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
320#if CONFIG_EXT_REFS
321 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
322 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
323#endif // CONFIG_EXT_REFS
324 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
325
326#if CONFIG_EXT_REFS
327 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
328 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
329 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
330 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
331#endif // CONFIG_EXT_REFS
332
333#endif // CONFIG_EXT_INTER
334
Emil Keyder01770b32017-01-20 18:03:11 -0500335 { H_PRED, { INTRA_FRAME, NONE_FRAME } },
336 { V_PRED, { INTRA_FRAME, NONE_FRAME } },
337 { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
338 { D207_PRED, { INTRA_FRAME, NONE_FRAME } },
339 { D153_PRED, { INTRA_FRAME, NONE_FRAME } },
340 { D63_PRED, { INTRA_FRAME, NONE_FRAME } },
341 { D117_PRED, { INTRA_FRAME, NONE_FRAME } },
342 { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700343
344#if CONFIG_EXT_INTER
345 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
346 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
347 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
348 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
349
350#if CONFIG_EXT_REFS
351 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
352 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
353 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
354 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
355
356 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
357 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
358 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
359 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
360#endif // CONFIG_EXT_REFS
361
362 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
363 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
364 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
365 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
366
367#if CONFIG_EXT_REFS
368 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
369 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
370 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
371 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
372#endif // CONFIG_EXT_REFS
373
374 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
375 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
376 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
377 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
378#endif // CONFIG_EXT_INTER
379};
380
Yaowu Xuf883b422016-08-30 14:01:10 -0700381static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500382 { { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700383#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500384 { { LAST2_FRAME, NONE_FRAME } }, { { LAST3_FRAME, NONE_FRAME } },
385 { { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700386#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500387 { { GOLDEN_FRAME, NONE_FRAME } }, { { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700388
389 { { LAST_FRAME, ALTREF_FRAME } },
390#if CONFIG_EXT_REFS
391 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
392#endif // CONFIG_EXT_REFS
393 { { GOLDEN_FRAME, ALTREF_FRAME } },
394
395#if CONFIG_EXT_REFS
396 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
397 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
398#endif // CONFIG_EXT_REFS
399
Emil Keyder01770b32017-01-20 18:03:11 -0500400 { { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700401};
402
hui su5db97432016-10-14 16:10:14 -0700403#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404static INLINE int write_uniform_cost(int n, int v) {
hui su37499292017-04-26 09:49:53 -0700405 const int l = get_unsigned_bits(n);
406 const int m = (1 << l) - n;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700407 if (l == 0) return 0;
408 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700409 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700410 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700411 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700412}
hui su5db97432016-10-14 16:10:14 -0700413#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414
415// constants for prune 1 and prune 2 decision boundaries
416#define FAST_EXT_TX_CORR_MID 0.0
417#define FAST_EXT_TX_EDST_MID 0.1
418#define FAST_EXT_TX_CORR_MARGIN 0.5
419#define FAST_EXT_TX_EDST_MARGIN 0.3
420
Yushin Cho7a428ba2017-01-12 16:28:49 -0800421#if CONFIG_DAALA_DIST
422static int od_compute_var_4x4(od_coeff *x, int stride) {
423 int sum;
424 int s2;
425 int i;
426 sum = 0;
427 s2 = 0;
428 for (i = 0; i < 4; i++) {
429 int j;
430 for (j = 0; j < 4; j++) {
431 int t;
432
433 t = x[i * stride + j];
434 sum += t;
435 s2 += t * t;
436 }
437 }
438 // TODO(yushin) : Check wheter any changes are required for high bit depth.
439 return (s2 - (sum * sum >> 4)) >> 4;
440}
441
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500442/* OD_DIST_LP_MID controls the frequency weighting filter used for computing
443 the distortion. For a value X, the filter is [1 X 1]/(X + 2) and
444 is applied both horizontally and vertically. For X=5, the filter is
445 a good approximation for the OD_QM8_Q4_HVS quantization matrix. */
446#define OD_DIST_LP_MID (5)
447#define OD_DIST_LP_NORM (OD_DIST_LP_MID + 2)
448
Yushin Cho7a428ba2017-01-12 16:28:49 -0800449static double od_compute_dist_8x8(int qm, int use_activity_masking, od_coeff *x,
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500450 od_coeff *y, od_coeff *e_lp, int stride) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800451 double sum;
452 int min_var;
453 double mean_var;
454 double var_stat;
455 double activity;
456 double calibration;
457 int i;
458 int j;
459 double vardist;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800460
461 vardist = 0;
462 OD_ASSERT(qm != OD_FLAT_QM);
Alex Converse76b89632017-03-20 11:47:12 -0700463 (void)qm;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800464#if 1
465 min_var = INT_MAX;
466 mean_var = 0;
467 for (i = 0; i < 3; i++) {
468 for (j = 0; j < 3; j++) {
469 int varx;
470 int vary;
471 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
472 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
473 min_var = OD_MINI(min_var, varx);
474 mean_var += 1. / (1 + varx);
475 /* The cast to (double) is to avoid an overflow before the sqrt.*/
476 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
477 }
478 }
479 /* We use a different variance statistic depending on whether activity
480 masking is used, since the harmonic mean appeared slghtly worse with
481 masking off. The calibration constant just ensures that we preserve the
482 rate compared to activity=1. */
483 if (use_activity_masking) {
484 calibration = 1.95;
485 var_stat = 9. / mean_var;
486 } else {
487 calibration = 1.62;
488 var_stat = min_var;
489 }
490 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
491 activity masking constant. */
492 activity = calibration * pow(.25 + var_stat, -1. / 6);
493#else
494 activity = 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800495#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800496 sum = 0;
497 for (i = 0; i < 8; i++) {
498 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500499 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800500 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500501 /* Normalize the filter to unit DC response. */
502 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
503 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800504 return activity * activity * (sum + vardist);
505}
506
507// Note : Inputs x and y are in a pixel domain
508static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
509 od_coeff *y, int bsize_w, int bsize_h,
510 int qindex) {
511 int i;
512 double sum;
513 sum = 0;
514
Yushin Cho7a428ba2017-01-12 16:28:49 -0800515 assert(bsize_w >= 8 && bsize_h >= 8);
516
517 if (qm == OD_FLAT_QM) {
518 for (i = 0; i < bsize_w * bsize_h; i++) {
519 double tmp;
520 tmp = x[i] - y[i];
521 sum += tmp * tmp;
522 }
523 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500524 int j;
525 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
526 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
527 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
528 int mid = OD_DIST_LP_MID;
529 for (i = 0; i < bsize_h; i++) {
530 for (j = 0; j < bsize_w; j++) {
531 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
532 }
533 }
534 for (i = 0; i < bsize_h; i++) {
535 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
536 tmp[i * bsize_w + bsize_w - 1] =
537 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
538 for (j = 1; j < bsize_w - 1; j++) {
539 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
540 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
541 }
542 }
543 for (j = 0; j < bsize_w; j++) {
544 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
545 e_lp[(bsize_h - 1) * bsize_w + j] =
546 mid * tmp[(bsize_h - 1) * bsize_w + j] +
547 2 * tmp[(bsize_h - 2) * bsize_w + j];
548 }
549 for (i = 1; i < bsize_h - 1; i++) {
550 for (j = 0; j < bsize_w; j++) {
551 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
552 tmp[(i - 1) * bsize_w + j] +
553 tmp[(i + 1) * bsize_w + j];
554 }
555 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800556 for (i = 0; i < bsize_h; i += 8) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800557 for (j = 0; j < bsize_w; j += 8) {
558 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500559 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
560 bsize_w);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800561 }
562 }
David Michael Barrd091b802017-01-21 16:05:46 +0900563 /* Scale according to linear regression against SSE, for 8x8 blocks. */
564 if (activity_masking) {
565 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
566 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
567 } else {
568 sum *= qindex >= 128
569 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
570 : qindex <= 43
571 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
572 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
573 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800574 }
575 return sum;
576}
577
578static int64_t av1_daala_dist(const uint8_t *src, int src_stride,
Yushin Cho4483e3d2017-04-18 19:41:20 -0700579 const uint8_t *dst, int dst_stride, int bsw,
580 int bsh, int qm, int use_activity_masking,
581 int qindex) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800582 int i, j;
583 int64_t d;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800584 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
585 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
586
587 assert(qm == OD_HVS_QM);
588
589 for (j = 0; j < bsh; j++)
590 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
591
592 for (j = 0; j < bsh; j++)
593 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
594
595 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
596 qindex);
597 return d;
598}
Fergus Simpson4063a682017-02-28 16:52:22 -0800599#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800600
Yaowu Xuf883b422016-08-30 14:01:10 -0700601static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse9f217762017-04-20 15:34:54 -0700602 const uint8_t *src, int src_stride,
603 const uint8_t *dst, int dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700604 double *hordist, double *verdist) {
Alex Converse9f217762017-04-20 15:34:54 -0700605 const int bw = block_size_wide[bsize];
606 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700607 unsigned int esq[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608
609 const int f_index = bsize - BLOCK_16X16;
610 if (f_index < 0) {
Alex Converse9f217762017-04-20 15:34:54 -0700611 const int w_shift = bw == 8 ? 1 : 2;
612 const int h_shift = bh == 8 ? 1 : 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200613#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700614 if (cpi->common.use_highbitdepth) {
Alex Converse9f217762017-04-20 15:34:54 -0700615 const uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
616 const uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
617 for (int i = 0; i < bh; ++i)
618 for (int j = 0; j < bw; ++j) {
619 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700620 esq[index] +=
621 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
622 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
623 }
624 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200625#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626
Alex Converse9f217762017-04-20 15:34:54 -0700627 for (int i = 0; i < bh; ++i)
628 for (int j = 0; j < bw; ++j) {
629 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700630 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
631 (src[j + i * src_stride] - dst[j + i * dst_stride]);
632 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200633#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700634 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200635#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636 } else {
Alex Converse9f217762017-04-20 15:34:54 -0700637 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
638 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
639 &esq[1]);
640 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
641 &esq[2]);
642 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
643 dst_stride, &esq[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700644 src += bh / 4 * src_stride;
645 dst += bh / 4 * dst_stride;
646
Alex Converse9f217762017-04-20 15:34:54 -0700647 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
648 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
649 &esq[5]);
650 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
651 &esq[6]);
652 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
653 dst_stride, &esq[7]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700654 src += bh / 4 * src_stride;
655 dst += bh / 4 * dst_stride;
656
Alex Converse9f217762017-04-20 15:34:54 -0700657 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
658 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
659 &esq[9]);
660 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
661 &esq[10]);
662 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
663 dst_stride, &esq[11]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700664 src += bh / 4 * src_stride;
665 dst += bh / 4 * dst_stride;
666
Alex Converse9f217762017-04-20 15:34:54 -0700667 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
668 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
669 &esq[13]);
670 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
671 &esq[14]);
672 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
673 dst_stride, &esq[15]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 }
675
Alex Converse9f217762017-04-20 15:34:54 -0700676 double total = (double)esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] +
677 esq[6] + esq[7] + esq[8] + esq[9] + esq[10] + esq[11] +
678 esq[12] + esq[13] + esq[14] + esq[15];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700679 if (total > 0) {
680 const double e_recip = 1.0 / total;
Alex Converse9f217762017-04-20 15:34:54 -0700681 hordist[0] = ((double)esq[0] + esq[4] + esq[8] + esq[12]) * e_recip;
682 hordist[1] = ((double)esq[1] + esq[5] + esq[9] + esq[13]) * e_recip;
683 hordist[2] = ((double)esq[2] + esq[6] + esq[10] + esq[14]) * e_recip;
684 verdist[0] = ((double)esq[0] + esq[1] + esq[2] + esq[3]) * e_recip;
685 verdist[1] = ((double)esq[4] + esq[5] + esq[6] + esq[7]) * e_recip;
686 verdist[2] = ((double)esq[8] + esq[9] + esq[10] + esq[11]) * e_recip;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 } else {
688 hordist[0] = verdist[0] = 0.25;
689 hordist[1] = verdist[1] = 0.25;
690 hordist[2] = verdist[2] = 0.25;
691 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692}
693
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700694static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize,
695 const uint8_t *src, int src_stride,
696 const uint8_t *dst, int dst_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700697 int prune_bitmask = 0;
698 double svm_proj_h = 0, svm_proj_v = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700699 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
701 hdist, vdist);
702
703 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
704 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
705 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
706 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
707 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
708 prune_bitmask |= 1 << FLIPADST_1D;
709 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
710 prune_bitmask |= 1 << ADST_1D;
711
712 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
713 prune_bitmask |= 1 << (FLIPADST_1D + 8);
714 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
715 prune_bitmask |= 1 << (ADST_1D + 8);
716
717 return prune_bitmask;
718}
719
720#if CONFIG_EXT_TX
Alex Converse89912f92017-04-21 13:28:50 -0700721static void get_horver_correlation(const int16_t *diff, int stride, int w,
722 int h, double *hcorr, double *vcorr) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723 // Returns hor/ver correlation coefficient
724 const int num = (h - 1) * (w - 1);
725 double num_r;
726 int i, j;
727 int64_t xy_sum = 0, xz_sum = 0;
728 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
729 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
730 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
731 *hcorr = *vcorr = 1;
732
733 assert(num > 0);
734 num_r = 1.0 / num;
735 for (i = 1; i < h; ++i) {
736 for (j = 1; j < w; ++j) {
737 const int16_t x = diff[i * stride + j];
738 const int16_t y = diff[i * stride + j - 1];
739 const int16_t z = diff[(i - 1) * stride + j];
740 xy_sum += x * y;
741 xz_sum += x * z;
742 x_sum += x;
743 y_sum += y;
744 z_sum += z;
745 x2_sum += x * x;
746 y2_sum += y * y;
747 z2_sum += z * z;
748 }
749 }
750 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
751 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
752 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
753 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
754 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
755 if (x_var_n > 0 && y_var_n > 0) {
756 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
757 *hcorr = *hcorr < 0 ? 0 : *hcorr;
758 }
759 if (x_var_n > 0 && z_var_n > 0) {
760 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
761 *vcorr = *vcorr < 0 ? 0 : *vcorr;
762 }
763}
764
Alex Converse89912f92017-04-21 13:28:50 -0700765int dct_vs_idtx(const int16_t *diff, int stride, int w, int h) {
766 double hcorr, vcorr;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700767 int prune_bitmask = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700768 get_horver_correlation(diff, stride, w, h, &hcorr, &vcorr);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769
Alex Converse89912f92017-04-21 13:28:50 -0700770 if (vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700771 prune_bitmask |= 1 << IDTX_1D;
Alex Converse89912f92017-04-21 13:28:50 -0700772 else if (vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 prune_bitmask |= 1 << DCT_1D;
774
Alex Converse89912f92017-04-21 13:28:50 -0700775 if (hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 prune_bitmask |= 1 << (IDTX_1D + 8);
Alex Converse89912f92017-04-21 13:28:50 -0700777 else if (hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 prune_bitmask |= 1 << (DCT_1D + 8);
779 return prune_bitmask;
780}
781
782// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700783static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700784 MACROBLOCK *x, const MACROBLOCKD *xd,
785 int adst_flipadst, int dct_idtx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700786 int prune = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700787
Alex Converse89912f92017-04-21 13:28:50 -0700788 if (adst_flipadst) {
789 const struct macroblock_plane *const p = &x->plane[0];
790 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
Alex Converse89912f92017-04-21 13:28:50 -0700792 pd->dst.buf, pd->dst.stride);
793 }
794 if (dct_idtx) {
795 av1_subtract_plane(x, bsize, 0);
796 const struct macroblock_plane *const p = &x->plane[0];
797 const int bw = 4 << (b_width_log2_lookup[bsize]);
798 const int bh = 4 << (b_height_log2_lookup[bsize]);
799 prune |= dct_vs_idtx(p->src_diff, bw, bw, bh);
800 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700801
802 return prune;
803}
804#endif // CONFIG_EXT_TX
805
806// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700807static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700808 const MACROBLOCK *x, const MACROBLOCKD *xd) {
809 const struct macroblock_plane *const p = &x->plane[0];
810 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
Alex Converse89912f92017-04-21 13:28:50 -0700812 pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813}
814
Yaowu Xuf883b422016-08-30 14:01:10 -0700815static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700816 const MACROBLOCKD *const xd, int tx_set) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700817#if CONFIG_EXT_TX
Yaowu Xu37fe5fb2017-05-09 11:43:45 -0700818 const int *tx_set_1D = tx_set >= 0 ? ext_tx_used_inter_1D[tx_set] : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700819#else
820 const int tx_set_1D[TX_TYPES_1D] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -0800821#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822
823 switch (cpi->sf.tx_type_search.prune_mode) {
824 case NO_PRUNE: return 0; break;
825 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700826 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700827 return 0;
828 return prune_one_for_sby(cpi, bsize, x, xd);
829 break;
830#if CONFIG_EXT_TX
831 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700832 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
834 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
835 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700836 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700837 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
838 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
839 break;
Fergus Simpson4063a682017-02-28 16:52:22 -0800840#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841 }
842 assert(0);
843 return 0;
844}
845
846static int do_tx_type_search(TX_TYPE tx_type, int prune) {
847// TODO(sarahparker) implement for non ext tx
848#if CONFIG_EXT_TX
849 return !(((prune >> vtx_tab[tx_type]) & 1) |
850 ((prune >> (htx_tab[tx_type] + 8)) & 1));
851#else
852 // temporary to avoid compiler warnings
853 (void)vtx_tab;
854 (void)htx_tab;
855 (void)tx_type;
856 (void)prune;
857 return 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800858#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700859}
860
Yaowu Xuf883b422016-08-30 14:01:10 -0700861static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
863 int plane, int64_t sse, int *rate,
864 int64_t *dist) {
865 const struct macroblockd_plane *const pd = &xd->plane[plane];
866 const int dequant_shift =
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200867#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200869#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700870 3;
871
872 // Fast approximate the modelling function.
873 if (cpi->sf.simple_model_rd_from_var) {
874 const int64_t square_error = sse;
875 int quantizer = (pd->dequant[1] >> dequant_shift);
876
877 if (quantizer < 120)
878 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700879 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700880 else
881 *rate = 0;
882 *dist = (square_error * quantizer) >> 8;
883 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700884 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
885 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 }
887
888 *dist <<= 4;
889}
890
Yaowu Xuf883b422016-08-30 14:01:10 -0700891static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700892 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
893 int plane_to, int *out_rate_sum,
894 int64_t *out_dist_sum, int *skip_txfm_sb,
895 int64_t *skip_sse_sb) {
896 // Note our transform coeffs are 8 times an orthogonal transform.
897 // Hence quantizer step is also 8 times. To get effective quantizer
898 // we need to divide by 8 before sending to modeling function.
899 int plane;
900 const int ref = xd->mi[0]->mbmi.ref_frame[0];
901
902 int64_t rate_sum = 0;
903 int64_t dist_sum = 0;
904 int64_t total_sse = 0;
905
906 x->pred_sse[ref] = 0;
907
908 for (plane = plane_from; plane <= plane_to; ++plane) {
909 struct macroblock_plane *const p = &x->plane[plane];
910 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han31b6a4f2017-02-23 11:05:53 -0800911#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -0800912 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
913#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700914 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Fergus Simpson4063a682017-02-28 16:52:22 -0800915#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916
917 unsigned int sse;
918 int rate;
919 int64_t dist;
920
Jingning Han9ce464c2017-02-20 15:36:30 -0800921#if CONFIG_CB4X4
922 if (x->skip_chroma_rd && plane) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -0800923#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -0800924
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925 // TODO(geza): Write direct sse functions that do not compute
926 // variance as well.
927 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
928 &sse);
929
930 if (plane == 0) x->pred_sse[ref] = sse;
931
932 total_sse += sse;
933
934 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
935
936 rate_sum += rate;
937 dist_sum += dist;
938 }
939
940 *skip_txfm_sb = total_sse == 0;
941 *skip_sse_sb = total_sse << 4;
942 *out_rate_sum = (int)rate_sum;
943 *out_dist_sum = dist_sum;
944}
945
Yaowu Xuf883b422016-08-30 14:01:10 -0700946int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
947 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 int i;
949 int64_t error = 0, sqcoeff = 0;
950
951 for (i = 0; i < block_size; i++) {
952 const int diff = coeff[i] - dqcoeff[i];
953 error += diff * diff;
954 sqcoeff += coeff[i] * coeff[i];
955 }
956
957 *ssz = sqcoeff;
958 return error;
959}
960
Yaowu Xuf883b422016-08-30 14:01:10 -0700961int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
962 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700963 int i;
964 int64_t error = 0;
965
966 for (i = 0; i < block_size; i++) {
967 const int diff = coeff[i] - dqcoeff[i];
968 error += diff * diff;
969 }
970
971 return error;
972}
973
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200974#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -0700975int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
976 const tran_low_t *dqcoeff, intptr_t block_size,
977 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700978 int i;
979 int64_t error = 0, sqcoeff = 0;
980 int shift = 2 * (bd - 8);
981 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
982
983 for (i = 0; i < block_size; i++) {
984 const int64_t diff = coeff[i] - dqcoeff[i];
985 error += diff * diff;
986 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
987 }
988 assert(error >= 0 && sqcoeff >= 0);
989 error = (error + rounding) >> shift;
990 sqcoeff = (sqcoeff + rounding) >> shift;
991
992 *ssz = sqcoeff;
993 return error;
994}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200995#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700996
Thomas Daede6ff6af62017-02-03 16:29:24 -0800997#if CONFIG_PVQ
998// Without PVQ, av1_block_error_c() return two kind of errors,
999// 1) reconstruction (i.e. decoded) error and
1000// 2) Squared sum of transformed residue (i.e. 'coeff')
1001// However, if PVQ is enabled, coeff does not keep the transformed residue
1002// but instead a transformed original is kept.
1003// Hence, new parameter ref vector (i.e. transformed predicted signal)
1004// is required to derive the residue signal,
1005// i.e. coeff - ref = residue (all transformed).
1006
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001007#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001008static int64_t av1_highbd_block_error2_c(const tran_low_t *coeff,
1009 const tran_low_t *dqcoeff,
1010 const tran_low_t *ref,
1011 intptr_t block_size, int64_t *ssz,
1012 int bd) {
1013 int64_t error;
1014 int64_t sqcoeff;
1015 int shift = 2 * (bd - 8);
1016 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1017 // Use the existing sse codes for calculating distortion of decoded signal:
1018 // i.e. (orig - decoded)^2
1019 // For high bit depth, throw away ssz until a 32-bit version of
1020 // av1_block_error_fp is written.
1021 int64_t ssz_trash;
1022 error = av1_block_error(coeff, dqcoeff, block_size, &ssz_trash);
1023 // prediction residue^2 = (orig - ref)^2
1024 sqcoeff = av1_block_error(coeff, ref, block_size, &ssz_trash);
1025 error = (error + rounding) >> shift;
1026 sqcoeff = (sqcoeff + rounding) >> shift;
1027 *ssz = sqcoeff;
1028 return error;
1029}
1030#else
1031// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1032// a separate function that does not do the extra computations for ssz.
1033static int64_t av1_block_error2_c(const tran_low_t *coeff,
1034 const tran_low_t *dqcoeff,
1035 const tran_low_t *ref, intptr_t block_size,
1036 int64_t *ssz) {
1037 int64_t error;
1038 // Use the existing sse codes for calculating distortion of decoded signal:
1039 // i.e. (orig - decoded)^2
1040 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1041 // prediction residue^2 = (orig - ref)^2
1042 *ssz = av1_block_error_fp(coeff, ref, block_size);
1043 return error;
1044}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001045#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001046#endif // CONFIG_PVQ
1047
Jingning Hanab77e732017-02-28 15:20:59 -08001048#if !CONFIG_PVQ || CONFIG_VAR_TX
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001049/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001050 * decide whether to include cost of a trailing EOB node or not (i.e. we
1051 * can skip this if the last coefficient in this transform block, e.g. the
1052 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1053 * were non-zero). */
Angie Chiang47e4b362017-03-24 11:25:10 -07001054#if !CONFIG_LV_MAP
1055static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1056 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1057 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1058 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 MACROBLOCKD *const xd = &x->e_mbd;
1060 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1061 const struct macroblock_plane *p = &x->plane[plane];
1062 const struct macroblockd_plane *pd = &xd->plane[plane];
1063 const PLANE_TYPE type = pd->plane_type;
1064 const uint16_t *band_count = &band_count_table[tx_size][1];
1065 const int eob = p->eobs[block];
1066 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1067 const int tx_size_ctx = txsize_sqr_map[tx_size];
1068 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1069 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1070 uint8_t token_cache[MAX_TX_SQUARE];
Angie Chiang77368af2017-03-23 16:22:07 -07001071 int pt = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072 int c, cost;
Angie Chiang77368af2017-03-23 16:22:07 -07001073 const int16_t *scan = scan_order->scan;
1074 const int16_t *nb = scan_order->neighbors;
Nathan E. Eggead66b812017-05-09 11:57:31 -04001075#if CONFIG_EC_MULTISYMBOL
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001076 const int ref = is_inter_block(mbmi);
1077 aom_prob *blockz_probs =
1078 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
Thomas Davies10525752017-03-06 12:10:46 +00001079
Nathan E. Eggead66b812017-05-09 11:57:31 -04001080#endif // CONFIG_EC_MULTISYMBOL
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001081
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001082#if CONFIG_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001083 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001084#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001085 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001086#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087
1088#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1089 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001090 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001091#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001092 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093
1094 if (eob == 0) {
Nathan E. Eggead66b812017-05-09 11:57:31 -04001095#if CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001097 cost = av1_cost_bit(blockz_probs[pt], 0);
1098#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001099 cost = token_costs[0][0][pt][EOB_TOKEN];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001100#endif // CONFIG_EC_MULTISYBMOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001101 } else {
1102 if (use_fast_coef_costing) {
1103 int band_left = *band_count++;
1104
1105 // dc token
1106 int v = qcoeff[0];
1107 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001108 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001109#if CONFIG_EC_MULTISYMBOL
Thomas Davies10525752017-03-06 12:10:46 +00001110 cost += (*token_costs)[!prev_t][pt][prev_t];
1111#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001112 cost += (*token_costs)[0][pt][prev_t];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001113#endif // CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001114
Yaowu Xuf883b422016-08-30 14:01:10 -07001115 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116 ++token_costs;
1117
1118 // ac tokens
1119 for (c = 1; c < eob; c++) {
1120 const int rc = scan[c];
1121 int16_t t;
1122
1123 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001124 cost += av1_get_token_cost(v, &t, cat6_bits);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001125#if CONFIG_EC_MULTISYMBOL
Thomas Davies10525752017-03-06 12:10:46 +00001126 cost += (*token_costs)[!t][!prev_t][t];
1127#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128 cost += (*token_costs)[!prev_t][!prev_t][t];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001129#endif // CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130 prev_t = t;
1131 if (!--band_left) {
1132 band_left = *band_count++;
1133 ++token_costs;
1134 }
1135 }
1136
1137 // eob token
Nathan E. Eggead66b812017-05-09 11:57:31 -04001138 if (band_left || CONFIG_EC_MULTISYMBOL)
Thomas Davies10525752017-03-06 12:10:46 +00001139 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140
1141 } else { // !use_fast_coef_costing
1142 int band_left = *band_count++;
1143
1144 // dc token
1145 int v = qcoeff[0];
1146 int16_t tok;
Nathan E. Eggead66b812017-05-09 11:57:31 -04001147#if !CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001149#endif // !CONFIG_EC_MULTISYMBOL
Alex Converseda3d94f2017-03-15 14:54:29 -07001150 cost = av1_get_token_cost(v, &tok, cat6_bits);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001151#if CONFIG_EC_MULTISYMBOL
Thomas Davies10525752017-03-06 12:10:46 +00001152 cost += (*token_costs)[!tok][pt][tok];
1153#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 cost += (*token_costs)[0][pt][tok];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001155#endif // CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001156
Yaowu Xuf883b422016-08-30 14:01:10 -07001157 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001158 ++token_costs;
1159
Nathan E. Eggead66b812017-05-09 11:57:31 -04001160#if !CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001161 tok_cost_ptr = &((*token_costs)[!tok]);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001162#endif // !CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001163
1164 // ac tokens
1165 for (c = 1; c < eob; c++) {
1166 const int rc = scan[c];
1167
1168 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001169 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 pt = get_coef_context(nb, token_cache, c);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001171#if CONFIG_EC_MULTISYMBOL
Thomas Davies10525752017-03-06 12:10:46 +00001172 cost += (*token_costs)[!tok][pt][tok];
1173#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001174 cost += (*tok_cost_ptr)[pt][tok];
Nathan E. Eggead66b812017-05-09 11:57:31 -04001175#endif // CONFIG_EC_MULTISYMBOL
Yaowu Xuf883b422016-08-30 14:01:10 -07001176 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001177 if (!--band_left) {
1178 band_left = *band_count++;
1179 ++token_costs;
1180 }
Nathan E. Eggead66b812017-05-09 11:57:31 -04001181#if !CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182 tok_cost_ptr = &((*token_costs)[!tok]);
Nathan E. Eggead66b812017-05-09 11:57:31 -04001183#endif // !CONFIG_EC_MULTISYMBOL
Yaowu Xuc27fc142016-08-22 16:08:15 -07001184 }
1185
1186 // eob token
Nathan E. Eggead66b812017-05-09 11:57:31 -04001187 if (band_left || CONFIG_EC_MULTISYMBOL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188 pt = get_coef_context(nb, token_cache, c);
1189 cost += (*token_costs)[0][pt][EOB_TOKEN];
1190 }
1191 }
1192 }
1193
Yaowu Xuc27fc142016-08-22 16:08:15 -07001194 return cost;
1195}
Angie Chiang47e4b362017-03-24 11:25:10 -07001196#endif // !CONFIG_LV_MAP
1197
Angie Chiang05917872017-04-15 12:28:56 -07001198int av1_cost_coeffs(const AV1_COMP *const cpi, MACROBLOCK *x, int plane,
Angie Chiang47e4b362017-03-24 11:25:10 -07001199 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1200 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1201 int use_fast_coef_costing) {
1202#if !CONFIG_LV_MAP
Angie Chiang05917872017-04-15 12:28:56 -07001203 const AV1_COMMON *const cm = &cpi->common;
Angie Chiang47e4b362017-03-24 11:25:10 -07001204 return cost_coeffs(cm, x, plane, block, tx_size, scan_order, a, l,
1205 use_fast_coef_costing);
1206#else // !CONFIG_LV_MAP
1207 (void)scan_order;
1208 (void)use_fast_coef_costing;
1209 const MACROBLOCKD *xd = &x->e_mbd;
1210 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1211 const struct macroblockd_plane *pd = &xd->plane[plane];
1212 const BLOCK_SIZE bsize = mbmi->sb_type;
1213#if CONFIG_CB4X4
1214#if CONFIG_CHROMA_2X2
1215 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
1216#else
1217 const BLOCK_SIZE plane_bsize =
1218 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
1219#endif // CONFIG_CHROMA_2X2
1220#else // CONFIG_CB4X4
1221 const BLOCK_SIZE plane_bsize =
1222 get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
1223#endif // CONFIG_CB4X4
1224
1225 TXB_CTX txb_ctx;
1226 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07001227 return av1_cost_coeffs_txb(cpi, x, plane, block, &txb_ctx);
Angie Chiang47e4b362017-03-24 11:25:10 -07001228#endif // !CONFIG_LV_MAP
1229}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001230#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231
Alex Converse61f37b82017-03-29 15:26:03 -07001232// Get transform block visible dimensions cropped to the MI units.
1233static void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
1234 BLOCK_SIZE plane_bsize, int blk_row, int blk_col,
1235 BLOCK_SIZE tx_bsize, int *width, int *height,
1236 int *visible_width, int *visible_height) {
1237 assert(tx_bsize <= plane_bsize);
1238 int txb_height = block_size_high[tx_bsize];
1239 int txb_width = block_size_wide[tx_bsize];
1240 const int block_height = block_size_high[plane_bsize];
1241 const int block_width = block_size_wide[plane_bsize];
1242 const struct macroblockd_plane *const pd = &xd->plane[plane];
1243 // TODO(aconverse@google.com): Investigate using crop_width/height here rather
1244 // than the MI size
1245 const int block_rows =
1246 (xd->mb_to_bottom_edge >= 0)
1247 ? block_height
1248 : (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
1249 const int block_cols =
1250 (xd->mb_to_right_edge >= 0)
1251 ? block_width
1252 : (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) + block_width;
1253 const int tx_unit_size = tx_size_wide_log2[0];
1254 if (width) *width = txb_width;
1255 if (height) *height = txb_height;
1256 *visible_width = clamp(block_cols - (blk_col << tx_unit_size), 0, txb_width);
1257 *visible_height =
1258 clamp(block_rows - (blk_row << tx_unit_size), 0, txb_height);
1259}
1260
1261// Compute the pixel domain sum square error on all visible 4x4s in the
1262// transform block.
1263static unsigned pixel_sse(const AV1_COMP *const cpi, const MACROBLOCKD *xd,
1264 int plane, const uint8_t *src, const int src_stride,
1265 const uint8_t *dst, const int dst_stride, int blk_row,
1266 int blk_col, const BLOCK_SIZE plane_bsize,
1267 const BLOCK_SIZE tx_bsize) {
1268 int txb_rows, txb_cols, visible_rows, visible_cols;
1269 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize,
1270 &txb_cols, &txb_rows, &visible_cols, &visible_rows);
1271 assert(visible_rows > 0);
1272 assert(visible_cols > 0);
1273 if (txb_rows == visible_rows && txb_cols == visible_cols) {
1274 unsigned sse;
1275 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse);
1276 return sse;
1277 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001278#if CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001279 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1280 uint64_t sse = aom_highbd_sse_odd_size(src, src_stride, dst, dst_stride,
1281 visible_cols, visible_rows);
1282 return (unsigned int)ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
1283 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001284#endif // CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001285 unsigned sse = aom_sse_odd_size(src, src_stride, dst, dst_stride,
1286 visible_cols, visible_rows);
1287 return sse;
1288}
1289
1290// Compute the squares sum squares on all visible 4x4s in the transform block.
1291static int64_t sum_squares_visible(const MACROBLOCKD *xd, int plane,
1292 const int16_t *diff, const int diff_stride,
1293 int blk_row, int blk_col,
1294 const BLOCK_SIZE plane_bsize,
1295 const BLOCK_SIZE tx_bsize) {
1296 int visible_rows, visible_cols;
1297 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize, NULL,
1298 NULL, &visible_cols, &visible_rows);
1299 return aom_sum_squares_2d_i16(diff, diff_stride, visible_cols, visible_rows);
1300}
1301
Angie Chiang808d8592017-04-06 18:36:55 -07001302void av1_dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
1303 BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col,
1304 TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse,
1305 OUTPUT_STATUS output_status) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 MACROBLOCKD *const xd = &x->e_mbd;
1307 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001308#if CONFIG_DAALA_DIST
1309 int qm = OD_HVS_QM;
1310 int use_activity_masking = 0;
1311#if CONFIG_PVQ
1312 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001313#endif // CONFIG_PVQ
Yushin Cho4483e3d2017-04-18 19:41:20 -07001314 struct macroblockd_plane *const pd = &xd->plane[plane];
1315#else // CONFIG_DAALA_DIST
1316 const struct macroblockd_plane *const pd = &xd->plane[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001317#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001318
1319 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
hui sud2f12ba2017-04-12 10:08:43 -07001320 // Transform domain distortion computation is more efficient as it does
Yaowu Xuc27fc142016-08-22 16:08:15 -07001321 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001322 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001323 int64_t this_sse;
Jingning Hanff705452017-04-27 11:32:15 -07001324 int shift = (MAX_TX_SCALE - av1_get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001325 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1326 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001327#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001328 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001329
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001330#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001332 *out_dist = av1_highbd_block_error2_c(coeff, dqcoeff, ref_coeff,
1333 buffer_length, &this_sse, bd) >>
1334 shift;
1335#else
1336 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1337 &this_sse) >>
1338 shift;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001339#endif // CONFIG_HIGHBITDEPTH
1340#elif CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001341 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001342 *out_dist =
1343 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1344 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345#else
1346 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001347 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001348#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001349 *out_sse = this_sse >> shift;
1350 } else {
1351 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Angie Chiang50910f62017-04-03 12:31:34 -07001352#if !CONFIG_PVQ || CONFIG_DAALA_DIST
Jingning Hanb9c57272016-10-25 10:15:39 -07001353 const int bsw = block_size_wide[tx_bsize];
1354 const int bsh = block_size_high[tx_bsize];
Angie Chiang50910f62017-04-03 12:31:34 -07001355#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356 const int src_stride = x->plane[plane].src.stride;
1357 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001358 // Scale the transform block index to pixel unit.
1359 const int src_idx = (blk_row * src_stride + blk_col)
1360 << tx_size_wide_log2[0];
1361 const int dst_idx = (blk_row * dst_stride + blk_col)
1362 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1364 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1365 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1366 const uint16_t eob = p->eobs[block];
1367
Yaowu Xuc27fc142016-08-22 16:08:15 -07001368 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001369 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370
Yushin Cho7a428ba2017-01-12 16:28:49 -08001371#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001372 if (plane == 0 && bsw >= 8 && bsh >= 8) {
1373 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
1374 const int pred_stride = block_size_wide[plane_bsize];
1375 const int pred_idx = (blk_row * pred_stride + blk_col)
1376 << tx_size_wide_log2[0];
1377 const int16_t *pred = &pd->pred[pred_idx];
1378 int i, j;
1379 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001380
Yushin Cho4483e3d2017-04-18 19:41:20 -07001381 for (j = 0; j < bsh; j++)
1382 for (i = 0; i < bsw; i++)
1383 pred8[j * bsw + i] = pred[j * pred_stride + i];
Alex Conversef323f012017-04-24 09:26:33 -07001384 *out_sse = av1_daala_dist(src, src_stride, pred8, bsw, bsw, bsh, qm,
1385 use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001386 } else {
Alex Conversef323f012017-04-24 09:26:33 -07001387 *out_sse = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1388 qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001389 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001390 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001391#endif // CONFIG_DAALA_DIST
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001392 {
1393 const int diff_stride = block_size_wide[plane_bsize];
1394 const int diff_idx = (blk_row * diff_stride + blk_col)
1395 << tx_size_wide_log2[0];
1396 const int16_t *diff = &p->src_diff[diff_idx];
Alex Conversef323f012017-04-24 09:26:33 -07001397 *out_sse = sum_squares_visible(xd, plane, diff, diff_stride, blk_row,
1398 blk_col, plane_bsize, tx_bsize);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001399#if CONFIG_HIGHBITDEPTH
hui sub1cc1f92017-04-11 17:41:29 -07001400 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Alex Conversef323f012017-04-24 09:26:33 -07001401 *out_sse = ROUND_POWER_OF_TWO(*out_sse, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001402#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001403 }
Alex Conversef323f012017-04-24 09:26:33 -07001404 *out_sse *= 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405
1406 if (eob) {
Angie Chiang228cc182017-04-07 15:22:16 -07001407 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001408#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001409 if (plane == 0 && bsw >= 8 && bsh >= 8)
Alex Conversef323f012017-04-24 09:26:33 -07001410 *out_dist = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1411 qm, use_activity_masking, x->qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001412 else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001413#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001414 *out_dist =
1415 pixel_sse(cpi, xd, plane, src, src_stride, dst, dst_stride,
1416 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001417 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001418#if CONFIG_HIGHBITDEPTH
Jingning Han6a9dbef2017-04-10 10:25:14 -07001419 uint8_t *recon;
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001420 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
Jingning Han6a9dbef2017-04-10 10:25:14 -07001421
1422 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1423 recon = CONVERT_TO_BYTEPTR(recon16);
1424 else
1425 recon = (uint8_t *)recon16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001426#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001427 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001428#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001429
Angie Chiang50910f62017-04-03 12:31:34 -07001430#if !CONFIG_PVQ
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001431#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001432 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1433 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
1434 NULL, 0, bsw, bsh, xd->bd);
1435 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001436#endif // CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001437 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL,
1438 0, bsw, bsh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001439#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001440 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001441#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001442#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001443 (void)dst;
Angie Chiang50910f62017-04-03 12:31:34 -07001444#endif // !CONFIG_PVQ
Angie Chiang41fffae2017-04-03 10:33:18 -07001445
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001446 const PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001447 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang41fffae2017-04-03 10:33:18 -07001448
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001449 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, recon,
1450 MAX_TX_SIZE, eob);
Angie Chiang41fffae2017-04-03 10:33:18 -07001451
Yushin Cho7a428ba2017-01-12 16:28:49 -08001452#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001453 if (plane == 0 && bsw >= 8 && bsh >= 8) {
Alex Conversef323f012017-04-24 09:26:33 -07001454 *out_dist = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, bsw,
1455 bsh, qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001456 } else {
Yushin Cho4483e3d2017-04-18 19:41:20 -07001457 if (plane == 0) {
1458 // Save decoded pixels for inter block in pd->pred to avoid
1459 // block_8x8_rd_txfm_daala_dist() need to produce them
1460 // by calling av1_inverse_transform_block() again.
1461 const int pred_stride = block_size_wide[plane_bsize];
1462 const int pred_idx = (blk_row * pred_stride + blk_col)
1463 << tx_size_wide_log2[0];
1464 int16_t *pred = &pd->pred[pred_idx];
1465 int i, j;
1466
1467 for (j = 0; j < bsh; j++)
1468 for (i = 0; i < bsw; i++)
1469 pred[j * pred_stride + i] = recon[j * MAX_TX_SIZE + i];
1470 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001471#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001472 *out_dist =
1473 pixel_sse(cpi, xd, plane, src, src_stride, recon, MAX_TX_SIZE,
1474 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001475#if CONFIG_DAALA_DIST
1476 }
1477#endif // CONFIG_DAALA_DIST
1478 }
Alex Conversef323f012017-04-24 09:26:33 -07001479 *out_dist *= 16;
1480 } else {
1481 *out_dist = *out_sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001482 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001483 }
1484}
1485
Yaowu Xuc27fc142016-08-22 16:08:15 -07001486static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1487 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1488 struct rdcost_block_args *args = arg;
1489 MACROBLOCK *const x = args->x;
1490 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001491 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiange50f3ec2017-04-10 15:50:33 -07001492 const AV1_COMP *cpi = args->cpi;
Angie Chiang65a39bb2017-04-11 16:50:04 -07001493 ENTROPY_CONTEXT *a = args->t_above + blk_col;
1494 ENTROPY_CONTEXT *l = args->t_left + blk_row;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001495#if !CONFIG_TXK_SEL
Angie Chiang18ad8942017-04-11 12:37:07 -07001496 const AV1_COMMON *cm = &cpi->common;
1497#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001498 int64_t rd1, rd2, rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001499 RD_STATS this_rd_stats;
Yushin Cho6341f5c2017-03-24 14:36:28 -07001500
Angie Chiangbc2288c2017-04-09 15:41:17 -07001501 assert(tx_size == get_tx_size(plane, xd));
1502
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001503 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504
1505 if (args->exit_early) return;
1506
1507 if (!is_inter_block(mbmi)) {
Luc Trudeauf5334002017-04-25 12:21:26 -04001508#if CONFIG_CFL
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001509
1510#if CONFIG_EC_ADAPT
1511 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
1512#else
1513 FRAME_CONTEXT *const ec_ctx = cm->fc;
1514#endif // CONFIG_EC_ADAPT
1515
1516 av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
1517 blk_row, tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04001518#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001519 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001520#endif
Angie Chiang62e54cd2017-04-06 10:45:56 -07001521 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
1522 }
1523
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001524#if !CONFIG_TXK_SEL
Angie Chiang62e54cd2017-04-06 10:45:56 -07001525 // full forward transform and quantization
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001526 const int coeff_ctx = combine_entropy_contexts(*a, *l);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001527 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1528 coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07001529 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001530
1531 if (!is_inter_block(mbmi)) {
1532 struct macroblock_plane *const p = &x->plane[plane];
Angie Chiangbc2288c2017-04-09 15:41:17 -07001533 av1_inverse_transform_block_facade(xd, plane, block, blk_row, blk_col,
1534 p->eobs[block]);
Angie Chiang808d8592017-04-06 18:36:55 -07001535 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1536 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1537 OUTPUT_HAS_DECODED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001538 } else {
Angie Chiang808d8592017-04-06 18:36:55 -07001539 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1540 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1541 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542 }
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001543#if CONFIG_CFL
1544 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1545 struct macroblockd_plane *const pd = &xd->plane[plane];
1546 const int dst_stride = pd->dst.stride;
1547 uint8_t *dst =
1548 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1549 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
1550 }
1551#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001552 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001553 if (args->this_rd + rd > args->best_rd) {
1554 args->exit_early = 1;
1555 return;
1556 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001557#if !CONFIG_PVQ
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001558 const PLANE_TYPE plane_type = get_plane_type(plane);
1559 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang18ad8942017-04-11 12:37:07 -07001560 const SCAN_ORDER *scan_order =
1561 get_scan(cm, tx_size, tx_type, is_inter_block(mbmi));
Angie Chiang05917872017-04-15 12:28:56 -07001562 this_rd_stats.rate =
1563 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l,
1564 args->use_fast_coef_costing);
Angie Chiang65a39bb2017-04-11 16:50:04 -07001565#else // !CONFIG_PVQ
1566 this_rd_stats.rate = x->rate;
1567#endif // !CONFIG_PVQ
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001568#else // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001569 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
1570 tx_size, a, l, args->use_fast_coef_costing,
1571 &this_rd_stats);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001572#endif // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001573
1574#if !CONFIG_PVQ
Angie Chiang3963d632016-11-10 18:41:40 -08001575#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001576 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1577 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001578#endif // CONFIG_RD_DEBUG
Yushin Cho6341f5c2017-03-24 14:36:28 -07001579 av1_set_txb_context(x, plane, block, tx_size, a, l);
Fergus Simpson4063a682017-02-28 16:52:22 -08001580#endif // !CONFIG_PVQ
Angie Chiangb3a12b52017-03-23 14:53:10 -07001581
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001582 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1583 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584
1585 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001586 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001587
Yushin Cho7a428ba2017-01-12 16:28:49 -08001588#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001589 if (plane == 0 &&
1590 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4)) {
1591 this_rd_stats.dist = 0;
1592 this_rd_stats.sse = 0;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001593 rd = 0;
1594 x->rate_4x4[block] = this_rd_stats.rate;
1595 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001596#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001597
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001598#if !CONFIG_PVQ
1599 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1600#else
1601 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001602#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001603 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001604
Yaowu Xuc27fc142016-08-22 16:08:15 -07001605 args->this_rd += rd;
1606
1607 if (args->this_rd > args->best_rd) {
1608 args->exit_early = 1;
1609 return;
1610 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611}
1612
Yushin Cho7a428ba2017-01-12 16:28:49 -08001613#if CONFIG_DAALA_DIST
1614static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
1615 int blk_col, BLOCK_SIZE plane_bsize,
1616 TX_SIZE tx_size, void *arg) {
1617 struct rdcost_block_args *args = arg;
1618 MACROBLOCK *const x = args->x;
1619 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001620 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1621 int64_t rd, rd1, rd2;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001622 RD_STATS this_rd_stats;
1623 int qm = OD_HVS_QM;
1624 int use_activity_masking = 0;
1625
Yushin Cho4483e3d2017-04-18 19:41:20 -07001626 (void)tx_size;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001627#if CONFIG_PVQ
1628 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001629#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08001630 av1_init_rd_stats(&this_rd_stats);
1631
1632 if (args->exit_early) return;
1633
1634 {
1635 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho4483e3d2017-04-18 19:41:20 -07001636 struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001637
1638 const int src_stride = p->src.stride;
1639 const int dst_stride = pd->dst.stride;
1640 const int diff_stride = block_size_wide[plane_bsize];
1641
1642 const uint8_t *src =
1643 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1644 const uint8_t *dst =
1645 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1646
Yushin Cho4483e3d2017-04-18 19:41:20 -07001647 unsigned int tmp1, tmp2;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001648 int qindex = x->qindex;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001649 const int pred_stride = block_size_wide[plane_bsize];
1650 const int pred_idx = (blk_row * pred_stride + blk_col)
1651 << tx_size_wide_log2[0];
1652 int16_t *pred = &pd->pred[pred_idx];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001653 int i, j;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001654 const int tx_blk_size = 8;
1655
1656 DECLARE_ALIGNED(16, uint8_t, pred8[8 * 8]);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001657
1658 for (j = 0; j < tx_blk_size; j++)
1659 for (i = 0; i < tx_blk_size; i++)
1660 pred8[j * tx_blk_size + i] = pred[j * diff_stride + i];
1661
Yushin Cho4483e3d2017-04-18 19:41:20 -07001662 tmp1 = av1_daala_dist(src, src_stride, pred8, tx_blk_size, 8, 8, qm,
1663 use_activity_masking, qindex);
1664 tmp2 = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8, qm,
1665 use_activity_masking, qindex);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001666
Yushin Cho4483e3d2017-04-18 19:41:20 -07001667 if (!is_inter_block(mbmi)) {
1668 this_rd_stats.sse = (int64_t)tmp1 * 16;
1669 this_rd_stats.dist = (int64_t)tmp2 * 16;
1670 } else {
1671 // For inter mode, the decoded pixels are provided in pd->pred,
1672 // while the predicted pixels are in dst.
1673 this_rd_stats.sse = (int64_t)tmp2 * 16;
1674 this_rd_stats.dist = (int64_t)tmp1 * 16;
1675 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001676 }
1677
1678 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
1679 if (args->this_rd + rd > args->best_rd) {
1680 args->exit_early = 1;
1681 return;
1682 }
1683
1684 {
1685 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
1686 // The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
1687 this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
1688 x->rate_4x4[block - max_blocks_wide] +
1689 x->rate_4x4[block - 1] + x->rate_4x4[block];
1690 }
1691 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1692 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001693 rd = AOMMIN(rd1, rd2);
1694
1695 args->rd_stats.dist += this_rd_stats.dist;
1696 args->rd_stats.sse += this_rd_stats.sse;
1697
1698 args->this_rd += rd;
1699
1700 if (args->this_rd > args->best_rd) {
1701 args->exit_early = 1;
1702 return;
1703 }
1704}
Fergus Simpson4063a682017-02-28 16:52:22 -08001705#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001706
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001707static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1708 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1709 BLOCK_SIZE bsize, TX_SIZE tx_size,
1710 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001711 MACROBLOCKD *const xd = &x->e_mbd;
1712 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001713 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001714 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715 args.x = x;
1716 args.cpi = cpi;
1717 args.best_rd = ref_best_rd;
1718 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001719 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001720
1721 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1722
Yaowu Xuf883b422016-08-30 14:01:10 -07001723 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001724
Yushin Cho7a428ba2017-01-12 16:28:49 -08001725#if CONFIG_DAALA_DIST
1726 if (plane == 0 &&
1727 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
1728 av1_foreach_8x8_transformed_block_in_plane(
1729 xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
1730 else
Fergus Simpson4063a682017-02-28 16:52:22 -08001731#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001732 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1733 &args);
1734
Yaowu Xuc27fc142016-08-22 16:08:15 -07001735 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001736 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001737 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001738 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001739 }
1740}
1741
1742#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001743void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1744 int64_t *distortion, int *skippable,
1745 int64_t *sse, int64_t ref_best_rd, int plane,
1746 BLOCK_SIZE bsize, TX_SIZE tx_size,
1747 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001748 MACROBLOCKD *const xd = &x->e_mbd;
1749 const struct macroblockd_plane *const pd = &xd->plane[plane];
1750 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001751 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001752 args.cpi = cpi;
1753 args.x = x;
1754 args.best_rd = ref_best_rd;
1755 args.use_fast_coef_costing = use_fast_coef_casting;
1756
1757#if CONFIG_EXT_TX
1758 assert(tx_size < TX_SIZES);
1759#endif // CONFIG_EXT_TX
1760
1761 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1762
Yaowu Xuf883b422016-08-30 14:01:10 -07001763 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001764
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1766 &args);
1767
1768 if (args.exit_early) {
1769 *rate = INT_MAX;
1770 *distortion = INT64_MAX;
1771 *sse = INT64_MAX;
1772 *skippable = 0;
1773 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001774 *distortion = args.rd_stats.dist;
1775 *rate = args.rd_stats.rate;
1776 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001777 *skippable = !x->plane[plane].eobs[0];
1778 }
1779}
1780#endif // CONFIG_SUPERTX
1781
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001782static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Urvang Joshifeb925f2016-12-05 10:37:29 -08001783 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1784 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001785 const MACROBLOCKD *const xd = &x->e_mbd;
1786 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001787
1788 const int tx_select =
1789 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1790
1791 if (tx_select) {
1792 const int is_inter = is_inter_block(mbmi);
1793 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1794 : intra_tx_size_cat_lookup[bsize];
1795 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1796 const int depth = tx_size_to_depth(coded_tx_size);
1797 const int tx_size_ctx = get_tx_size_context(xd);
1798 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1799 return r_tx_size;
1800 } else {
1801 return 0;
1802 }
1803}
1804
Angie Chiang65201562017-04-10 15:23:28 -07001805// #TODO(angiebird): use this function whenever it's possible
Angie Chiang05917872017-04-15 12:28:56 -07001806int av1_tx_type_cost(const AV1_COMP *cpi, const MACROBLOCKD *xd,
1807 BLOCK_SIZE bsize, int plane, TX_SIZE tx_size,
1808 TX_TYPE tx_type) {
1809 if (plane > 0) return 0;
1810
Angie Chiang65201562017-04-10 15:23:28 -07001811 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1812 const int is_inter = is_inter_block(mbmi);
1813#if CONFIG_EXT_TX
1814 const AV1_COMMON *cm = &cpi->common;
1815 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
1816 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1817 const int ext_tx_set =
1818 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
1819 if (is_inter) {
1820 if (ext_tx_set > 0)
1821 return cpi
1822 ->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]][tx_type];
1823 } else {
1824 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1825 return cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]]
1826 [mbmi->mode][tx_type];
1827 }
1828 }
1829#else
1830 (void)bsize;
1831 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1832 !FIXED_TX_TYPE) {
1833 if (is_inter) {
1834 return cpi->inter_tx_type_costs[tx_size][tx_type];
1835 } else {
1836 return cpi->intra_tx_type_costs[tx_size]
1837 [intra_mode_to_tx_type_context[mbmi->mode]]
1838 [tx_type];
1839 }
1840 }
1841#endif // CONFIG_EXT_TX
1842 return 0;
1843}
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001844static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1845 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1846 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001847 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848 MACROBLOCKD *const xd = &x->e_mbd;
1849 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1850 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001851 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001852 int s0, s1;
1853 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001854 const int tx_select =
1855 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001856
1857 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858
1859 assert(skip_prob > 0);
1860#if CONFIG_EXT_TX && CONFIG_RECT_TX
1861 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1862#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1863
Yaowu Xuf883b422016-08-30 14:01:10 -07001864 s0 = av1_cost_bit(skip_prob, 0);
1865 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866
1867 mbmi->tx_type = tx_type;
1868 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001869 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001871 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001872#if !CONFIG_TXK_SEL
Angie Chiang05917872017-04-15 12:28:56 -07001873 int plane = 0;
1874 rd_stats->rate += av1_tx_type_cost(cpi, xd, bs, plane, tx_size, tx_type);
1875#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001876
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001877 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001878 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001879 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001881 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1882 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 }
1884 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001885 rd = RDCOST(x->rdmult, x->rddiv,
1886 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001887 }
1888
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001889 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001890
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001891 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1892 !(rd_stats->skip))
1893 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001894
1895 return rd;
1896}
1897
Angie Chiang2d147c12017-04-05 11:23:59 -07001898static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
1899 TX_TYPE tx_type, TX_SIZE tx_size) {
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001900 const MACROBLOCKD *const xd = &x->e_mbd;
1901 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiang2d147c12017-04-05 11:23:59 -07001902 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1903 const int is_inter = is_inter_block(mbmi);
1904 int prune = 0;
1905 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1906 // passing -1 in for tx_type indicates that all 1D
1907 // transforms should be considered for pruning
1908 prune = prune_tx_types(cpi, bs, x, xd, -1);
1909
Angie Chianga4fa1902017-04-05 15:26:09 -07001910 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
Angie Chiang2d147c12017-04-05 11:23:59 -07001911 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
1912 return 1;
1913 if (!is_inter && x->use_default_intra_tx_type &&
1914 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1915 return 1;
1916 if (is_inter && x->use_default_inter_tx_type &&
1917 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1918 return 1;
1919 if (max_tx_size >= TX_32X32 && tx_size == TX_4X4) return 1;
1920#if CONFIG_EXT_TX
1921 const AV1_COMMON *const cm = &cpi->common;
1922 int ext_tx_set =
1923 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
1924 if (is_inter) {
1925 if (!ext_tx_used_inter[ext_tx_set][tx_type]) return 1;
1926 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1927 if (!do_tx_type_search(tx_type, prune)) return 1;
1928 }
1929 } else {
1930 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1931 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) return 1;
1932 }
1933 if (!ext_tx_used_intra[ext_tx_set][tx_type]) return 1;
1934 }
1935#else // CONFIG_EXT_TX
1936 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) return 1;
1937 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1938 !do_tx_type_search(tx_type, prune))
1939 return 1;
1940#endif // CONFIG_EXT_TX
1941 return 0;
1942}
1943
Yaowu Xuc27fc142016-08-22 16:08:15 -07001944#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001945static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1946 MACROBLOCK *x, int *r, int64_t *d, int *s,
1947 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001948 RD_STATS rd_stats;
1949 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1950 max_txsize_lookup[bs]);
1951 *r = rd_stats.rate;
1952 *d = rd_stats.dist;
1953 *s = rd_stats.skip;
1954 *sse = rd_stats.sse;
1955 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001956}
1957#endif // CONFIG_EXT_INTER
1958
Urvang Joshi52648442016-10-13 17:27:51 -07001959static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001960 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001961 BLOCK_SIZE bs) {
1962 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001963 MACROBLOCKD *const xd = &x->e_mbd;
1964 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1965 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001966 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001967 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1968 int s0 = av1_cost_bit(skip_prob, 0);
1969 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001970 const int is_inter = is_inter_block(mbmi);
1971 int prune = 0;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07001972 const int plane = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973#if CONFIG_EXT_TX
1974 int ext_tx_set;
1975#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001976 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977
1978 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001979#if CONFIG_VAR_TX
1980 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08001981#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001982#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001983 ext_tx_set =
1984 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985#endif // CONFIG_EXT_TX
1986
1987 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1988#if CONFIG_EXT_TX
1989 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1990#else
1991 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08001992#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001993#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001994 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
1995 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001996 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001997#if CONFIG_PVQ
1998 od_rollback_buffer pre_buf, post_buf;
1999
2000 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2001 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002002#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002003
2004 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002005 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006 if (is_inter) {
2007 if (x->use_default_inter_tx_type &&
2008 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2009 continue;
2010 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2011 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2012 if (!do_tx_type_search(tx_type, prune)) continue;
2013 }
2014 } else {
2015 if (x->use_default_intra_tx_type &&
2016 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2017 continue;
2018 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2019 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2020 }
2021 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2022 }
2023
2024 mbmi->tx_type = tx_type;
2025
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002026 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002027 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002028#if CONFIG_PVQ
2029 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002030#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002031 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002032 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002034 if (this_rd_stats.skip)
2035 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002036 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002037 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2038 this_rd_stats.dist);
2039 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2040 !this_rd_stats.skip)
2041 this_rd =
2042 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002043
2044 if (this_rd < best_rd) {
2045 best_rd = this_rd;
2046 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002047 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002048#if CONFIG_PVQ
2049 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002050#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002051 }
2052 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002053#if CONFIG_PVQ
2054 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002055#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002056 } else {
2057 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002058 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2059 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002060 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061#else // CONFIG_EXT_TX
2062 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2063 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002064 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002065 if (!is_inter && x->use_default_intra_tx_type &&
2066 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2067 continue;
2068 if (is_inter && x->use_default_inter_tx_type &&
2069 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2070 continue;
2071 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002072 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002073 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002074 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002075
2076 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002077 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002078 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2079 !do_tx_type_search(tx_type, prune))
2080 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002081 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002082 if (this_rd_stats.skip)
2083 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002084 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002085 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2086 this_rd_stats.dist);
2087 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2088 this_rd =
2089 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090
2091 if (this_rd < best_rd) {
2092 best_rd = this_rd;
2093 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002094 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002095 }
2096 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002097 } else {
2098 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002099 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2100 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101 }
2102#endif // CONFIG_EXT_TX
2103 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002104}
2105
Urvang Joshi52648442016-10-13 17:27:51 -07002106static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002107 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002108 BLOCK_SIZE bs) {
2109 MACROBLOCKD *const xd = &x->e_mbd;
2110 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2111
2112 mbmi->tx_size = TX_4X4;
2113 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002114#if CONFIG_VAR_TX
2115 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002116#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002117
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002118 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2119 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120}
2121
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002122#if CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002123static INLINE int bsize_to_num_blk(BLOCK_SIZE bsize) {
2124 int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
2125 return num_blk;
2126}
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002127#endif // CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002128
Urvang Joshi52648442016-10-13 17:27:51 -07002129static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002130 MACROBLOCK *x, RD_STATS *rd_stats,
2131 int64_t ref_best_rd, BLOCK_SIZE bs) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002132 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133 MACROBLOCKD *const xd = &x->e_mbd;
2134 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002135 int64_t rd = INT64_MAX;
Angie Chianga4fa1902017-04-05 15:26:09 -07002136 int n;
2137 int start_tx, end_tx;
2138 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
2139 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2140 TX_SIZE best_tx_size = max_tx_size;
2141 TX_TYPE best_tx_type = DCT_DCT;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002142#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002143 TX_TYPE best_txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
2144 const int num_blk = bsize_to_num_blk(bs);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002145#endif // CONFIG_TXK_SEL
Angie Chianga4fa1902017-04-05 15:26:09 -07002146 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
2147 const int is_inter = is_inter_block(mbmi);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002148#if CONFIG_PVQ
2149 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002150 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002151#endif // CONFIG_PVQ
Angie Chianga4fa1902017-04-05 15:26:09 -07002152
2153 av1_invalid_rd_stats(rd_stats);
2154
2155#if CONFIG_EXT_TX && CONFIG_RECT_TX
2156 int evaluate_rect_tx = 0;
2157 if (tx_select) {
2158 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
2159 } else {
2160 const TX_SIZE chosen_tx_size =
2161 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2162 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
2163 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
2164 }
2165 if (evaluate_rect_tx) {
Angie Chiangf1cb0752017-04-10 16:01:20 -07002166 TX_TYPE tx_start = DCT_DCT;
2167 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002168#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002169 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2170 // performed in av1_search_txk_type()
2171 tx_end = DCT_DCT + 1;
2172#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002173 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002174 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002175 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Angie Chianga4fa1902017-04-05 15:26:09 -07002176 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
2177 RD_STATS this_rd_stats;
2178 int ext_tx_set =
2179 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
2180 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2181 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2182 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
2183 rect_tx_size);
2184 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002185#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002186 memcpy(best_txk_type, mbmi->txk_type,
2187 sizeof(best_txk_type[0]) * num_blk);
2188#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002189 best_tx_type = tx_type;
2190 best_tx_size = rect_tx_size;
2191 best_rd = rd;
2192 *rd_stats = this_rd_stats;
2193 }
2194 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002195#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002196 const int is_inter = is_inter_block(mbmi);
2197 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002198#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002199 }
2200 }
2201#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2202
2203 if (tx_select) {
2204 start_tx = max_tx_size;
2205 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
2206 } else {
2207 const TX_SIZE chosen_tx_size =
2208 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2209 start_tx = chosen_tx_size;
2210 end_tx = chosen_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002211 }
2212
Angie Chianga4fa1902017-04-05 15:26:09 -07002213 last_rd = INT64_MAX;
2214 for (n = start_tx; n >= end_tx; --n) {
Sarah Parker36661922017-04-13 14:26:49 -07002215#if CONFIG_EXT_TX && CONFIG_RECT_TX
2216 if (is_rect_tx(n)) break;
2217#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002218 TX_TYPE tx_start = DCT_DCT;
2219 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002220#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002221 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2222 // performed in av1_search_txk_type()
2223 tx_end = DCT_DCT + 1;
2224#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002225 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002226 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002227 RD_STATS this_rd_stats;
2228 if (skip_txfm_search(cpi, x, bs, tx_type, n)) continue;
2229 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
2230#if CONFIG_PVQ
2231 od_encode_rollback(&x->daala_enc, &buf);
2232#endif // CONFIG_PVQ
2233 // Early termination in transform size search.
2234 if (cpi->sf.tx_size_search_breakout &&
2235 (rd == INT64_MAX ||
2236 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
2237 (n < (int)max_tx_size && rd > last_rd)))
2238 break;
2239
2240 last_rd = rd;
2241 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002242#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002243 memcpy(best_txk_type, mbmi->txk_type,
2244 sizeof(best_txk_type[0]) * num_blk);
2245#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002246 best_tx_type = tx_type;
2247 best_tx_size = n;
2248 best_rd = rd;
2249 *rd_stats = this_rd_stats;
2250 }
2251#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2252 const int is_inter = is_inter_block(mbmi);
2253 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2254#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2255 }
2256 }
2257 mbmi->tx_size = best_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002258 mbmi->tx_type = best_tx_type;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002259#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002260 memcpy(mbmi->txk_type, best_txk_type, sizeof(best_txk_type[0]) * num_blk);
2261#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002262
Jingning Hane67b38a2016-11-04 10:30:00 -07002263#if CONFIG_VAR_TX
2264 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002265#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002266
Yaowu Xuc27fc142016-08-22 16:08:15 -07002267#if !CONFIG_EXT_TX
2268 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002269#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002270#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002271 if (best_rd != INT64_MAX) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002272 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx_size);
Yushin Cho05f540a2016-11-08 22:12:51 -08002273 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002274#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002275}
2276
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002277static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2278 RD_STATS *rd_stats, BLOCK_SIZE bs,
2279 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002280 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002281 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002282
2283 assert(bs == xd->mi[0]->mbmi.sb_type);
2284
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002285 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002286 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002287 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002288 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002289 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002290 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002291 }
2292}
2293
2294static int conditional_skipintra(PREDICTION_MODE mode,
2295 PREDICTION_MODE best_intra_mode) {
2296 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2297 best_intra_mode != D135_PRED)
2298 return 1;
2299 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2300 best_intra_mode != D45_PRED)
2301 return 1;
2302 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2303 best_intra_mode != D45_PRED)
2304 return 1;
2305 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2306 best_intra_mode != D135_PRED)
2307 return 1;
2308 return 0;
2309}
2310
hui su308a6392017-01-12 14:49:57 -08002311// Model based RD estimation for luma intra blocks.
2312static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002313 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002314 MACROBLOCKD *const xd = &x->e_mbd;
2315 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002316 assert(!is_inter_block(mbmi));
hui su308a6392017-01-12 14:49:57 -08002317 RD_STATS this_rd_stats;
2318 int row, col;
2319 int64_t temp_sse, this_rd;
2320 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2321 const int stepr = tx_size_high_unit[tx_size];
2322 const int stepc = tx_size_wide_unit[tx_size];
2323 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2324 const int max_blocks_high = max_block_high(xd, bsize, 0);
2325 mbmi->tx_size = tx_size;
2326 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002327 const int step = stepr * stepc;
2328 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002329 for (row = 0; row < max_blocks_high; row += stepr) {
2330 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002331#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09002332 const struct macroblockd_plane *const pd = &xd->plane[0];
2333 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002334
2335#if CONFIG_EC_ADAPT
2336 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
2337#else
Luc Trudeau64ed2ce2017-05-12 12:01:24 -04002338 FRAME_CONTEXT *const ec_ctx = cpi->common.fc;
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002339#endif // CONFIG_EC_ADAPT
2340
2341 av1_predict_intra_block_encoder_facade(x, ec_ctx, 0, block, col, row,
2342 tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04002343#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002344 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002345#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002346 block += step;
hui su308a6392017-01-12 14:49:57 -08002347 }
2348 }
2349 // RD estimation.
2350 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2351 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002352#if CONFIG_EXT_INTRA
2353 if (av1_is_directional_mode(mbmi->mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002354 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2355 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002356 }
2357#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002358#if CONFIG_FILTER_INTRA
2359 if (mbmi->mode == DC_PRED) {
2360 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2361 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2362 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2363 mode_cost += (av1_cost_bit(prob, 1) +
2364 write_uniform_cost(FILTER_INTRA_MODES, mode));
2365 } else {
2366 mode_cost += av1_cost_bit(prob, 0);
2367 }
2368 }
2369#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002370 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2371 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002372 return this_rd;
2373}
2374
Urvang Joshib100db72016-10-12 16:28:56 -07002375#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002376// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2377// new_height'. Extra rows and columns are filled in by copying last valid
2378// row/column.
2379static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2380 int orig_height, int new_width,
2381 int new_height) {
2382 int j;
2383 assert(new_width >= orig_width);
2384 assert(new_height >= orig_height);
2385 if (new_width == orig_width && new_height == orig_height) return;
2386
2387 for (j = orig_height - 1; j >= 0; --j) {
2388 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2389 // Copy last column to extra columns.
2390 memset(color_map + j * new_width + orig_width,
2391 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2392 }
2393 // Copy last row to extra rows.
2394 for (j = orig_height; j < new_height; ++j) {
2395 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2396 new_width);
2397 }
2398}
2399
hui su33567b22017-04-30 16:40:19 -07002400#if CONFIG_PALETTE_DELTA_ENCODING
2401// Bias toward using colors in the cache.
2402// TODO(huisu): Try other schemes to improve compression.
2403static void optimize_palette_colors(uint16_t *color_cache, int n_cache,
2404 int n_colors, int stride,
2405 float *centroids) {
2406 if (n_cache <= 0) return;
2407 for (int i = 0; i < n_colors * stride; i += stride) {
2408 float min_diff = fabsf(centroids[i] - color_cache[0]);
2409 int idx = 0;
2410 for (int j = 1; j < n_cache; ++j) {
2411 float this_diff = fabsf(centroids[i] - color_cache[j]);
2412 if (this_diff < min_diff) {
2413 min_diff = this_diff;
2414 idx = j;
2415 }
2416 }
2417 if (min_diff < 1.5) centroids[i] = color_cache[idx];
2418 }
2419}
2420#endif // CONFIG_PALETTE_DELTA_ENCODING
2421
hui sude0c70a2017-01-09 17:12:17 -08002422static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2423 BLOCK_SIZE bsize, int palette_ctx,
2424 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2425 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002426 int64_t *best_rd, int64_t *best_model_rd,
2427 int *rate, int *rate_tokenonly,
2428 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002429 int rate_overhead = 0;
2430 MACROBLOCKD *const xd = &x->e_mbd;
2431 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002432 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002433 assert(!is_inter_block(mbmi));
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002434 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435 const int src_stride = x->plane[0].src.stride;
2436 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002437 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002438 int block_width, block_height, rows, cols;
2439 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2440 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002441
2442 assert(cpi->common.allow_screen_content_tools);
2443
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002444#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002445 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002446 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2447 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002449#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002450 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002451#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002452 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002453#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002454
2455 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002456 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002458 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002459 float *const data = x->palette_buffer->kmeans_data_buf;
2460 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002461 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002462 RD_STATS tokenonly_rd_stats;
2463 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002464 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002465#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002466 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2467 if (cpi->common.use_highbitdepth)
2468 lb = ub = src16[0];
2469 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002470#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471 lb = ub = src[0];
2472
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002473#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002474 if (cpi->common.use_highbitdepth) {
2475 for (r = 0; r < rows; ++r) {
2476 for (c = 0; c < cols; ++c) {
2477 val = src16[r * src_stride + c];
2478 data[r * cols + c] = val;
2479 if (val < lb)
2480 lb = val;
2481 else if (val > ub)
2482 ub = val;
2483 }
2484 }
2485 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002486#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002487 for (r = 0; r < rows; ++r) {
2488 for (c = 0; c < cols; ++c) {
2489 val = src[r * src_stride + c];
2490 data[r * cols + c] = val;
2491 if (val < lb)
2492 lb = val;
2493 else if (val > ub)
2494 ub = val;
2495 }
2496 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002497#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002498 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002499#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002500
2501 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002502#if CONFIG_FILTER_INTRA
2503 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2504#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002505
2506 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2507
hui su33567b22017-04-30 16:40:19 -07002508#if CONFIG_PALETTE_DELTA_ENCODING
2509 const MODE_INFO *above_mi = xd->above_mi;
2510 const MODE_INFO *left_mi = xd->left_mi;
2511 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
2512 const int n_cache =
2513 av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
2514#endif // CONFIG_PALETTE_DELTA_ENCODING
2515
Yaowu Xuc27fc142016-08-22 16:08:15 -07002516 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2517 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002518 if (colors == PALETTE_MIN_SIZE) {
2519 // Special case: These colors automatically become the centroids.
2520 assert(colors == n);
2521 assert(colors == 2);
2522 centroids[0] = lb;
2523 centroids[1] = ub;
2524 k = 2;
2525 } else {
2526 for (i = 0; i < n; ++i) {
2527 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2528 }
2529 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
hui su33567b22017-04-30 16:40:19 -07002530#if CONFIG_PALETTE_DELTA_ENCODING
2531 optimize_palette_colors(color_cache, n_cache, n, 1, centroids);
2532#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi773e3542017-05-05 18:09:42 -07002533 k = av1_remove_duplicates(centroids, n);
2534 if (k < PALETTE_MIN_SIZE) {
2535 // Too few unique colors to create a palette. And DC_PRED will work
2536 // well for that case anyway. So skip.
2537 continue;
2538 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002539 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002540
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002541#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002542 if (cpi->common.use_highbitdepth)
2543 for (i = 0; i < k; ++i)
2544 pmi->palette_colors[i] =
2545 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2546 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002547#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 for (i = 0; i < k; ++i)
2549 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2550 pmi->palette_size[0] = k;
2551
Yaowu Xuf883b422016-08-30 14:01:10 -07002552 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002553 extend_palette_color_map(color_map, cols, rows, block_width,
2554 block_height);
hui su78c611a2017-01-13 17:06:04 -08002555 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002556 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002557 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002559 av1_cost_bit(
2560 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002561 1);
hui su33567b22017-04-30 16:40:19 -07002562 palette_mode_cost += av1_palette_color_cost_y(pmi,
2563#if CONFIG_PALETTE_DELTA_ENCODING
2564 color_cache, n_cache,
2565#endif // CONFIG_PALETTE_DELTA_ENCODING
2566 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002567 for (i = 0; i < rows; ++i) {
2568 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002569 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002570 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002571 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002572 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002573 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2574 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575 }
2576 }
hui su78c611a2017-01-13 17:06:04 -08002577 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2578 if (*best_model_rd != INT64_MAX &&
2579 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2580 continue;
2581 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2582 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2583 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2584 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002585 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002586 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002587 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002588 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002589 if (this_rd < *best_rd) {
2590 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002591 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002592 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002593 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002594 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002595 if (rate) *rate = this_rate;
2596 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2597 if (distortion) *distortion = tokenonly_rd_stats.dist;
2598 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 }
2600 }
2601 }
hui sude0c70a2017-01-09 17:12:17 -08002602
2603 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2604 memcpy(color_map, best_palette_color_map,
2605 rows * cols * sizeof(best_palette_color_map[0]));
2606 }
2607 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002608 return rate_overhead;
2609}
Urvang Joshib100db72016-10-12 16:28:56 -07002610#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002611
Urvang Joshifeb925f2016-12-05 10:37:29 -08002612static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002613 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2614 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2615 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002616 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002617 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002618 PREDICTION_MODE mode;
2619 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi330aec82017-05-08 15:37:42 -07002620 assert(!is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002621 int64_t best_rd = rd_thresh;
2622 struct macroblock_plane *p = &x->plane[0];
2623 struct macroblockd_plane *pd = &xd->plane[0];
2624 const int src_stride = p->src.stride;
2625 const int dst_stride = pd->dst.stride;
2626 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002627 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002628#if CONFIG_CB4X4
2629 // TODO(jingning): This is a temporal change. The whole function should be
2630 // out when cb4x4 is enabled.
2631 ENTROPY_CONTEXT ta[4], tempa[4];
2632 ENTROPY_CONTEXT tl[4], templ[4];
2633#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634 ENTROPY_CONTEXT ta[2], tempa[2];
2635 ENTROPY_CONTEXT tl[2], templ[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08002636#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002637
2638 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2639 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2640 const int tx_width_unit = tx_size_wide_unit[tx_size];
2641 const int tx_height_unit = tx_size_high_unit[tx_size];
2642 const int pred_block_width = block_size_wide[bsize];
2643 const int pred_block_height = block_size_high[bsize];
2644 const int tx_width = tx_size_wide[tx_size];
2645 const int tx_height = tx_size_high[tx_size];
2646 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2647 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002648 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002649 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002650 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002651#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002652 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002653#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002654 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2655#if CONFIG_EXT_TX && CONFIG_RECT_TX
2656 const int sub_bsize = bsize;
2657#else
2658 const int sub_bsize = BLOCK_4X4;
2659#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002660
Yushin Cho77bba8d2016-11-04 16:36:56 -07002661#if CONFIG_PVQ
2662 od_rollback_buffer pre_buf, post_buf;
2663 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2664 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002665#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002666
Urvang Joshifeb925f2016-12-05 10:37:29 -08002667 assert(bsize < BLOCK_8X8);
2668 assert(tx_width < 8 || tx_height < 8);
2669#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002670 if (is_lossless)
2671 assert(tx_width == 4 && tx_height == 4);
2672 else
2673 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002674#else
2675 assert(tx_width == 4 && tx_height == 4);
2676#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2677
2678 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2679 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2680
2681 xd->mi[0]->mbmi.tx_size = tx_size;
2682
Urvang Joshib100db72016-10-12 16:28:56 -07002683#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002684 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002685#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002686
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002687#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002688 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002689#if CONFIG_PVQ
2690 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2691#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002692 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2693 int64_t this_rd;
2694 int ratey = 0;
2695 int64_t distortion = 0;
2696 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002697 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698
Urvang Joshifeb925f2016-12-05 10:37:29 -08002699 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2700 (1 << mode)))
2701 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002702
2703 // Only do the oblique modes if the best so far is
2704 // one of the neighboring directional modes
2705 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2706 if (conditional_skipintra(mode, *best_mode)) continue;
2707 }
2708
Urvang Joshifeb925f2016-12-05 10:37:29 -08002709 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2710 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002711
Urvang Joshifeb925f2016-12-05 10:37:29 -08002712 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2713 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2714 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2715 const int block =
2716 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002717 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2718 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08002719#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002720 int16_t *const src_diff = av1_raster_block_offset_int16(
2721 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002722#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002723 int skip;
2724 assert(block < 4);
2725 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2726 idx == 0 && idy == 0));
2727 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2728 block == 0 || block == 2));
2729 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002730 av1_predict_intra_block(
2731 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2732 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002733#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002734 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2735 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002736#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002737 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07002738 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002739 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002740 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002741 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002742#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002743 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002744 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07002745 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002746 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002747 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002748 skip = (p->eobs[block] == 0);
2749 can_skip &= skip;
2750 tempa[idx] = !skip;
2751 templ[idy] = !skip;
2752#if CONFIG_EXT_TX
2753 if (tx_size == TX_8X4) {
2754 tempa[idx + 1] = tempa[idx];
2755 } else if (tx_size == TX_4X8) {
2756 templ[idy + 1] = templ[idy];
2757 }
2758#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002759#else
2760 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002761
Thomas Daede6ff6af62017-02-03 16:29:24 -08002762 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2763 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
2764
2765 ratey += x->rate;
2766 skip = x->pvq_skip[0];
2767 tempa[idx] = !skip;
2768 templ[idy] = !skip;
2769 can_skip &= skip;
2770#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002771 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2772 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08002773#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002774 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002775#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002776 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2777 DCT_DCT, tx_size, dst, dst_stride,
2778 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779 } else {
2780 int64_t dist;
2781 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07002782 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002783 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
Angie Chiangff6d8902016-10-21 11:02:09 -07002787 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002788 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002789 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07002790 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002791 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002792 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002793 skip = (p->eobs[block] == 0);
2794 can_skip &= skip;
2795 tempa[idx] = !skip;
2796 templ[idy] = !skip;
2797#if CONFIG_EXT_TX
2798 if (tx_size == TX_8X4) {
2799 tempa[idx + 1] = tempa[idx];
2800 } else if (tx_size == TX_4X8) {
2801 templ[idy + 1] = templ[idy];
2802 }
2803#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002804#else
2805 (void)scan_order;
2806
2807 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2808 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2809 ratey += x->rate;
2810 skip = x->pvq_skip[0];
2811 tempa[idx] = !skip;
2812 templ[idy] = !skip;
2813 can_skip &= skip;
2814#endif
2815#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002816 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002817#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002818 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2819 tx_type, tx_size, dst, dst_stride,
2820 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002821 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822 dist = (int64_t)tmp << 4;
2823 distortion += dist;
2824 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2825 goto next_highbd;
2826 }
2827 }
2828 }
2829
2830 rate += ratey;
2831 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2832
2833 if (this_rd < best_rd) {
2834 *bestrate = rate;
2835 *bestratey = ratey;
2836 *bestdistortion = distortion;
2837 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002838 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002839 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002840 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2841 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08002842#if CONFIG_PVQ
2843 od_encode_checkpoint(&x->daala_enc, &post_buf);
2844#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002845 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846 memcpy(best_dst16 + idy * 8,
2847 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002848 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002849 }
2850 }
2851 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08002852#if CONFIG_PVQ
2853 od_encode_rollback(&x->daala_enc, &pre_buf);
2854#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855 }
2856
2857 if (best_rd >= rd_thresh) return best_rd;
2858
Thomas Daede6ff6af62017-02-03 16:29:24 -08002859#if CONFIG_PVQ
2860 od_encode_rollback(&x->daala_enc, &post_buf);
2861#endif
2862
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002863 if (y_skip) *y_skip &= best_can_skip;
2864
Urvang Joshifeb925f2016-12-05 10:37:29 -08002865 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002866 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002867 best_dst16 + idy * 8,
2868 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002869 }
2870
2871 return best_rd;
2872 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002873#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002874
Yushin Cho77bba8d2016-11-04 16:36:56 -07002875#if CONFIG_PVQ
2876 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002877#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002878
Yaowu Xuc27fc142016-08-22 16:08:15 -07002879 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2880 int64_t this_rd;
2881 int ratey = 0;
2882 int64_t distortion = 0;
2883 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002884 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002885
Urvang Joshifeb925f2016-12-05 10:37:29 -08002886 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2887 (1 << mode))) {
2888 continue;
2889 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002890
2891 // Only do the oblique modes if the best so far is
2892 // one of the neighboring directional modes
2893 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2894 if (conditional_skipintra(mode, *best_mode)) continue;
2895 }
2896
Urvang Joshifeb925f2016-12-05 10:37:29 -08002897 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2898 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002899
Urvang Joshifeb925f2016-12-05 10:37:29 -08002900 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2901 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2902 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2903 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002904 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2905 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002906#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002907 int16_t *const src_diff = av1_raster_block_offset_int16(
2908 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08002909#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002910 int skip;
2911 assert(block < 4);
2912 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2913 idx == 0 && idy == 0));
2914 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2915 block == 0 || block == 2));
2916 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002917 av1_predict_intra_block(xd, pd->width, pd->height,
2918 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2919 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002920#if CONFIG_CB4X4
2921 2 * (col + idx), 2 * (row + idy),
2922#else
2923 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002924#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002925 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002926#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002927 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2928 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002929#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002930
Urvang Joshi14731732017-04-27 18:40:49 -07002931 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
2932 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
2933 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002934#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002935 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002936#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002937#if !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002938 const AV1_XFORM_QUANT xform_quant =
2939 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
2940 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08002941#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002942 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08002943#else
Urvang Joshi14731732017-04-27 18:40:49 -07002944 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002945#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002946 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08002947
Angie Chiang7dec6c42017-05-03 17:58:17 -07002948 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Urvang Joshi14731732017-04-27 18:40:49 -07002949
2950 ratey +=
2951 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
2952 templ + idy, cpi->sf.use_fast_coef_costing);
2953 skip = (p->eobs[block] == 0);
2954 can_skip &= skip;
2955 tempa[idx] = !skip;
2956 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002957#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07002958 if (tx_size == TX_8X4) {
2959 tempa[idx + 1] = tempa[idx];
2960 } else if (tx_size == TX_4X8) {
2961 templ[idy + 1] = templ[idy];
2962 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08002963#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002964#else
Urvang Joshi14731732017-04-27 18:40:49 -07002965 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08002966
Urvang Joshi14731732017-04-27 18:40:49 -07002967 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08002968#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002969 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08002970#else
Urvang Joshi14731732017-04-27 18:40:49 -07002971 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002972#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002973 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2974
2975 ratey += x->rate;
2976 skip = x->pvq_skip[0];
2977 tempa[idx] = !skip;
2978 templ[idy] = !skip;
2979 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002980#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002981
2982 if (!is_lossless) { // To use the pixel domain distortion, we need to
2983 // calculate inverse txfm *before* calculating RD
2984 // cost. Compared to calculating the distortion in
2985 // the frequency domain, the overhead of encoding
2986 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08002987#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002988 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08002989#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002990 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2991 tx_type, tx_size, dst, dst_stride,
2992 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07002993 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002994 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07002995 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002996 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07002997 }
2998
2999 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
3000 goto next;
3001
3002 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
3003#if CONFIG_PVQ
3004 if (!skip)
3005#endif // CONFIG_PVQ
3006 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3007 DCT_DCT, tx_size, dst, dst_stride,
3008 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003009 }
3010 }
3011 }
3012
3013 rate += ratey;
3014 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
3015
3016 if (this_rd < best_rd) {
3017 *bestrate = rate;
3018 *bestratey = ratey;
3019 *bestdistortion = distortion;
3020 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003021 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003023 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3024 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003025#if CONFIG_PVQ
3026 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003027#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003028 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003029 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003030 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003031 }
3032 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003033#if CONFIG_PVQ
3034 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003035#endif // CONFIG_PVQ
3036 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003037
3038 if (best_rd >= rd_thresh) return best_rd;
3039
Yushin Cho77bba8d2016-11-04 16:36:56 -07003040#if CONFIG_PVQ
3041 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003042#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003043
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003044 if (y_skip) *y_skip &= best_can_skip;
3045
Urvang Joshifeb925f2016-12-05 10:37:29 -08003046 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003047 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003048 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003049
3050 return best_rd;
3051}
3052
Urvang Joshi52648442016-10-13 17:27:51 -07003053static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3054 MACROBLOCK *mb, int *rate,
3055 int *rate_y, int64_t *distortion,
3056 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003057 const MACROBLOCKD *const xd = &mb->e_mbd;
3058 MODE_INFO *const mic = xd->mi[0];
3059 const MODE_INFO *above_mi = xd->above_mi;
3060 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003061 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003062 assert(!is_inter_block(mbmi));
Urvang Joshifeb925f2016-12-05 10:37:29 -08003063 const BLOCK_SIZE bsize = mbmi->sb_type;
3064 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3065 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003066 int idx, idy;
3067 int cost = 0;
3068 int64_t total_distortion = 0;
3069 int tot_rate_y = 0;
3070 int64_t total_rd = 0;
3071 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003072 const int is_lossless = xd->lossless[mbmi->segment_id];
3073#if CONFIG_EXT_TX && CONFIG_RECT_TX
3074 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3075#else
3076 const TX_SIZE tx_size = TX_4X4;
3077#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003078
3079#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003080#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003081 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003082#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003083#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003084#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003085 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003086#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003087
3088 // TODO(any): Add search of the tx_type to improve rd performance at the
3089 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003090 mbmi->tx_type = DCT_DCT;
3091 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003093 if (y_skip) *y_skip = 1;
3094
Urvang Joshifeb925f2016-12-05 10:37:29 -08003095 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3096 // 8x8 coding block.
3097 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3098 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003099 PREDICTION_MODE best_mode = DC_PRED;
3100 int r = INT_MAX, ry = INT_MAX;
3101 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003102 int j;
3103 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003104 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003105 const PREDICTION_MODE A =
3106 av1_above_block_mode(mic, above_mi, pred_block_idx);
3107 const PREDICTION_MODE L =
3108 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003109
3110 bmode_costs = cpi->y_mode_costs[A][L];
3111 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003112 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003113 cpi, mb, idy, idx, &best_mode, bmode_costs,
3114 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003115 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003116#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003117 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003118#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003119 total_rd += this_rd;
3120 cost += r;
3121 total_distortion += d;
3122 tot_rate_y += ry;
3123
Urvang Joshifeb925f2016-12-05 10:37:29 -08003124 mic->bmi[pred_block_idx].as_mode = best_mode;
3125 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3126 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3127 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3128 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003129
3130 if (total_rd >= best_rd) return INT64_MAX;
3131 }
3132 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003133 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003134
Yushin Cho7a428ba2017-01-12 16:28:49 -08003135#if CONFIG_DAALA_DIST
3136 {
3137 const struct macroblock_plane *p = &mb->plane[0];
3138 const struct macroblockd_plane *pd = &xd->plane[0];
3139 const int src_stride = p->src.stride;
3140 const int dst_stride = pd->dst.stride;
3141 uint8_t *src = p->src.buf;
3142 uint8_t *dst = pd->dst.buf;
3143 int use_activity_masking = 0;
3144 int qm = OD_HVS_QM;
3145
3146#if CONFIG_PVQ
3147 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003148#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003149 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho4483e3d2017-04-18 19:41:20 -07003150 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8,
Yushin Cho7a428ba2017-01-12 16:28:49 -08003151 qm, use_activity_masking, mb->qindex)
3152 << 4;
3153 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003154#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003155 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003156 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 int rate_tx_type = 0;
3158#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003159 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3160 1) {
3161 const int eset =
3162 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003163 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3164 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003165 }
3166#else
clang-format67948d32016-09-07 22:40:40 -07003167 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003168 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3169 [intra_mode_to_tx_type_context[mbmi->mode]]
3170 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003171#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003172 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003173 cost += rate_tx_type;
3174 tot_rate_y += rate_tx_type;
3175 }
3176
3177 *rate = cost;
3178 *rate_y = tot_rate_y;
3179 *distortion = total_distortion;
3180
3181 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3182}
3183
hui su5db97432016-10-14 16:10:14 -07003184#if CONFIG_FILTER_INTRA
3185// Return 1 if an filter intra mode is selected; return 0 otherwise.
3186static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3187 int *rate, int *rate_tokenonly,
3188 int64_t *distortion, int *skippable,
3189 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003190 int64_t *best_rd, int64_t *best_model_rd,
3191 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003192 MACROBLOCKD *const xd = &x->e_mbd;
3193 MODE_INFO *const mic = xd->mi[0];
3194 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003195 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003196 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003197 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003198 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003199 TX_TYPE best_tx_type;
3200
hui su5db97432016-10-14 16:10:14 -07003201 av1_zero(filter_intra_mode_info);
3202 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003204#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003205 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003206#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003207
3208 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003209 int this_rate;
3210 int64_t this_rd, this_model_rd;
3211 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003212 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003213 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003214 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3215 if (*best_model_rd != INT64_MAX &&
3216 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3217 continue;
3218 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003219 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3220 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003221 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003222 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003223 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003224 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003225
3226 if (this_rd < *best_rd) {
3227 *best_rd = this_rd;
3228 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003229 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003230 best_tx_type = mic->mbmi.tx_type;
3231 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003232 *rate_tokenonly = tokenonly_rd_stats.rate;
3233 *distortion = tokenonly_rd_stats.dist;
3234 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003235 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003236 }
3237 }
3238
hui su5db97432016-10-14 16:10:14 -07003239 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003240 mbmi->mode = DC_PRED;
3241 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003242 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3243 filter_intra_mode_info.use_filter_intra_mode[0];
3244 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3245 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003246 mbmi->tx_type = best_tx_type;
3247 return 1;
3248 } else {
3249 return 0;
3250 }
3251}
hui su5db97432016-10-14 16:10:14 -07003252#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253
hui su5db97432016-10-14 16:10:14 -07003254#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003255// Run RD calculation with given luma intra prediction angle., and return
3256// the RD cost. Update the best mode info. if the RD cost is the best so far.
3257static int64_t calc_rd_given_intra_angle(
3258 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3259 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3260 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3261 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003262#if CONFIG_INTRA_INTERP
3263 INTRA_FILTER *best_filter,
3264#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003265 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003266 int this_rate;
3267 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003268 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003269 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003270 assert(!is_inter_block(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003271
hui su45dc5972016-12-08 17:42:50 -08003272 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003273 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3274 if (*best_model_rd != INT64_MAX &&
3275 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3276 return INT64_MAX;
3277 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003278 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3279 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3280
3281 this_rate = tokenonly_rd_stats.rate + mode_cost +
3282 write_uniform_cost(2 * max_angle_delta + 1,
3283 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003284 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003285
3286 if (this_rd < *best_rd) {
3287 *best_rd = this_rd;
3288 *best_angle_delta = mbmi->angle_delta[0];
3289 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003290#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003291 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003292#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003293 *best_tx_type = mbmi->tx_type;
3294 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003295 rd_stats->rate = tokenonly_rd_stats.rate;
3296 rd_stats->dist = tokenonly_rd_stats.dist;
3297 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003298 }
hui su45dc5972016-12-08 17:42:50 -08003299 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003300}
3301
hui su45dc5972016-12-08 17:42:50 -08003302// With given luma directional intra prediction mode, pick the best angle delta
3303// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003304static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003305 int *rate, RD_STATS *rd_stats,
3306 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003307 int64_t best_rd,
3308 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309 MACROBLOCKD *const xd = &x->e_mbd;
3310 MODE_INFO *const mic = xd->mi[0];
3311 MB_MODE_INFO *mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003312 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08003313 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003314 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003315#if CONFIG_INTRA_INTERP
3316 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003317 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003319#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003320 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003321 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3322 TX_TYPE best_tx_type = mbmi->tx_type;
3323
hui su0a6731f2017-04-26 15:23:47 -07003324 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003325
hui su0a6731f2017-04-26 15:23:47 -07003326 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003327#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003328 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3329 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3330 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003331#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003332 for (i = 0; i < 2; ++i) {
3333 best_rd_in = (best_rd == INT64_MAX)
3334 ? INT64_MAX
3335 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3336 this_rd = calc_rd_given_intra_angle(
3337 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003338#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003339 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003340#else
hui su45dc5972016-12-08 17:42:50 -08003341 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003342#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003343 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003344 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003345#if CONFIG_INTRA_INTERP
3346 &best_filter,
3347#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003348 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003349 rd_cost[2 * angle_delta + i] = this_rd;
3350 if (first_try && this_rd == INT64_MAX) return best_rd;
3351 first_try = 0;
3352 if (angle_delta == 0) {
3353 rd_cost[1] = this_rd;
3354 break;
3355 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003356 }
hui su45dc5972016-12-08 17:42:50 -08003357#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003358 }
hui su45dc5972016-12-08 17:42:50 -08003359#endif // CONFIG_INTRA_INTERP
3360 }
3361
3362 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003363 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003364 int64_t rd_thresh;
3365#if CONFIG_INTRA_INTERP
3366 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3367 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3368 mic->mbmi.intra_filter = filter;
3369#endif // CONFIG_INTRA_INTERP
3370 for (i = 0; i < 2; ++i) {
3371 int skip_search = 0;
3372 rd_thresh = best_rd + (best_rd >> 5);
3373 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3374 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3375 skip_search = 1;
3376 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003377 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003378 cpi, x, bsize,
3379#if CONFIG_INTRA_INTERP
3380 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3381#else
3382 mode_cost,
3383#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003384 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003385 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3386#if CONFIG_INTRA_INTERP
3387 &best_filter,
3388#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003389 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003390 }
3391 }
3392#if CONFIG_INTRA_INTERP
3393 }
3394#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003395 }
3396
hui sueda3d762016-12-06 16:58:23 -08003397#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003398 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003399 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003400 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003401 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3402 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003403 this_rd = calc_rd_given_intra_angle(
3404 cpi, x, bsize,
3405 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003406 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003407 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003408 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003409 }
3410 }
3411 }
hui sueda3d762016-12-06 16:58:23 -08003412#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003413
3414 mbmi->tx_size = best_tx_size;
3415 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003416#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003417 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003418#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003419 mbmi->tx_type = best_tx_type;
3420 return best_rd;
3421}
3422
3423// Indices are sign, integer, and fractional part of the gradient value
3424static const uint8_t gradient_to_angle_bin[2][7][16] = {
3425 {
3426 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3427 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3428 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3429 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3430 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3431 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3432 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3433 },
3434 {
3435 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3436 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3437 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3438 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3439 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3440 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3441 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3442 },
3443};
3444
3445static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3446 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003447#if CONFIG_ALT_INTRA
3448 0,
3449#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450};
3451
3452static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003453 int cols, BLOCK_SIZE bsize,
3454 uint8_t *directional_mode_skip_mask) {
3455 memset(directional_mode_skip_mask, 0,
3456 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3457 // Sub-8x8 blocks do not use extra directions.
3458 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003459 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003460 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3461 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003462 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003463 for (r = 1; r < rows; ++r) {
3464 for (c = 1; c < cols; ++c) {
3465 dx = src[c] - src[c - 1];
3466 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003467 int index;
3468 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003469 if (dy == 0) {
3470 index = 2;
3471 } else {
hui su9cc10652017-04-27 17:22:07 -07003472 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473 dx = abs(dx);
3474 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003475 const int remd = (dx % dy) * 16 / dy;
3476 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003477 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003478 }
3479 hist[index] += temp;
3480 }
3481 src += src_stride;
3482 }
3483
hui su9cc10652017-04-27 17:22:07 -07003484 int i;
3485 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003486 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3487 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003488 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003489 const uint8_t angle_bin = mode_to_angle_bin[i];
3490 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003491 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003492 if (angle_bin > 0) {
3493 score += hist[angle_bin - 1];
3494 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003495 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003496 if (angle_bin < DIRECTIONAL_MODES - 1) {
3497 score += hist[angle_bin + 1];
3498 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003499 }
3500 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3501 directional_mode_skip_mask[i] = 1;
3502 }
3503 }
3504}
3505
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003506#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003507static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003508 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003509 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003510 memset(directional_mode_skip_mask, 0,
3511 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3512 // Sub-8x8 blocks do not use extra directions.
3513 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003514 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003515 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003516 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3517 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003518 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003519 for (r = 1; r < rows; ++r) {
3520 for (c = 1; c < cols; ++c) {
3521 dx = src[c] - src[c - 1];
3522 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003523 int index;
3524 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003525 if (dy == 0) {
3526 index = 2;
3527 } else {
hui su9cc10652017-04-27 17:22:07 -07003528 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529 dx = abs(dx);
3530 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003531 const int remd = (dx % dy) * 16 / dy;
3532 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003533 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003534 }
3535 hist[index] += temp;
3536 }
3537 src += src_stride;
3538 }
3539
hui su9cc10652017-04-27 17:22:07 -07003540 int i;
3541 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003542 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3543 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003544 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003545 const uint8_t angle_bin = mode_to_angle_bin[i];
3546 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003547 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003548 if (angle_bin > 0) {
3549 score += hist[angle_bin - 1];
3550 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003551 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003552 if (angle_bin < DIRECTIONAL_MODES - 1) {
3553 score += hist[angle_bin + 1];
3554 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003555 }
3556 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3557 directional_mode_skip_mask[i] = 1;
3558 }
3559 }
3560}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003561#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003562#endif // CONFIG_EXT_INTRA
3563
3564// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003565static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3566 int *rate, int *rate_tokenonly,
3567 int64_t *distortion, int *skippable,
3568 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 MACROBLOCKD *const xd = &x->e_mbd;
3571 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003572 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003573 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08003574 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003575 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003576#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003577 const int rows = block_size_high[bsize];
3578 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003579#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003580 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003581#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003582 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003583 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003584 const int src_stride = x->plane[0].src.stride;
3585 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003586#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003587#if CONFIG_FILTER_INTRA
3588 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003589 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3590#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003591 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003592#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003593 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 uint8_t *best_palette_color_map =
3595 cpi->common.allow_screen_content_tools
3596 ? x->palette_buffer->best_palette_color_map
3597 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003598 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003599 const int try_palette =
3600 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003601#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003602 const MODE_INFO *above_mi = xd->above_mi;
3603 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003604 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3605 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003606 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003607#if CONFIG_PVQ
3608 od_rollback_buffer pre_buf, post_buf;
3609
3610 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3611 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003612#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003613 bmode_costs = cpi->y_mode_costs[A][L];
3614
3615#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003616 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003617#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003619 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 directional_mode_skip_mask);
3621 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003622#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003623 angle_estimation(src, src_stride, rows, cols, bsize,
3624 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003625#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003626#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003627 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003628#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003629#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003630 pmi->palette_size[0] = 0;
3631 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003632 palette_y_mode_ctx +=
3633 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003634 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003635 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003636#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003637
3638 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3639 x->use_default_intra_tx_type = 1;
3640 else
3641 x->use_default_intra_tx_type = 0;
3642
3643 /* Y Search for intra prediction mode */
3644 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003645 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003646 int this_rate, this_rate_tokenonly, s;
3647 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003648 if (mode_idx == FINAL_MODE_SEARCH) {
3649 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003650 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003651 x->use_default_intra_tx_type = 0;
3652 } else {
hui sude0c70a2017-01-09 17:12:17 -08003653 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003654 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003655#if CONFIG_PVQ
3656 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003657#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003659 mbmi->angle_delta[0] = 0;
3660#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003661 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003662 if (best_model_rd != INT64_MAX &&
3663 this_model_rd > best_model_rd + (best_model_rd >> 1))
3664 continue;
3665 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3666#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003667 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3668 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003669 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003670 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07003671 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
3672 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003673 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003674 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003675 }
3676#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003677 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003678#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003679 this_rate_tokenonly = this_rd_stats.rate;
3680 this_distortion = this_rd_stats.dist;
3681 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003682
3683 if (this_rate_tokenonly == INT_MAX) continue;
3684
hui sude0c70a2017-01-09 17:12:17 -08003685 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003686
hui sude0c70a2017-01-09 17:12:17 -08003687 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003688 // super_block_yrd above includes the cost of the tx_size in the
3689 // tokenonly rate, but for intra blocks, tx_size is always coded
3690 // (prediction granularity), so we account for it in the full rate,
3691 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003692 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003693 }
Urvang Joshib100db72016-10-12 16:28:56 -07003694#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003695 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003696 this_rate +=
3697 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3698 [palette_y_mode_ctx],
3699 0);
hui su9bc1d8d2017-03-24 12:36:03 -07003700 }
Urvang Joshib100db72016-10-12 16:28:56 -07003701#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003702#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003703 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003704 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3705#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003707 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08003708#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003709 const int p_angle =
3710 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003711 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003712 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003713 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003714#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003715 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
3716 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003717 }
3718#endif // CONFIG_EXT_INTRA
3719 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003720#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003721 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003722 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 }
hui su5db97432016-10-14 16:10:14 -07003724#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003725
3726 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003727 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003728 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003729#if CONFIG_FILTER_INTRA
3730 beat_best_rd = 1;
3731#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732 *rate = this_rate;
3733 *rate_tokenonly = this_rate_tokenonly;
3734 *distortion = this_distortion;
3735 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003736#if CONFIG_PVQ
3737 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003738#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003739 }
3740 }
3741
Yushin Cho77bba8d2016-11-04 16:36:56 -07003742#if CONFIG_PVQ
3743 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003744#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003745
Luc Trudeaue3980282017-04-25 23:17:21 -04003746#if CONFIG_CFL
3747 // Perform one extra txfm_rd_in_plane() call, this time with the best value so
3748 // we can store reconstructed luma values
3749 RD_STATS this_rd_stats;
3750 x->cfl_store_y = 1;
3751 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, 0, bsize,
3752 mic->mbmi.tx_size, cpi->sf.use_fast_coef_costing);
3753 x->cfl_store_y = 0;
3754#endif
3755
Urvang Joshib100db72016-10-12 16:28:56 -07003756#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003757 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003758 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3759 bmode_costs[DC_PRED], &best_mbmi,
3760 best_palette_color_map, &best_rd, &best_model_rd,
3761 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003762 }
Urvang Joshib100db72016-10-12 16:28:56 -07003763#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003764
hui su5db97432016-10-14 16:10:14 -07003765#if CONFIG_FILTER_INTRA
3766 if (beat_best_rd) {
3767 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3768 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003769 &best_rd, &best_model_rd,
3770 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003771 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003772 }
3773 }
hui su5db97432016-10-14 16:10:14 -07003774#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003775
hui sude0c70a2017-01-09 17:12:17 -08003776 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003777 return best_rd;
3778}
3779
Yue Chena1e48dc2016-08-29 17:29:33 -07003780// Return value 0: early termination triggered, no valid rd cost available;
3781// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003782static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3783 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3784 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003785 MACROBLOCKD *const xd = &x->e_mbd;
3786 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3787 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3788 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003789 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003790 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003791
3792 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003793
Jingning Han31b6a4f2017-02-23 11:05:53 -08003794#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003795 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07003796
3797 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
3798 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08003799#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003800
Yushin Cho77bba8d2016-11-04 16:36:56 -07003801#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003802 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003803 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3804 av1_subtract_plane(x, bsize, plane);
3805 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003806#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003807
Yushin Cho09de28b2016-06-21 14:51:23 -07003808 if (is_cost_valid) {
3809 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003810 RD_STATS pn_rd_stats;
3811 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3812 uv_tx_size, cpi->sf.use_fast_coef_costing);
3813 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003814 is_cost_valid = 0;
3815 break;
3816 }
Angie Chiang284d7772016-11-08 11:06:45 -08003817 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3818 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003819 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003820 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003821 is_cost_valid = 0;
3822 break;
3823 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003824 }
3825 }
3826
3827 if (!is_cost_valid) {
3828 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003829 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003830 }
3831
3832 return is_cost_valid;
3833}
3834
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835#if CONFIG_VAR_TX
Alex Converse61f37b82017-03-29 15:26:03 -07003836// FIXME crop these calls
3837static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
3838 TX_SIZE tx_size) {
3839 return aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size],
3840 tx_size_high[tx_size]);
3841}
3842
Yaowu Xuf883b422016-08-30 14:01:10 -07003843void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3844 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07003845 int plane_bsize, const ENTROPY_CONTEXT *a,
3846 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003847 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003848 MACROBLOCKD *xd = &x->e_mbd;
3849 const struct macroblock_plane *const p = &x->plane[plane];
3850 struct macroblockd_plane *const pd = &xd->plane[plane];
3851 int64_t tmp;
3852 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003853 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003854 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003855 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003856 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003858 int bh = block_size_high[txm_bsize];
3859 int bw = block_size_wide[txm_bsize];
3860 int txb_h = tx_size_high_unit[tx_size];
3861 int txb_w = tx_size_wide_unit[tx_size];
3862
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003864 uint8_t *src =
3865 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3866 uint8_t *dst =
3867 &pd->dst
3868 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003869#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003870 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3871 uint8_t *rec_buffer;
3872#else
3873 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003874#endif // CONFIG_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003875 int max_blocks_high = block_size_high[plane_bsize];
3876 int max_blocks_wide = block_size_wide[plane_bsize];
3877 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003878 const int16_t *diff =
3879 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003880 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003881
3882 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003883
3884 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003885 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003887 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3888
3889 max_blocks_high >>= tx_size_wide_log2[0];
3890 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891
Angie Chiang77368af2017-03-23 16:22:07 -07003892 int coeff_ctx = get_entropy_context(tx_size, a, l);
3893
Angie Chiangff6d8902016-10-21 11:02:09 -07003894 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003895 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003896
Angie Chiangff6d8902016-10-21 11:02:09 -07003897 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898
Angie Chiang808d8592017-04-06 18:36:55 -07003899// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003900#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003901 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3902 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003903 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003904 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905 } else {
3906 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003907 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003908 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003909 }
3910#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003911 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003912 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003913#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003914
Jingning Han9fdc4222016-10-27 21:32:19 -07003915 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003916 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003917 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3918 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003920 for (idy = 0; idy < blocks_height; ++idy) {
3921 for (idx = 0; idx < blocks_width; ++idx) {
3922 const int16_t *d =
3923 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003924 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003925 }
3926 }
3927 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003928 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929 }
3930
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003931#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003932 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3933 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003934#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003935 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07003936 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937
Angie Chiang41fffae2017-04-03 10:33:18 -07003938 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
3939 MAX_TX_SIZE, eob);
3940 if (eob > 0) {
Jingning Han4b47c932016-11-03 09:20:08 -07003941 if (txb_w + blk_col > max_blocks_wide ||
3942 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003943 int idx, idy;
3944 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003945 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3946 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003948 for (idy = 0; idy < blocks_height; ++idy) {
3949 for (idx = 0; idx < blocks_width; ++idx) {
3950 uint8_t *const s =
3951 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3952 uint8_t *const r =
3953 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003954 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 tmp += this_dist;
3956 }
3957 }
3958 } else {
3959 uint32_t this_dist;
3960 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3961 &this_dist);
3962 tmp = this_dist;
3963 }
3964 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003965 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07003966 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07003967 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003968 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07003969 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003970
Angie Chiangd81fdb42016-11-03 12:20:58 -07003971#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003972 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3973 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08003974#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975}
3976
Yaowu Xuf883b422016-08-30 14:01:10 -07003977static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003978 int blk_col, int plane, int block, int block32,
3979 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003980 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3981 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003982 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003983 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003984 MACROBLOCKD *const xd = &x->e_mbd;
3985 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3986 struct macroblock_plane *const p = &x->plane[plane];
3987 struct macroblockd_plane *const pd = &xd->plane[plane];
3988 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3989 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003990 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003991 [MAX_MIB_SIZE] =
3992 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003993 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3994 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003995 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003996 int64_t this_rd = INT64_MAX;
3997 ENTROPY_CONTEXT *pta = ta + blk_col;
3998 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07004000 int ctx =
4001 txfm_partition_context(tx_above + (blk_col >> 1),
4002 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004003 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004004 int tmp_eob = 0;
4005 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07004006 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08004007 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004008
Jingning Han63cbf342016-11-09 15:37:48 -08004009 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08004010
Jingning Hand3fada82016-11-22 10:46:55 -08004011 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004012
4013 if (ref_best_rd < 0) {
4014 *is_cost_valid = 0;
4015 return;
4016 }
4017
Jingning Hance059e82016-10-31 16:27:28 -07004018 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004019
Angie Chiangc0feea82016-11-03 15:36:18 -07004020 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004021
4022 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4023
Jingning Han1c019f92016-11-21 12:53:32 -08004024 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4025 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004026
4027 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4028 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004029
4030 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4031 rd_stats_stack[block32].rate != INT_MAX) {
4032 *rd_stats = rd_stats_stack[block32];
4033 p->eobs[block] = !rd_stats->skip;
4034 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4035 } else {
4036 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004037 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004038 if (tx_size == TX_32X32) {
4039 rd_stats_stack[block32] = *rd_stats;
4040 }
4041 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004042
Angie Chiangb5dda482016-11-02 16:19:58 -07004043 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4044 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4045 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004047#if CONFIG_RD_DEBUG
4048 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4049 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004050#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004051 rd_stats->rate = zero_blk_rate;
4052 rd_stats->dist = rd_stats->sse;
4053 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4055 p->eobs[block] = 0;
4056 } else {
4057 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004058 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059 }
4060
Jingning Han571189c2016-10-24 10:38:43 -07004061 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004062 rd_stats->rate +=
4063 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4064 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004065 tmp_eob = p->eobs[block];
4066 }
4067
Jingning Han571189c2016-10-24 10:38:43 -07004068 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004069 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4070 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004071 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004072 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004073 int this_cost_valid = 1;
4074 int64_t tmp_rd = 0;
4075
Angie Chiangd7246172016-11-03 11:49:15 -07004076 sum_rd_stats.rate =
4077 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004078
4079 assert(tx_size < TX_SIZES_ALL);
4080
Yaowu Xuc27fc142016-08-22 16:08:15 -07004081 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004082 int offsetr = blk_row + (i >> 1) * bsl;
4083 int offsetc = blk_col + (i & 0x01) * bsl;
4084
4085 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4086
Jingning Han63cbf342016-11-09 15:37:48 -08004087 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004088 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004089 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4090 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004091
Angie Chiangc0feea82016-11-03 15:36:18 -07004092 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004093
Angie Chiangd7246172016-11-03 11:49:15 -07004094 tmp_rd =
4095 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004096 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004097 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004098 }
4099 if (this_cost_valid) sum_rd = tmp_rd;
4100 }
4101
4102 if (this_rd < sum_rd) {
4103 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004104 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4105 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004106 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004107 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004108 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004109 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4110 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004111 inter_tx_size[idy][idx] = tx_size;
4112 mbmi->tx_size = tx_size;
4113 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004114 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004115 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004116 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004117 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4118 }
4119}
4120
Angie Chiangb5dda482016-11-02 16:19:58 -07004121static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4122 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004123 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004124 MACROBLOCKD *const xd = &x->e_mbd;
4125 int is_cost_valid = 1;
4126 int64_t this_rd = 0;
4127
4128 if (ref_best_rd < 0) is_cost_valid = 0;
4129
Angie Chiangc0feea82016-11-03 15:36:18 -07004130 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004131
4132 if (is_cost_valid) {
4133 const struct macroblockd_plane *const pd = &xd->plane[0];
4134 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004135 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4136 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004137 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004138 const int bh = tx_size_high_unit[max_tx_size];
4139 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004140 int idx, idy;
4141 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004142 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004143 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4145 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4146 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4147 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4148
Angie Chiangb5dda482016-11-02 16:19:58 -07004149 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004150 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151
Jingning Han9ca05b72017-01-03 14:41:36 -08004152 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004153 memcpy(tx_above, xd->above_txfm_context,
4154 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4155 memcpy(tx_left, xd->left_txfm_context,
4156 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4157
4158 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004159 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004160 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004161 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004162 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004163 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004164 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004165 this_rd += AOMMIN(
4166 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4167 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004169 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004170 }
4171 }
4172 }
4173
Angie Chiangb5dda482016-11-02 16:19:58 -07004174 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4175 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004176 if (this_rd > ref_best_rd) is_cost_valid = 0;
4177
4178 if (!is_cost_valid) {
4179 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004180 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004181 }
4182}
4183
Yaowu Xuf883b422016-08-30 14:01:10 -07004184static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004185 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004186 int64_t ref_best_rd, TX_TYPE tx_type,
4187 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004188 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 MACROBLOCKD *const xd = &x->e_mbd;
4190 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004192 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4193 int s0 = av1_cost_bit(skip_prob, 0);
4194 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004195 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004196 int row, col;
4197 const int max_blocks_high = max_block_high(xd, bsize, 0);
4198 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004199
4200 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004201 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004202 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004203
Angie Chiangb5dda482016-11-02 16:19:58 -07004204 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004205
Jingning Hane67b38a2016-11-04 10:30:00 -07004206 for (row = 0; row < max_blocks_high / 2; ++row)
4207 for (col = 0; col < max_blocks_wide / 2; ++col)
4208 mbmi->min_tx_size = AOMMIN(
4209 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4210
Yaowu Xuc27fc142016-08-22 16:08:15 -07004211#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004212 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4213 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004214 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004215 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4216 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004217 if (is_inter) {
4218 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004219 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004220 cpi->inter_tx_type_costs[ext_tx_set]
4221 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004222 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004223 } else {
4224 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004225 rd_stats->rate +=
4226 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4227 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 }
4229 }
4230#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004231 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4232 rd_stats->rate +=
4233 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004234#endif // CONFIG_EXT_TX
4235
Angie Chiangb5dda482016-11-02 16:19:58 -07004236 if (rd_stats->skip)
4237 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004239 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004240
Angie Chiangb5dda482016-11-02 16:19:58 -07004241 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4242 !(rd_stats->skip))
4243 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004244
4245 return rd;
4246}
4247
Angie Chiangb5dda482016-11-02 16:19:58 -07004248static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4249 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004250 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004251 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004252 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4253 MACROBLOCKD *const xd = &x->e_mbd;
4254 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4255 int64_t rd = INT64_MAX;
4256 int64_t best_rd = INT64_MAX;
4257 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4258 const int is_inter = is_inter_block(mbmi);
4259 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004260 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004261 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004262 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Angie Chiangf1cb0752017-04-10 16:01:20 -07004263 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004264 int idx, idy;
4265 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004266 const int count32 =
4267 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004268#if CONFIG_EXT_PARTITION
4269 RD_STATS rd_stats_stack[16];
4270#else
Jingning Han63cbf342016-11-09 15:37:48 -08004271 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004272#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004273#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004274 const int ext_tx_set =
4275 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004276#endif // CONFIG_EXT_TX
4277
4278 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4279#if CONFIG_EXT_TX
4280 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4281#else
4282 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004283#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004284
Angie Chiangc0feea82016-11-03 15:36:18 -07004285 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286
Jingning Han89d648b2016-11-22 11:22:08 -08004287 for (idx = 0; idx < count32; ++idx)
4288 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004289
Yaowu Xuc27fc142016-08-22 16:08:15 -07004290 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004291 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004292 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004293#if CONFIG_EXT_TX
4294 if (is_inter) {
4295 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4296 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4297 if (!do_tx_type_search(tx_type, prune)) continue;
4298 }
4299 } else {
4300 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4301 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4302 }
4303 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4304 }
4305#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4307 !do_tx_type_search(tx_type, prune))
4308 continue;
4309#endif // CONFIG_EXT_TX
4310 if (is_inter && x->use_default_inter_tx_type &&
4311 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4312 continue;
4313
Jingning Hane67b38a2016-11-04 10:30:00 -07004314 if (xd->lossless[mbmi->segment_id])
4315 if (tx_type != DCT_DCT) continue;
4316
Angie Chiangb5dda482016-11-02 16:19:58 -07004317 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004318 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004319
4320 if (rd < best_rd) {
4321 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004322 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323 best_tx_type = mbmi->tx_type;
4324 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004325 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004326 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4327 for (idy = 0; idy < xd->n8_h; ++idy)
4328 for (idx = 0; idx < xd->n8_w; ++idx)
4329 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4330 }
4331 }
4332
4333 mbmi->tx_type = best_tx_type;
4334 for (idy = 0; idy < xd->n8_h; ++idy)
4335 for (idx = 0; idx < xd->n8_w; ++idx)
4336 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4337 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004338 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004339 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4340}
4341
Yaowu Xuf883b422016-08-30 14:01:10 -07004342static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004343 int blk_col, int plane, int block, TX_SIZE tx_size,
4344 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004345 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004346 MACROBLOCKD *const xd = &x->e_mbd;
4347 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4348 struct macroblock_plane *const p = &x->plane[plane];
4349 struct macroblockd_plane *const pd = &xd->plane[plane];
4350 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4351 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4352 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4353 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004354 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4355 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004356
Jingning Hand3fada82016-11-22 10:46:55 -08004357 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004358
Yaowu Xuc27fc142016-08-22 16:08:15 -07004359 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4360
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004361 plane_tx_size =
4362 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4363 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364
4365 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004366 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004367 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4368 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004369 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004370 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004371
Jingning Han58224042016-10-27 16:35:32 -07004372 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004373 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004374 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004375 tl[i] = !(p->eobs[block] == 0);
4376 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004377 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4378 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004379 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380 int i;
4381
4382 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004383
4384 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004385 int offsetr = blk_row + (i >> 1) * bsl;
4386 int offsetc = blk_col + (i & 0x01) * bsl;
4387
4388 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4389
4390 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4391 above_ctx, left_ctx, rd_stats);
4392 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004393 }
4394 }
4395}
4396
4397// Return value 0: early termination triggered, no valid rd cost available;
4398// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004399static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4400 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4401 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004402 MACROBLOCKD *const xd = &x->e_mbd;
4403 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4404 int plane;
4405 int is_cost_valid = 1;
4406 int64_t this_rd;
4407
4408 if (ref_best_rd < 0) is_cost_valid = 0;
4409
Angie Chiangc0feea82016-11-03 15:36:18 -07004410 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004411
Jingning Han31b6a4f2017-02-23 11:05:53 -08004412#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004413 if (x->skip_chroma_rd) return is_cost_valid;
4414 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08004415#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004416
Yue Chena1e48dc2016-08-29 17:29:33 -07004417#if CONFIG_EXT_TX && CONFIG_RECT_TX
4418 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004419 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004420 }
4421#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4422
Yaowu Xuc27fc142016-08-22 16:08:15 -07004423 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004425 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004426 }
4427
Yaowu Xuc27fc142016-08-22 16:08:15 -07004428 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4429 const struct macroblockd_plane *const pd = &xd->plane[plane];
4430 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004431 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4432 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004433 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004434 const int bh = tx_size_high_unit[max_tx_size];
4435 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004436 int idx, idy;
4437 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004438 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004439 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4440 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004441 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004442 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004443
Jingning Han9ca05b72017-01-03 14:41:36 -08004444 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004445
4446 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004447 for (idx = 0; idx < mi_width; idx += bw) {
4448 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004449 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004450 block += step;
4451 }
4452 }
4453
Angie Chiangb5dda482016-11-02 16:19:58 -07004454 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 is_cost_valid = 0;
4456 break;
4457 }
4458
Angie Chiang628d7c92016-11-03 16:24:56 -07004459 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004460
Angie Chiangb5dda482016-11-02 16:19:58 -07004461 this_rd =
4462 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4463 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004464
4465 if (this_rd > ref_best_rd) {
4466 is_cost_valid = 0;
4467 break;
4468 }
4469 }
4470
4471 if (!is_cost_valid) {
4472 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004473 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004474 }
4475
4476 return is_cost_valid;
4477}
4478#endif // CONFIG_VAR_TX
4479
Urvang Joshib100db72016-10-12 16:28:56 -07004480#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004481static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4482 int dc_mode_cost,
4483 uint8_t *best_palette_color_map,
4484 MB_MODE_INFO *const best_mbmi,
4485 int64_t *best_rd, int *rate,
4486 int *rate_tokenonly, int64_t *distortion,
4487 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004488 MACROBLOCKD *const xd = &x->e_mbd;
4489 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004490 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08004491 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004492 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004493 int this_rate;
4494 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004495 int colors_u, colors_v, colors;
4496 const int src_stride = x->plane[1].src.stride;
4497 const uint8_t *const src_u = x->plane[1].src.buf;
4498 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004499 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004500 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004501 int plane_block_width, plane_block_height, rows, cols;
4502 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4503 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004504 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4505
hui su83c26632017-01-24 17:19:06 -08004506 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004507#if CONFIG_FILTER_INTRA
4508 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4509#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004510
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004511#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004512 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004513 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4514 cpi->common.bit_depth);
4515 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4516 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004517 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004518#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004519 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4520 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004521#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004522 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004523#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004524
hui su33567b22017-04-30 16:40:19 -07004525#if CONFIG_PALETTE_DELTA_ENCODING
4526 const MODE_INFO *above_mi = xd->above_mi;
4527 const MODE_INFO *left_mi = xd->left_mi;
4528 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
4529 const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
4530#endif // CONFIG_PALETTE_DELTA_ENCODING
4531
Yaowu Xuc27fc142016-08-22 16:08:15 -07004532 colors = colors_u > colors_v ? colors_u : colors_v;
4533 if (colors > 1 && colors <= 64) {
4534 int r, c, n, i, j;
4535 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004536 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004537 float lb_u, ub_u, val_u;
4538 float lb_v, ub_v, val_v;
4539 float *const data = x->palette_buffer->kmeans_data_buf;
4540 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004541
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004542#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004543 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4544 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4545 if (cpi->common.use_highbitdepth) {
4546 lb_u = src_u16[0];
4547 ub_u = src_u16[0];
4548 lb_v = src_v16[0];
4549 ub_v = src_v16[0];
4550 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004551#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004552 lb_u = src_u[0];
4553 ub_u = src_u[0];
4554 lb_v = src_v[0];
4555 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004556#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004558#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004559
Yaowu Xuc27fc142016-08-22 16:08:15 -07004560 for (r = 0; r < rows; ++r) {
4561 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004562#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004563 if (cpi->common.use_highbitdepth) {
4564 val_u = src_u16[r * src_stride + c];
4565 val_v = src_v16[r * src_stride + c];
4566 data[(r * cols + c) * 2] = val_u;
4567 data[(r * cols + c) * 2 + 1] = val_v;
4568 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004569#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004570 val_u = src_u[r * src_stride + c];
4571 val_v = src_v[r * src_stride + c];
4572 data[(r * cols + c) * 2] = val_u;
4573 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004574#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004576#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577 if (val_u < lb_u)
4578 lb_u = val_u;
4579 else if (val_u > ub_u)
4580 ub_u = val_u;
4581 if (val_v < lb_v)
4582 lb_v = val_v;
4583 else if (val_v > ub_v)
4584 ub_v = val_v;
4585 }
4586 }
4587
4588 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4589 --n) {
4590 for (i = 0; i < n; ++i) {
4591 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4592 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4593 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004594 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07004595#if CONFIG_PALETTE_DELTA_ENCODING
hui su33567b22017-04-30 16:40:19 -07004596 optimize_palette_colors(color_cache, n_cache, n, 2, centroids);
hui sud13c24a2017-04-07 16:13:07 -07004597 // Sort the U channel colors in ascending order.
4598 for (i = 0; i < 2 * (n - 1); i += 2) {
4599 int min_idx = i;
4600 float min_val = centroids[i];
4601 for (j = i + 2; j < 2 * n; j += 2)
4602 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
4603 if (min_idx != i) {
4604 float temp_u = centroids[i], temp_v = centroids[i + 1];
4605 centroids[i] = centroids[min_idx];
4606 centroids[i + 1] = centroids[min_idx + 1];
4607 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
4608 }
4609 }
4610 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
4611#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004612 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4613 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004614 pmi->palette_size[1] = n;
4615 for (i = 1; i < 3; ++i) {
4616 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004617#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004618 if (cpi->common.use_highbitdepth)
4619 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4620 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4621 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004622#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004623 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4624 clip_pixel((int)centroids[j * 2 + i - 1]);
4625 }
4626 }
4627
Angie Chiang284d7772016-11-08 11:06:45 -08004628 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4629 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004631 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08004632 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004633 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004634 av1_cost_bit(
4635 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui su33567b22017-04-30 16:40:19 -07004636 this_rate += av1_palette_color_cost_uv(pmi,
4637#if CONFIG_PALETTE_DELTA_ENCODING
4638 color_cache, n_cache,
4639#endif // CONFIG_PALETTE_DELTA_ENCODING
4640 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004641 for (i = 0; i < rows; ++i) {
4642 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004643 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004644 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004645 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004646 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004647 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4648 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649 }
4650 }
4651
Angie Chiang284d7772016-11-08 11:06:45 -08004652 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653 if (this_rd < *best_rd) {
4654 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004655 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004656 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004657 plane_block_width * plane_block_height *
4658 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004659 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004660 *distortion = tokenonly_rd_stats.dist;
4661 *rate_tokenonly = tokenonly_rd_stats.rate;
4662 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663 }
4664 }
4665 }
hui su83c26632017-01-24 17:19:06 -08004666 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004667 memcpy(color_map, best_palette_color_map,
4668 rows * cols * sizeof(best_palette_color_map[0]));
4669 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004670}
Urvang Joshib100db72016-10-12 16:28:56 -07004671#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672
hui su5db97432016-10-14 16:10:14 -07004673#if CONFIG_FILTER_INTRA
4674// Return 1 if an filter intra mode is selected; return 0 otherwise.
4675static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4676 int *rate, int *rate_tokenonly,
4677 int64_t *distortion, int *skippable,
4678 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004679 MACROBLOCKD *const xd = &x->e_mbd;
4680 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004681 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004682 int this_rate;
4683 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004684 FILTER_INTRA_MODE mode;
4685 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004686 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687
hui su5db97432016-10-14 16:10:14 -07004688 av1_zero(filter_intra_mode_info);
4689 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004690 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004691#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004692 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004693#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004694
4695 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004696 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004697 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 continue;
4699
Angie Chiang284d7772016-11-08 11:06:45 -08004700 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004701 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004702 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4703 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004704 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004705 if (this_rd < *best_rd) {
4706 *best_rd = this_rd;
4707 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004708 *rate_tokenonly = tokenonly_rd_stats.rate;
4709 *distortion = tokenonly_rd_stats.dist;
4710 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004711 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4712 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004713 }
4714 }
4715
hui su5db97432016-10-14 16:10:14 -07004716 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004717 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004718 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4719 filter_intra_mode_info.use_filter_intra_mode[1];
4720 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4721 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004722 return 1;
4723 } else {
4724 return 0;
4725 }
4726}
hui su5db97432016-10-14 16:10:14 -07004727#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728
hui su5db97432016-10-14 16:10:14 -07004729#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004730// Run RD calculation with given chroma intra prediction angle., and return
4731// the RD cost. Update the best mode info. if the RD cost is the best so far.
4732static int64_t pick_intra_angle_routine_sbuv(
4733 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4734 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4735 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004736 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004737 assert(!is_inter_block(mbmi));
Angie Chiang284d7772016-11-08 11:06:45 -08004738 int this_rate;
4739 int64_t this_rd;
4740 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004741
hui su45dc5972016-12-08 17:42:50 -08004742 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4743 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004744 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4745 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004746 if (this_rd < *best_rd) {
4747 *best_rd = this_rd;
4748 *best_angle_delta = mbmi->angle_delta[1];
4749 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004750 rd_stats->rate = tokenonly_rd_stats.rate;
4751 rd_stats->dist = tokenonly_rd_stats.dist;
4752 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004753 }
hui su45dc5972016-12-08 17:42:50 -08004754 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755}
4756
hui su45dc5972016-12-08 17:42:50 -08004757// With given chroma directional intra prediction mode, pick the best angle
4758// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004759static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004760 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004761 int64_t best_rd, int *rate,
4762 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004763 MACROBLOCKD *const xd = &x->e_mbd;
4764 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004765 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08004766 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07004767 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768
hui su45dc5972016-12-08 17:42:50 -08004769 rd_stats->rate = INT_MAX;
4770 rd_stats->skip = 0;
4771 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07004772 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004773
hui su0a6731f2017-04-26 15:23:47 -07004774 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004775 for (i = 0; i < 2; ++i) {
4776 best_rd_in = (best_rd == INT64_MAX)
4777 ? INT64_MAX
4778 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4779 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4780 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4781 best_rd_in, rate, rd_stats,
4782 &best_angle_delta, &best_rd);
4783 rd_cost[2 * angle_delta + i] = this_rd;
4784 if (angle_delta == 0) {
4785 if (this_rd == INT64_MAX) return 0;
4786 rd_cost[1] = this_rd;
4787 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788 }
4789 }
hui su45dc5972016-12-08 17:42:50 -08004790 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004791
hui su45dc5972016-12-08 17:42:50 -08004792 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07004793 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004794 int64_t rd_thresh;
4795 for (i = 0; i < 2; ++i) {
4796 int skip_search = 0;
4797 rd_thresh = best_rd + (best_rd >> 5);
4798 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4799 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4800 skip_search = 1;
4801 if (!skip_search) {
4802 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07004803 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4804 rate, rd_stats, &best_angle_delta,
4805 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004806 }
4807 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004808 }
4809
4810 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004811 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004812}
4813#endif // CONFIG_EXT_INTRA
4814
Urvang Joshi52648442016-10-13 17:27:51 -07004815static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4816 int *rate, int *rate_tokenonly,
4817 int64_t *distortion, int *skippable,
4818 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004819 MACROBLOCKD *xd = &x->e_mbd;
4820 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004821 assert(!is_inter_block(mbmi));
hui su83c26632017-01-24 17:19:06 -08004822 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004823 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004825 int this_rate;
4826 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004827#if CONFIG_PVQ
4828 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004829 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004830#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004831#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004832 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004833 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004834#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004835
hui su83c26632017-01-24 17:19:06 -08004836#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004837 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4838#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004839#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004840 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004841#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004843#if CONFIG_EXT_INTRA
4844 const int is_directional_mode =
4845 av1_is_directional_mode(mode, mbmi->sb_type);
4846#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004847 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4848 (1 << mode)))
4849 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004850
4851 mbmi->uv_mode = mode;
4852#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004854 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004855 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4856 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004857 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4858 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004859 continue;
4860 } else {
hui su83c26632017-01-24 17:19:06 -08004861#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004862 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004863#if CONFIG_PVQ
4864 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004865#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004867 }
hui su83c26632017-01-24 17:19:06 -08004868#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869 }
hui su83c26632017-01-24 17:19:06 -08004870#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004871 this_rate =
4872 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004873
4874#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004875 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004876 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4877 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08004878 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004879#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004880#if CONFIG_FILTER_INTRA
4881 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4882 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4883#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004884#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4886 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004887 this_rate += av1_cost_bit(
4888 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004889#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004890
Yushin Cho77bba8d2016-11-04 16:36:56 -07004891#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004892 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004893#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004894 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004895
4896 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004897 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004898 best_rd = this_rd;
4899 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004900 *rate_tokenonly = tokenonly_rd_stats.rate;
4901 *distortion = tokenonly_rd_stats.dist;
4902 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004903 }
4904 }
4905
Urvang Joshib100db72016-10-12 16:28:56 -07004906#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004907 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4908 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004909 rd_pick_palette_intra_sbuv(cpi, x,
4910 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4911 best_palette_color_map, &best_mbmi, &best_rd,
4912 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004913 }
Urvang Joshib100db72016-10-12 16:28:56 -07004914#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004915
hui su5db97432016-10-14 16:10:14 -07004916#if CONFIG_FILTER_INTRA
4917 if (mbmi->sb_type >= BLOCK_8X8) {
4918 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004919 skippable, bsize, &best_rd))
4920 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004921 }
hui su5db97432016-10-14 16:10:14 -07004922#endif // CONFIG_FILTER_INTRA
4923
hui su83c26632017-01-24 17:19:06 -08004924 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004925 // Make sure we actually chose a mode
4926 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004927 return best_rd;
4928}
4929
Urvang Joshi52648442016-10-13 17:27:51 -07004930static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004931 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4932 TX_SIZE max_tx_size, int *rate_uv,
4933 int *rate_uv_tokenonly, int64_t *dist_uv,
4934 int *skip_uv, PREDICTION_MODE *mode_uv) {
4935 // Use an estimated rd for uv_intra based on DC_PRED if the
4936 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004937 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004938#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004939#if CONFIG_CHROMA_2X2
4940 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4941 bsize, max_tx_size);
4942#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004943 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4944 if (x->skip_chroma_rd) {
4945 *rate_uv = 0;
4946 *rate_uv_tokenonly = 0;
4947 *dist_uv = 0;
4948 *skip_uv = 1;
4949 *mode_uv = DC_PRED;
4950 return;
4951 }
Jingning Han65113f32017-04-12 10:06:58 -07004952 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
4953 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07004954 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07004955 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004956#endif // CONFIG_CHROMA_2X2
4957#else
4958 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4959 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4960#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4962}
4963
Urvang Joshi52648442016-10-13 17:27:51 -07004964static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004965 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004966#if CONFIG_EXT_INTER
4967 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004968 return cpi
4969 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004970 }
David Barkercb03dc32017-04-07 13:05:09 +01004971#endif
4972
David Barkercb03dc32017-04-07 13:05:09 +01004973 int mode_cost = 0;
4974 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4975 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4976
4977 assert(is_inter_mode(mode));
4978
4979 if (mode == NEWMV) {
4980 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4981 return mode_cost;
4982 } else {
4983 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4984 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4985
4986 if (is_all_zero_mv) return mode_cost;
4987
4988 if (mode == ZEROMV) {
4989 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4990 return mode_cost;
4991 } else {
4992 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4993 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4994
4995 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4996 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4997 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4998
4999 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
5000 return mode_cost;
5001 }
5002 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005003}
5004
Sarah Parker6fdc8532016-11-16 17:47:13 -08005005#if CONFIG_EXT_INTER
5006static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
5007 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005008 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08005009 switch (comp_type) {
5010 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005011#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08005012 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005013#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08005014#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08005015 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08005016#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08005017 default: assert(0); return 0;
5018 }
5019}
5020#endif // CONFIG_EXT_INTER
5021
clang-format55ce9e02017-02-15 22:27:12 -08005022static int set_and_cost_bmi_mvs(
5023 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
5024 PREDICTION_MODE mode, int_mv this_mv[2],
5025 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
5026 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005027#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08005028 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005029#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00005030 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
5031 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005032 MODE_INFO *const mic = xd->mi[0];
5033 const MB_MODE_INFO *const mbmi = &mic->mbmi;
5034 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5035 int thismvcost = 0;
5036 int idx, idy;
5037 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
5038 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
5039 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005040 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00005041 (void)mi_row;
5042 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005043
5044 switch (mode) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005045 case NEWMV: this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005046#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005047 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005048 lower_mv_precision(&this_mv[0].as_mv, 0);
5049#endif // CONFIG_EXT_INTER
5050
Yaowu Xuc27fc142016-08-22 16:08:15 -07005051 for (idx = 0; idx < 1 + is_compound; ++idx) {
5052 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005053 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005054 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005055 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5056 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005057 }
5058 (void)mvjcost;
5059 (void)mvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005060 break;
5061 case NEARMV:
5062 case NEARESTMV:
5063 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5064 if (is_compound)
5065 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5066 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005067 case ZEROMV: {
5068 int ref;
5069 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005070#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005071 this_mv[ref].as_int =
5072 gm_get_motion_vector(
5073 &cpi->common.global_motion[mbmi->ref_frame[ref]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005074 cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005075 mi_row, i)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005076 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005077#else
5078 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005079#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005080 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005082 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005083#if CONFIG_EXT_INTER
5084 case NEW_NEWMV:
5085 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5086 compound_seg_newmvs[1].as_int == INVALID_MV) {
5087 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5088 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5089 } else {
5090 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5091 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5092 }
Alex Converse6317c882016-09-29 14:21:37 -07005093 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005094 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005095 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005096 lower_mv_precision(&this_mv[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005097 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005098 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5099 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
David Barker404b2e82017-03-27 13:07:47 +01005100 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005101 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5102 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005103 break;
5104 case NEW_NEARMV:
5105 case NEW_NEARESTMV:
5106 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005107 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108 lower_mv_precision(&this_mv[0].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005109 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005110 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5111 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005112 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5113 break;
5114 case NEAR_NEWMV:
5115 case NEAREST_NEWMV:
5116 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5117 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005118 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005119 lower_mv_precision(&this_mv[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005120 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005121 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5122 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005123 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124 case NEAREST_NEARESTMV:
5125 case NEAR_NEARMV:
5126 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5127 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5128 break;
5129 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005130#if CONFIG_GLOBAL_MOTION
5131 this_mv[0].as_int =
5132 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005133 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005134 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005135 .as_int;
5136 this_mv[1].as_int =
5137 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005138 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005139 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005140 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005141#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005142 this_mv[0].as_int = 0;
5143 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005144#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005145 break;
5146#endif // CONFIG_EXT_INTER
5147 default: break;
5148 }
5149
5150 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5151 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5152
5153 mic->bmi[i].as_mode = mode;
5154
Yaowu Xuc27fc142016-08-22 16:08:15 -07005155 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005156 mic->bmi[i].pred_mv[0].as_int =
5157 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5158 if (is_compound)
5159 mic->bmi[i].pred_mv[1].as_int =
5160 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005161 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005162 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5163 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005164 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005165
5166 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5167 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5168 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5169
Yaowu Xuc27fc142016-08-22 16:08:15 -07005170#if CONFIG_EXT_INTER
5171 if (is_compound)
5172 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5173 else
5174#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005175 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5176 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005177 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005178}
5179
Yushin Choab44fd12017-01-09 16:06:53 -08005180static int64_t encode_inter_mb_segment_sub8x8(
5181 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5182 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5183 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005184 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005185 MACROBLOCKD *xd = &x->e_mbd;
5186 struct macroblockd_plane *const pd = &xd->plane[0];
5187 struct macroblock_plane *const p = &x->plane[0];
5188 MODE_INFO *const mi = xd->mi[0];
5189 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005190 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5191 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005192 const int width = block_size_wide[plane_bsize];
5193 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005194 int idx, idy;
5195 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005196 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005198 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005199 int64_t thisdistortion = 0, thissse = 0;
5200 int thisrate = 0;
5201 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005202 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005203 const int num_4x4_w = tx_size_wide_unit[tx_size];
5204 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005205#if !CONFIG_PVQ
5206 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5207#else
5208 (void)cpi;
5209 (void)ta;
5210 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005211 (void)tx_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08005212#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005213
5214#if CONFIG_EXT_TX && CONFIG_RECT_TX
5215 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5216 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5217 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5218#else
5219 assert(tx_size == TX_4X4);
5220#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005221
Yaowu Xuc27fc142016-08-22 16:08:15 -07005222 assert(tx_type == DCT_DCT);
5223
Jingning Hanc44009c2017-05-06 11:36:49 -07005224 av1_build_inter_predictor_sub8x8(cm, xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005225
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005226#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005227 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005228 aom_highbd_subtract_block(
5229 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5230 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005232 aom_subtract_block(height, width,
5233 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005234 8, src, p->src.stride, dst, pd->dst.stride);
5235 }
5236#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005237 aom_subtract_block(height, width,
5238 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239 8, src, p->src.stride, dst, pd->dst.stride);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005240#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005241
Jingning Hanbafee8d2016-12-02 10:25:03 -08005242 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5243 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005244 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005245 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005246 const int k = i + (idy * 2 + idx);
5247 const int block = av1_raster_order_to_block_index(tx_size, k);
5248 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5249 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005250 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Angie Chiangff6d8902016-10-21 11:02:09 -07005251 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005252 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07005253 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang808d8592017-04-06 18:36:55 -07005254 av1_dist_block(cpi, x, 0, BLOCK_8X8, block, idy + (i >> 1),
5255 idx + (i & 0x1), tx_size, &dist, &ssz,
5256 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005257 thisdistortion += dist;
5258 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005259#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005260 thisrate +=
Angie Chiang05917872017-04-15 12:28:56 -07005261 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, (ta + (k & 1)),
Angie Chiang77368af2017-03-23 16:22:07 -07005262 (tl + (k >> 1)), cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5264 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005265#else
5266 thisrate += x->rate;
Fergus Simpson4063a682017-02-28 16:52:22 -08005267#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005268#if CONFIG_EXT_TX
5269 if (tx_size == TX_8X4) {
5270 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5271 }
5272 if (tx_size == TX_4X8) {
5273 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5274 }
5275#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005276 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5277 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005278 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005279 if (rd >= best_yrd) return INT64_MAX;
5280 }
5281 }
5282
5283 *distortion = thisdistortion;
5284 *labelyrate = thisrate;
5285 *sse = thissse;
5286
5287 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5288}
5289
5290typedef struct {
5291 int eobs;
5292 int brate;
5293 int byrate;
5294 int64_t bdist;
5295 int64_t bsse;
5296 int64_t brdcost;
5297 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005298 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005299#if CONFIG_EXT_INTER
5300 int_mv ref_mv[2];
5301#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005302
5303#if CONFIG_CB4X4
5304 ENTROPY_CONTEXT ta[4];
5305 ENTROPY_CONTEXT tl[4];
5306#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307 ENTROPY_CONTEXT ta[2];
5308 ENTROPY_CONTEXT tl[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005309#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310} SEG_RDSTAT;
5311
5312typedef struct {
5313 int_mv *ref_mv[2];
5314 int_mv mvp;
5315
5316 int64_t segment_rd;
5317 int r;
5318 int64_t d;
5319 int64_t sse;
5320 int segment_yrate;
5321 PREDICTION_MODE modes[4];
5322#if CONFIG_EXT_INTER
5323 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5324#else
5325 SEG_RDSTAT rdstat[4][INTER_MODES];
5326#endif // CONFIG_EXT_INTER
5327 int mvthresh;
5328} BEST_SEG_INFO;
5329
Alex Converse0fa0f422017-04-24 12:51:14 -07005330static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5331 return (mv->row >> 3) < mv_limits->row_min ||
5332 (mv->row >> 3) > mv_limits->row_max ||
5333 (mv->col >> 3) < mv_limits->col_min ||
5334 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335}
5336
5337static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5338 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5339 struct macroblock_plane *const p = &x->plane[0];
5340 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5341
5342 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005343 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005344 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5345 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005346 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005347 if (has_second_ref(mbmi))
5348 pd->pre[1].buf =
5349 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005350 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005351}
5352
5353static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5354 struct buf_2d orig_pre[2]) {
5355 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5356 x->plane[0].src = orig_src;
5357 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5358 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5359}
5360
5361// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5362// TODO(aconverse): Find out if this is still productive then clean up or remove
5363static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005364 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005365#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005366 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005367#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005369 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5370 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005371 int_mv zeromv[2];
5372 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5373 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005374 (void)mi_row;
5375 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005376 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5377#if CONFIG_GLOBAL_MOTION
5378 if (this_mode == ZEROMV
5379#if CONFIG_EXT_INTER
5380 || this_mode == ZERO_ZEROMV
5381#endif // CONFIG_EXT_INTER
5382 )
5383 zeromv[cur_frm].as_int =
5384 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005385 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005386 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005387 .as_int;
5388 else
5389#endif // CONFIG_GLOBAL_MOTION
5390 zeromv[cur_frm].as_int = 0;
5391 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005392#if !CONFIG_EXT_INTER
5393 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005394#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005395 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005396 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005397 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005398 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005400 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005401 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5402 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5403 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005404
Yaowu Xuc27fc142016-08-22 16:08:15 -07005405 if (this_mode == NEARMV) {
5406 if (c1 > c3) return 0;
5407 } else if (this_mode == NEARESTMV) {
5408 if (c2 > c3) return 0;
5409 } else {
5410 assert(this_mode == ZEROMV);
5411 if (ref_frames[1] <= INTRA_FRAME) {
5412 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5413 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5414 return 0;
5415 } else {
5416 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5417 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5418 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5419 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5420 return 0;
5421 }
5422 }
5423 }
5424#if CONFIG_EXT_INTER
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005425 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005426 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005427 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5428 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005429 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005430 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5431 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005432 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005433
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005434 if (this_mode == NEAREST_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005435 if (c2 > c3) return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436 } else if (this_mode == NEAR_NEARMV) {
5437 if (c5 > c3) return 0;
5438 } else {
5439 assert(this_mode == ZERO_ZEROMV);
5440 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5441 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005443 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005444 return 0;
5445 }
5446 }
5447#endif // CONFIG_EXT_INTER
5448 return 1;
5449}
5450
Urvang Joshi52648442016-10-13 17:27:51 -07005451static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5452 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5453 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005454#if CONFIG_EXT_INTER
David Barkerc155e012017-05-11 13:54:54 +01005455 int_mv *ref_mv_sub8x8[2], const uint8_t *mask,
5456 int mask_stride,
Fergus Simpson4063a682017-02-28 16:52:22 -08005457#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005459 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005460 const int pw = block_size_wide[bsize];
5461 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005462 MACROBLOCKD *xd = &x->e_mbd;
5463 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005464 // This function should only ever be called for compound modes
5465 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005466 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005467 int_mv ref_mv[2];
5468 int ite, ref;
5469#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005470 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5472 mbmi->interp_filter[3],
5473 };
5474#else
James Zern7b9407a2016-05-18 23:48:05 -07005475 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005476#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005477 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005478 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005479#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005480 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5481 const int ic = block & 1;
5482 const int ir = (block - ic) >> 1;
5483 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5484 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005485#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005486 int is_global[2];
5487 for (ref = 0; ref < 2; ++ref) {
5488 WarpedMotionParams *const wm =
5489 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5490 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5491 }
5492#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005493#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005494
5495 // Do joint motion search in compound mode to get more accurate mv.
5496 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5497 int last_besterr[2] = { INT_MAX, INT_MAX };
5498 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005499 av1_get_scaled_ref_frame(cpi, refs[0]),
5500 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005501 };
5502
5503// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005504#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005505 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5506 uint8_t *second_pred;
5507#else
5508 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005509#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005510
Jingning Han61418bb2017-01-23 17:12:48 -08005511#if CONFIG_EXT_INTER && CONFIG_CB4X4
5512 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005513#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005514
Yaowu Xuc27fc142016-08-22 16:08:15 -07005515 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005516#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5518 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5519 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005520#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005521 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5522
5523 if (scaled_ref_frame[ref]) {
5524 int i;
5525 // Swap out the reference frame for a version that's been scaled to
5526 // match the resolution of the current frame, allowing the existing
5527 // motion search code to be used without additional modifications.
5528 for (i = 0; i < MAX_MB_PLANE; i++)
5529 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005530 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5531 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005532 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005533 }
5534
5535// Since we have scaled the reference frames to match the size of the current
5536// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005537#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005538 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5539 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005540#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005541 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5542 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005543#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005544
5545 // Allow joint search multiple times iteratively for each reference frame
5546 // and break out of the search loop if it couldn't find a better mv.
5547 for (ite = 0; ite < 4; ite++) {
5548 struct buf_2d ref_yv12[2];
5549 int bestsme = INT_MAX;
5550 int sadpb = x->sadperbit16;
5551 MV *const best_mv = &x->best_mv.as_mv;
5552 int search_range = 3;
5553
Alex Converse0fa0f422017-04-24 12:51:14 -07005554 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005555 int id = ite % 2; // Even iterations search in the first reference frame,
5556 // odd iterations search in the second. The predictor
5557 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005558 const int plane = 0;
5559 ConvolveParams conv_params = get_conv_params(0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005560#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5561 WarpTypesAllowed warp_types;
5562#if CONFIG_GLOBAL_MOTION
5563 warp_types.global_warp_allowed = is_global[!id];
5564#endif // CONFIG_GLOBAL_MOTION
5565#if CONFIG_WARPED_MOTION
5566 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5567#endif // CONFIG_WARPED_MOTION
5568#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005569
5570 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005571 ref_yv12[0] = xd->plane[plane].pre[0];
5572 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005573
5574#if CONFIG_DUAL_FILTER
5575 // reload the filter types
5576 interp_filter[0] =
5577 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5578 interp_filter[1] =
5579 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005580#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581
5582// Get the prediction block from the 'other' reference frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005583#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005584 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5585 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005586 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5588 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005589#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5590 &warp_types, p_col, p_row,
5591#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005592 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593 } else {
5594 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005595#endif // CONFIG_HIGHBITDEPTH
Angie Chiang9f45bc42017-01-13 16:27:54 -08005596 av1_build_inter_predictor(
5597 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5598 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005599#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5600 &warp_types, p_col, p_row, plane, !id,
5601#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005602 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005603#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005604 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005605#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005606
5607 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005608 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005609 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610
5611 // Use the mv result from the single mode as mv predictor.
5612 *best_mv = frame_mv[refs[id]].as_mv;
5613
5614 best_mv->col >>= 3;
5615 best_mv->row >>= 3;
5616
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005617 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618
5619 // Small-range full-pixel motion search.
5620 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005621 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
David Barkerc155e012017-05-11 13:54:54 +01005622#if CONFIG_EXT_INTER
5623 mask, mask_stride, id,
5624#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005625 &ref_mv[id].as_mv, second_pred);
David Barkerc155e012017-05-11 13:54:54 +01005626 if (bestsme < INT_MAX) {
5627#if CONFIG_EXT_INTER
5628 if (mask)
5629 bestsme = av1_get_mvpred_mask_var(x, best_mv, &ref_mv[id].as_mv,
5630 second_pred, mask, mask_stride, id,
5631 &cpi->fn_ptr[bsize], 1);
5632 else
5633#endif
5634 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5635 second_pred, &cpi->fn_ptr[bsize], 1);
5636 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637
Alex Converse0fa0f422017-04-24 12:51:14 -07005638 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005639
5640 if (bestsme < INT_MAX) {
5641 int dis; /* TODO: use dis in distortion calculation later. */
5642 unsigned int sse;
5643 if (cpi->sf.use_upsampled_references) {
5644 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005645 struct buf_2d backup_pred = pd->pre[0];
5646 const YV12_BUFFER_CONFIG *upsampled_ref =
5647 get_upsampled_ref(cpi, refs[id]);
5648
5649 // Set pred for Y plane
Jingning Han91d9a792017-04-18 12:01:52 -07005650 setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 upsampled_ref->y_crop_width,
5652 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5653 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5654 pd->subsampling_y);
5655
Jingning Han271bb2c2016-12-14 12:34:46 -08005656// If bsize < BLOCK_8X8, adjust pred pointer for this block
5657#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658 if (bsize < BLOCK_8X8)
5659 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005660 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5661 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005662 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005663#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664
5665 bestsme = cpi->find_fractional_mv_step(
5666 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5667 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5668 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01005669 &dis, &sse, second_pred,
5670#if CONFIG_EXT_INTER
5671 mask, mask_stride, id,
5672#endif
5673 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005674
5675 // Restore the reference frames.
5676 pd->pre[0] = backup_pred;
5677 } else {
5678 (void)block;
5679 bestsme = cpi->find_fractional_mv_step(
5680 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5681 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5682 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01005683 &dis, &sse, second_pred,
5684#if CONFIG_EXT_INTER
5685 mask, mask_stride, id,
5686#endif
5687 pw, ph, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688 }
5689 }
5690
5691 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005692 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005693
5694 if (bestsme < last_besterr[id]) {
5695 frame_mv[refs[id]].as_mv = *best_mv;
5696 last_besterr[id] = bestsme;
5697 } else {
5698 break;
5699 }
5700 }
5701
5702 *rate_mv = 0;
5703
5704 for (ref = 0; ref < 2; ++ref) {
5705 if (scaled_ref_frame[ref]) {
5706 // Restore the prediction frame pointers to their unscaled versions.
5707 int i;
5708 for (i = 0; i < MAX_MB_PLANE; i++)
5709 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5710 }
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005711 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Jingning Han61418bb2017-01-23 17:12:48 -08005712#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005714#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005715 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5716 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5717 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005718#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005719 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005720 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5721 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5722 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005723#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005724 }
5725}
5726
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005727#if !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005728static void update_mv_search_and_seg_mvs(
5729 int *const run_mv_search, int_mv *const seg_mvs, int has_second_rf,
5730 const MV_REFERENCE_FRAME *const ref_frame,
5731 const SEG_RDSTAT *const ref_rdstat, int_mv *const bsi_ref_mv[2]) {
5732 if (has_second_rf) {
5733 if (seg_mvs[ref_frame[0]].as_int == ref_rdstat->mvs[0].as_int &&
5734 ref_rdstat->mvs[0].as_int != INVALID_MV)
5735 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5736 --*run_mv_search;
5737
5738 if (seg_mvs[ref_frame[1]].as_int == ref_rdstat->mvs[1].as_int &&
5739 ref_rdstat->mvs[1].as_int != INVALID_MV)
5740 if (bsi_ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5741 --*run_mv_search;
5742 } else {
5743 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5744 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5745 *run_mv_search = 0;
5746 seg_mvs[ref_frame[0]].as_int = ref_rdstat->mvs[0].as_int;
5747 }
5748 }
5749}
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005750#endif // !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005751
Yushin Cho482016d2017-01-06 14:06:13 -08005752static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005753 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005754 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5755 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005756 int mvthresh, int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005757#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005758 int_mv compound_seg_newmvs[4][2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005759#endif // CONFIG_EXT_INTER
5760 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5761 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005762 int_mv tmp_ref_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005763 MACROBLOCKD *xd = &x->e_mbd;
5764 MODE_INFO *mi = xd->mi[0];
5765 MB_MODE_INFO *mbmi = &mi->mbmi;
5766 int mode_idx;
5767 int k, br = 0, idx, idy;
5768 int64_t bd = 0, block_sse = 0;
5769 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005770 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005771 struct macroblock_plane *const p = &x->plane[0];
5772 struct macroblockd_plane *const pd = &xd->plane[0];
5773 const int label_count = 4;
5774 int64_t this_segment_rd = 0;
5775 int label_mv_thresh;
5776 int segmentyrate = 0;
5777 const BLOCK_SIZE bsize = mbmi->sb_type;
5778 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5779 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005780#if CONFIG_CB4X4
5781 ENTROPY_CONTEXT t_above[4], t_left[4];
5782#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005783 ENTROPY_CONTEXT t_above[2], t_left[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005784#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005785 int subpelmv = 1, have_ref = 0;
5786 const int has_second_rf = has_second_ref(mbmi);
5787 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5788 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005789#if CONFIG_PVQ
5790 od_rollback_buffer pre_buf;
5791
5792 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005793#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005794#if CONFIG_EXT_TX && CONFIG_RECT_TX
5795 mbmi->tx_size =
5796 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5797#else
5798 mbmi->tx_size = TX_4X4;
5799#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5800
Yaowu Xuf883b422016-08-30 14:01:10 -07005801 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005802
5803 bsi->segment_rd = best_rd;
5804 bsi->ref_mv[0] = best_ref_mv;
5805 bsi->ref_mv[1] = second_best_ref_mv;
5806 bsi->mvp.as_int = best_ref_mv->as_int;
5807 bsi->mvthresh = mvthresh;
5808
5809 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5810
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811 for (idx = 0; idx < 4; ++idx) {
5812 for (k = NEARESTMV; k <= NEWMV; ++k) {
5813 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5814 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5815
5816 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5817 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5818 }
5819 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005820
5821 memcpy(t_above, pd->above_context, sizeof(t_above));
5822 memcpy(t_left, pd->left_context, sizeof(t_left));
5823
5824 // 64 makes this threshold really big effectively
5825 // making it so that we very rarely check mvs on
5826 // segments. setting this to 1 would make mv thresh
5827 // roughly equal to what it is for macroblocks
5828 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5829
5830 // Segmentation method overheads
5831 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5832 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5833 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5834 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5835 int_mv mode_mv[MB_MODE_COUNT][2];
5836 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5837 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005838 int64_t new_best_rd = INT64_MAX;
5839 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005840 int ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005841 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5842 uint8_t ref_mv_count[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005844 int_mv ref_mvs_sub8x8[2][2];
5845#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005846#if CONFIG_PVQ
5847 od_rollback_buffer idx_buf, post_buf;
5848 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5849 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005850#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005851
5852 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5853 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5854#if CONFIG_EXT_INTER
5855 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Yaowu Xu531d6af2017-03-07 17:48:52 -08005856 av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
5857 mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005858#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005859#if CONFIG_GLOBAL_MOTION
5860 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -08005861 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005862 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005863 mi_col, mi_row, index)
David Barkercdcac6d2016-12-01 17:04:16 +00005864 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005865#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005866 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005867#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005868 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005869 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005870#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005871 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005872#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005873 &frame_mv[NEARESTMV][frame],
5874 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005875
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5877 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5878 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5879 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005880
5881#if CONFIG_EXT_INTER
5882 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5883 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005884 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5885 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886
5887 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005888#if CONFIG_GLOBAL_MOTION
5889 frame_mv[ZERO_ZEROMV][frame].as_int =
5890 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005891 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005892 mi_col, mi_row, index)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005893 .as_int;
5894#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005895 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005896#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005897 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5898 frame_mv[NEARESTMV][frame].as_int;
5899
5900 if (ref == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005901 frame_mv[NEAREST_NEWMV][frame].as_int =
5902 frame_mv[NEARESTMV][frame].as_int;
5903 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5904 frame_mv[NEAR_NEARMV][frame].as_int =
5905 frame_mv[NEARMV][frame].as_int;
5906 } else if (ref == 1) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907 frame_mv[NEW_NEARESTMV][frame].as_int =
5908 frame_mv[NEARESTMV][frame].as_int;
5909 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5910 frame_mv[NEAR_NEARMV][frame].as_int =
5911 frame_mv[NEARMV][frame].as_int;
5912 }
5913 }
5914#endif // CONFIG_EXT_INTER
5915 }
5916
5917// search for the best motion vector on this segment
5918#if CONFIG_EXT_INTER
5919 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005920 this_mode <= (has_second_rf ? NEW_NEWMV : NEWMV); ++this_mode)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005921#else
5922 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5923#endif // CONFIG_EXT_INTER
5924 {
5925 const struct buf_2d orig_src = x->plane[0].src;
5926 struct buf_2d orig_pre[2];
5927 // This flag controls if the motion estimation will kick off. When it
5928 // is set to a non-zero value, the encoder will force motion estimation.
5929 int run_mv_search = 0;
5930
5931 mode_idx = INTER_OFFSET(this_mode);
5932#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005933 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005934 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[0][ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005935#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005936 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937 if (!(inter_mode_mask & (1 << this_mode))) continue;
5938
Yaowu Xuc27fc142016-08-22 16:08:15 -07005939 run_mv_search = 2;
5940#if !CONFIG_EXT_INTER
5941 if (filter_idx > 0 && this_mode == NEWMV) {
Urvang Joshif7751be2017-04-27 12:50:39 -07005942 const BEST_SEG_INFO *ref_bsi = bsi_buf;
5943 const SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005944
Urvang Joshif7751be2017-04-27 12:50:39 -07005945 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5946 has_second_rf, mbmi->ref_frame,
5947 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005948
5949 if (run_mv_search != 0 && filter_idx > 1) {
5950 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005951 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005952 run_mv_search = 2;
Urvang Joshif7751be2017-04-27 12:50:39 -07005953 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5954 has_second_rf, mbmi->ref_frame,
5955 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005956 }
5957 }
Fergus Simpson4063a682017-02-28 16:52:22 -08005958#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005959
Sarah Parkere5299862016-08-16 14:57:37 -07005960#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005961 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005962 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005963 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005964#endif // CONFIG_GLOBAL_MOTION
5965
5966 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005967#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005968 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005969#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005970 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00005971 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07005972 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005973
5974 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005975 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5976 sizeof(bsi->rdstat[index][mode_idx].ta));
5977 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5978 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005979#if CONFIG_PVQ
5980 od_encode_rollback(&x->daala_enc, &idx_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005981#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005982
5983 // motion search for newmv (single predictor case only)
5984 if (!has_second_rf &&
5985#if CONFIG_EXT_INTER
5986 have_newmv_in_inter_mode(this_mode) &&
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005987 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005988#else
5989 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005990 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005991 run_mv_search)
5992#endif // CONFIG_EXT_INTER
5993 ) {
5994 int step_param = 0;
5995 int bestsme = INT_MAX;
5996 int sadpb = x->sadperbit4;
5997 MV mvp_full;
5998 int max_mv;
5999 int cost_list[5];
Alex Converse0fa0f422017-04-24 12:51:14 -07006000 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006001
6002 /* Is the best so far sufficiently good that we cant justify doing
6003 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07006004 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006005
Yaowu Xuc27fc142016-08-22 16:08:15 -07006006#if CONFIG_EXT_INTER
Thomas Daede6eca8352017-03-17 14:14:12 -07006007 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006008#else
6009// use previous block's result as next block's MV predictor.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006010#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006011 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
6012 : AOMMAX(abs(bsi->mvp.as_mv.row),
6013 abs(bsi->mvp.as_mv.col)) >>
6014 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015
6016 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6017 // Take wtd average of the step_params based on the last frame's
6018 // max mv magnitude and the best ref mvs of the current block for
6019 // the given reference.
6020 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006021 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006022 } else {
6023 step_param = cpi->mv_step_param;
6024 }
6025
Yaowu Xuc27fc142016-08-22 16:08:15 -07006026 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
6027 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006028
6029 if (cpi->sf.adaptive_motion_search) {
6030 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
6031 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07006032 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006033 }
6034
6035 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07006036 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006037
Alex Converse0fa0f422017-04-24 12:51:14 -07006038 av1_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006039
6040 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6041
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006042 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07006043 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006044 cpi, x, bsize, &mvp_full, step_param, sadpb,
6045 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6046 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6047
Alex Converse0fa0f422017-04-24 12:51:14 -07006048 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049
6050 if (bestsme < INT_MAX) {
6051 int distortion;
6052 if (cpi->sf.use_upsampled_references) {
6053 int best_mv_var;
6054 const int try_second =
6055 x->second_best_mv.as_int != INVALID_MV &&
6056 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006057 const int pw = block_size_wide[bsize];
6058 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006059 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 struct buf_2d backup_pred = pd->pre[0];
6061 const YV12_BUFFER_CONFIG *upsampled_ref =
6062 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6063
6064 // Set pred for Y plane
6065 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006066 &pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006067 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6068 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6069 pd->subsampling_x, pd->subsampling_y);
6070
6071 // adjust pred pointer for this block
6072 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006073 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006074 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006075 << 3];
6076
6077 best_mv_var = cpi->find_fractional_mv_step(
6078 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6079 x->errorperbit, &cpi->fn_ptr[bsize],
6080 cpi->sf.mv.subpel_force_stop,
6081 cpi->sf.mv.subpel_iters_per_step,
6082 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01006083 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL,
6084#if CONFIG_EXT_INTER
6085 NULL, 0, 0,
6086#endif
6087 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006088
6089 if (try_second) {
6090 int this_var;
6091 MV best_mv = x->best_mv.as_mv;
6092 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Alex Converse0fa0f422017-04-24 12:51:14 -07006093 const int minc =
6094 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6095 const int maxc =
6096 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6097 const int minr =
6098 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6099 const int maxr =
6100 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006101
6102 x->best_mv = x->second_best_mv;
6103 if (x->best_mv.as_mv.row * 8 <= maxr &&
6104 x->best_mv.as_mv.row * 8 >= minr &&
6105 x->best_mv.as_mv.col * 8 <= maxc &&
6106 x->best_mv.as_mv.col * 8 >= minc) {
6107 this_var = cpi->find_fractional_mv_step(
6108 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6109 x->errorperbit, &cpi->fn_ptr[bsize],
6110 cpi->sf.mv.subpel_force_stop,
6111 cpi->sf.mv.subpel_iters_per_step,
6112 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6113 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
David Barkerc155e012017-05-11 13:54:54 +01006114 NULL,
6115#if CONFIG_EXT_INTER
6116 NULL, 0, 0,
6117#endif
6118 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006119 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6120 x->best_mv.as_mv = best_mv;
6121 }
6122 }
6123
6124 // Restore the reference frames.
6125 pd->pre[0] = backup_pred;
6126 } else {
6127 cpi->find_fractional_mv_step(
6128 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6129 x->errorperbit, &cpi->fn_ptr[bsize],
6130 cpi->sf.mv.subpel_force_stop,
6131 cpi->sf.mv.subpel_iters_per_step,
6132 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01006133 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL,
6134#if CONFIG_EXT_INTER
6135 NULL, 0, 0,
6136#endif
6137 0, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006138 }
6139
6140// save motion search result for use in compound prediction
6141#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006142 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006143#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006144 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145#endif // CONFIG_EXT_INTER
6146 }
6147
6148 if (cpi->sf.adaptive_motion_search)
6149 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6150
6151#if CONFIG_EXT_INTER
6152 mode_mv[this_mode][0] = x->best_mv;
6153#else
6154 mode_mv[NEWMV][0] = x->best_mv;
6155#endif // CONFIG_EXT_INTER
6156
6157 // restore src pointers
6158 mi_buf_restore(x, orig_src, orig_pre);
6159 }
6160
6161 if (has_second_rf) {
6162#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006163 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6164 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006166 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6167 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168#endif // CONFIG_EXT_INTER
6169 continue;
6170 }
6171
6172#if CONFIG_DUAL_FILTER
6173 (void)run_mv_search;
Fergus Simpson4063a682017-02-28 16:52:22 -08006174#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006175
6176 if (has_second_rf &&
6177#if CONFIG_EXT_INTER
6178 this_mode == NEW_NEWMV &&
6179#else
6180 this_mode == NEWMV &&
6181#endif // CONFIG_EXT_INTER
6182#if CONFIG_DUAL_FILTER
6183 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6184#else
6185 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
Fergus Simpson4063a682017-02-28 16:52:22 -08006186#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006187 {
6188 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006189 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6191 int rate_mv;
Zoe Liu122f3942017-04-25 11:18:38 -07006192 frame_mv[this_mode][mbmi->ref_frame[0]].as_int =
6193 seg_mvs[index][mbmi->ref_frame[0]].as_int;
6194 frame_mv[this_mode][mbmi->ref_frame[1]].as_int =
6195 seg_mvs[index][mbmi->ref_frame[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6197 mi_col,
6198#if CONFIG_EXT_INTER
David Barkerc155e012017-05-11 13:54:54 +01006199 bsi->ref_mv, NULL, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006200#endif // CONFIG_EXT_INTER
Zoe Liu122f3942017-04-25 11:18:38 -07006201 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006203 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006204 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006205 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006206 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6207#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006208 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006210 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006211 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6212#endif // CONFIG_EXT_INTER
6213 }
6214 // restore src pointers
6215 mi_buf_restore(x, orig_src, orig_pre);
6216 }
6217
Urvang Joshi454280d2016-10-14 16:51:44 -07006218 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6219 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Urvang Joshi454280d2016-10-14 16:51:44 -07006220 seg_mvs[index],
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006221#if CONFIG_EXT_INTER
6222 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006223#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006224 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006225
6226 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006227 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006228 mode_mv[this_mode][ref].as_int;
6229 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006230 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006231 mode_mv[this_mode][ref].as_int;
6232 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006233 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006234 mode_mv[this_mode][ref].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006235 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6236 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006237 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006238 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6239 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006240 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006241 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6242 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006243#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006244 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006245 bsi->ref_mv[ref]->as_int;
6246 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006247 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006248 bsi->ref_mv[ref]->as_int;
6249 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006250 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006251 bsi->ref_mv[ref]->as_int;
6252#endif // CONFIG_EXT_INTER
6253 }
6254
6255 // Trap vectors that reach beyond the UMV borders
Alex Converse0fa0f422017-04-24 12:51:14 -07006256 if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) ||
6257 (has_second_rf &&
6258 mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv)))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006259 continue;
6260
6261 if (filter_idx > 0) {
6262 BEST_SEG_INFO *ref_bsi = bsi_buf;
6263 subpelmv = 0;
6264 have_ref = 1;
6265
6266 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6267 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6268#if CONFIG_EXT_INTER
6269 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006270 have_ref &=
6271 ((mode_mv[this_mode][ref].as_int ==
6272 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6273 (bsi->ref_mv[ref]->as_int ==
6274 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006275 else
6276#endif // CONFIG_EXT_INTER
6277 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006278 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 }
6280
Urvang Joshi454280d2016-10-14 16:51:44 -07006281 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006282
6283 if (filter_idx > 1 && !subpelmv && !have_ref) {
6284 ref_bsi = bsi_buf + 1;
6285 have_ref = 1;
6286 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6287#if CONFIG_EXT_INTER
6288 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006289 have_ref &=
6290 ((mode_mv[this_mode][ref].as_int ==
6291 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6292 (bsi->ref_mv[ref]->as_int ==
6293 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006294 else
6295#endif // CONFIG_EXT_INTER
6296 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006297 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298
Urvang Joshi454280d2016-10-14 16:51:44 -07006299 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006300 }
6301
6302 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006303 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006304 bsi->rdstat[index][mode_idx].byrate =
6305 ref_bsi->rdstat[index][mode_idx].byrate;
6306 bsi->rdstat[index][mode_idx].bdist =
6307 ref_bsi->rdstat[index][mode_idx].bdist;
6308 bsi->rdstat[index][mode_idx].bsse =
6309 ref_bsi->rdstat[index][mode_idx].bsse;
6310 bsi->rdstat[index][mode_idx].brate +=
6311 ref_bsi->rdstat[index][mode_idx].byrate;
6312 bsi->rdstat[index][mode_idx].eobs =
6313 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006314
Urvang Joshi454280d2016-10-14 16:51:44 -07006315 bsi->rdstat[index][mode_idx].brdcost =
6316 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6317 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006318
Urvang Joshi454280d2016-10-14 16:51:44 -07006319 memcpy(bsi->rdstat[index][mode_idx].ta,
6320 ref_bsi->rdstat[index][mode_idx].ta,
6321 sizeof(bsi->rdstat[index][mode_idx].ta));
6322 memcpy(bsi->rdstat[index][mode_idx].tl,
6323 ref_bsi->rdstat[index][mode_idx].tl,
6324 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006325 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006326 bsi->rdstat[index + 1][mode_idx].eobs =
6327 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006328 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006329 bsi->rdstat[index + 2][mode_idx].eobs =
6330 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006331
Urvang Joshi454280d2016-10-14 16:51:44 -07006332 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006333 // If the NEWMV mode is using the same motion vector as the
6334 // NEARESTMV mode, skip the rest rate-distortion calculations
6335 // and use the inferred motion vector modes.
6336 if (this_mode == NEWMV) {
6337 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006338 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006339 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006340 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006341 bsi->ref_mv[1]->as_int)
6342 continue;
6343 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006344 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006345 bsi->ref_mv[0]->as_int)
6346 continue;
6347 }
6348 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006349 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006350 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006351#if CONFIG_PVQ
6352 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006353#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354 }
6355 continue;
6356 }
6357 }
6358
Yushin Choab44fd12017-01-09 16:06:53 -08006359 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006360 cpi, x, bsi->segment_rd - this_segment_rd, index,
6361 &bsi->rdstat[index][mode_idx].byrate,
6362 &bsi->rdstat[index][mode_idx].bdist,
6363 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6364 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006365
Urvang Joshi454280d2016-10-14 16:51:44 -07006366 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6367 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6368 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6369 bsi->rdstat[index][mode_idx].brate +=
6370 bsi->rdstat[index][mode_idx].byrate;
6371 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006372 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006373 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006374 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006375 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006376 }
6377
Urvang Joshi454280d2016-10-14 16:51:44 -07006378 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379 // If the NEWMV mode is using the same motion vector as the
6380 // NEARESTMV mode, skip the rest rate-distortion calculations
6381 // and use the inferred motion vector modes.
6382 if (this_mode == NEWMV) {
6383 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006384 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006385 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006386 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006387 bsi->ref_mv[1]->as_int)
6388 continue;
6389 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006390 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006391 bsi->ref_mv[0]->as_int)
6392 continue;
6393 }
6394 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006395 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006396 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006397
6398#if CONFIG_PVQ
6399 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006400#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006401 }
6402 } /*for each 4x4 mode*/
6403
Urvang Joshi454280d2016-10-14 16:51:44 -07006404 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006405 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006406 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006407#if CONFIG_EXT_INTER
6408 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6409#else
6410 for (midx = 0; midx < INTER_MODES; ++midx)
6411#endif // CONFIG_EXT_INTER
6412 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6413 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006414#if CONFIG_PVQ
6415 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006416#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006417 return INT64_MAX;
6418 }
6419
6420 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006421 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6422 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006423#if CONFIG_PVQ
6424 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006425#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006426
6427#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006428 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006430 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006432 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
6433 mode_mv[mode_selected], frame_mv, seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006434#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006435 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006436#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006437 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row,
6438 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006439
Urvang Joshi454280d2016-10-14 16:51:44 -07006440 br += bsi->rdstat[index][mode_idx].brate;
6441 bd += bsi->rdstat[index][mode_idx].bdist;
6442 block_sse += bsi->rdstat[index][mode_idx].bsse;
6443 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6444 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006445
6446 if (this_segment_rd > bsi->segment_rd) {
6447 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006448 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006449#if CONFIG_EXT_INTER
6450 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6451#else
6452 for (midx = 0; midx < INTER_MODES; ++midx)
6453#endif // CONFIG_EXT_INTER
6454 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6455 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006456#if CONFIG_PVQ
6457 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006458#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006459 return INT64_MAX;
6460 }
6461 }
6462 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006463#if CONFIG_PVQ
6464 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006465#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006466
6467 bsi->r = br;
6468 bsi->d = bd;
6469 bsi->segment_yrate = segmentyrate;
6470 bsi->segment_rd = this_segment_rd;
6471 bsi->sse = block_sse;
6472
6473 // update the coding decisions
6474 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6475
Yushin Cho7a428ba2017-01-12 16:28:49 -08006476#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07006477 // Compute prediction (i.e. skip) and decoded distortion by daala-distortion.
Yushin Cho7a428ba2017-01-12 16:28:49 -08006478 {
6479 const int src_stride = p->src.stride;
6480 const int dst_stride = pd->dst.stride;
6481 uint8_t *src = p->src.buf;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006482 uint8_t *dst = pd->dst.buf;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006483 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006484 const int use_activity_masking = 0;
6485 const int qm = OD_HVS_QM;
6486 const int bsw = block_size_wide[plane_bsize];
6487 const int bsh = block_size_high[plane_bsize];
6488 int64_t rd1, rd2;
6489 int64_t daala_sse, daala_dist;
6490 TX_SIZE tx_size = mbmi->tx_size;
6491
6492#if CONFIG_HIGHBITDEPTH
6493 uint8_t *recon_8x8;
6494 DECLARE_ALIGNED(16, uint16_t, recon16[8 * 8]);
6495
6496 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6497 recon_8x8 = CONVERT_TO_BYTEPTR(recon16);
6498 else
6499 recon_8x8 = (uint8_t *)recon16;
6500#else
6501 DECLARE_ALIGNED(16, uint8_t, recon_8x8[8 * 8]);
6502#endif // CONFIG_HIGHBITDEPTH
6503
Yushin Cho7a428ba2017-01-12 16:28:49 -08006504#if CONFIG_PVQ
6505 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08006506#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006507
Yushin Cho4483e3d2017-04-18 19:41:20 -07006508 // For each of sub8x8 prediction block in a 8x8 block
6509 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08006510 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6511 int i = idy * 2 + idx;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006512 const uint8_t *const src_sub8x8 =
6513 src + av1_raster_block_offset(BLOCK_8X8, i, p->src.stride);
6514 uint8_t *const dst_sub8x8 =
6515 dst + av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride);
6516 uint8_t *recon_sub8x8 = recon_8x8 + (idy * 8 + idx) * 4;
6517 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6518 const int txb_height = max_block_high(xd, plane_bsize, 0);
6519 int idx_, idy_;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006520
Jingning Hanc44009c2017-05-06 11:36:49 -07006521 av1_build_inter_predictor_sub8x8(cm, xd, 0, i, idy, idx, mi_row,
6522 mi_col);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006523#if CONFIG_HIGHBITDEPTH
6524 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6525 aom_highbd_subtract_block(
Sebastien Alaiwan3f1ae4e2017-05-12 11:20:28 +02006526 bsh, bsw,
Yushin Cho4483e3d2017-04-18 19:41:20 -07006527 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6528 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride, xd->bd);
6529 } else {
6530 aom_subtract_block(
Sebastien Alaiwan3f1ae4e2017-05-12 11:20:28 +02006531 bsh, bsw,
Yushin Cho4483e3d2017-04-18 19:41:20 -07006532 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6533 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6534 }
6535#else
6536 aom_subtract_block(
6537 bsh, bsw, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
6538 8, src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6539#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006540
Yushin Cho4483e3d2017-04-18 19:41:20 -07006541#if CONFIG_HIGHBITDEPTH
6542 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6543 aom_highbd_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8,
6544 NULL, 0, NULL, 0, bsw, bsh, xd->bd);
6545 } else {
6546#endif // CONFIG_HIGHBITDEPTH
6547 aom_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8, NULL, 0,
6548 NULL, 0, bsw, bsh);
6549#if CONFIG_HIGHBITDEPTH
6550 }
6551#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006552
Yushin Cho4483e3d2017-04-18 19:41:20 -07006553 // To get decoded pixels, do 4x4 xform and quant for each 4x4 block
6554 // in a sub8x8 prediction block. In case remaining parts of
6555 // sub8x8 inter mode rdo assume pd->dst stores predicted pixels,
6556 // use local buffer to store decoded pixels.
6557 for (idy_ = 0; idy_ < txb_height; idy_++) {
6558 for (idx_ = 0; idx_ < txb_width; idx_++) {
6559 int coeff_ctx = 0;
6560 const tran_low_t *dqcoeff;
6561 uint16_t eob;
6562 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6563 uint8_t *recon_4x4 = recon_sub8x8 + (idy_ * 8 + idx_) * 4;
6564 const int block_raster_idx = (idy + idy_) * 2 + (idx + idx_);
6565 const int block =
6566 av1_raster_order_to_block_index(tx_size, block_raster_idx);
6567 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006568
Yushin Cho4483e3d2017-04-18 19:41:20 -07006569 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6570 av1_xform_quant(cm, x, 0, block, idy + idy_, idx + idx_, BLOCK_8X8,
6571 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07006572 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006573
Yushin Cho4483e3d2017-04-18 19:41:20 -07006574 eob = p->eobs[block];
6575 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size,
6576 recon_4x4, 8, eob);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006577 }
6578 }
6579 }
Yushin Cho4483e3d2017-04-18 19:41:20 -07006580 }
6581 // Compute daala-distortion for a 8x8 block
6582 daala_sse = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, 8, 8,
6583 qm, use_activity_masking, x->qindex)
6584 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006585
Yushin Cho4483e3d2017-04-18 19:41:20 -07006586 daala_dist = av1_daala_dist(src, src_stride, recon_8x8, 8, 8, 8, qm,
6587 use_activity_masking, x->qindex)
6588 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006589
Yushin Cho4483e3d2017-04-18 19:41:20 -07006590 bsi->sse = daala_sse;
6591 bsi->d = daala_dist;
6592
6593 rd1 = RDCOST(x->rdmult, x->rddiv, bsi->r, bsi->d);
6594 rd2 = RDCOST(x->rdmult, x->rddiv, 0, bsi->sse);
6595 bsi->segment_rd = AOMMIN(rd1, rd2);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006596 }
6597#endif // CONFIG_DAALA_DIST
6598
Yaowu Xuc27fc142016-08-22 16:08:15 -07006599 if (bsi->segment_rd > best_rd) return INT64_MAX;
6600 /* set it to the best */
6601 for (idx = 0; idx < 4; idx++) {
6602 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6603 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6604 if (has_second_ref(mbmi))
6605 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006606 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006607 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006608 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006609#if CONFIG_EXT_INTER
6610 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6611 if (has_second_rf)
6612 mi->bmi[idx].ref_mv[1].as_int =
6613 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6614#endif // CONFIG_EXT_INTER
6615 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6616 mi->bmi[idx].as_mode = bsi->modes[idx];
6617 }
6618
6619 /*
6620 * used to set mbmi->mv.as_int
6621 */
6622 *returntotrate = bsi->r;
6623 *returndistortion = bsi->d;
6624 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006625 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006626 *psse = bsi->sse;
6627 mbmi->mode = bsi->modes[3];
6628
6629 return bsi->segment_rd;
6630}
6631
Yaowu Xuf883b422016-08-30 14:01:10 -07006632static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006633 const MACROBLOCKD *xd, int segment_id,
6634 unsigned int *ref_costs_single,
6635 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006636 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006637 int seg_ref_active =
6638 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6639 if (seg_ref_active) {
6640 memset(ref_costs_single, 0,
6641 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6642 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6643 *comp_mode_p = 128;
6644 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006645 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6646 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006647
6648 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006649 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650 *comp_mode_p = comp_inter_p;
6651 } else {
6652 *comp_mode_p = 128;
6653 }
6654
Yaowu Xuf883b422016-08-30 14:01:10 -07006655 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006656
6657 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006658 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6659 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006660#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006661 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6662 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6663 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006664#endif // CONFIG_EXT_REFS
6665
Yaowu Xuf883b422016-08-30 14:01:10 -07006666 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006667
6668 ref_costs_single[LAST_FRAME] =
6669#if CONFIG_EXT_REFS
6670 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6671 ref_costs_single[BWDREF_FRAME] =
6672#endif // CONFIG_EXT_REFS
6673 ref_costs_single[GOLDEN_FRAME] =
6674 ref_costs_single[ALTREF_FRAME] = base_cost;
6675
6676#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006677 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6678 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6679 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6680 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6681 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6682 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006683
Yaowu Xuf883b422016-08-30 14:01:10 -07006684 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6685 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6686 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6687 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006688
Yaowu Xuf883b422016-08-30 14:01:10 -07006689 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6690 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006691
Yaowu Xuf883b422016-08-30 14:01:10 -07006692 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6693 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006694
Yaowu Xuf883b422016-08-30 14:01:10 -07006695 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6696 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006697#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006698 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6699 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6700 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006701
Yaowu Xuf883b422016-08-30 14:01:10 -07006702 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6703 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006704#endif // CONFIG_EXT_REFS
6705 } else {
6706 ref_costs_single[LAST_FRAME] = 512;
6707#if CONFIG_EXT_REFS
6708 ref_costs_single[LAST2_FRAME] = 512;
6709 ref_costs_single[LAST3_FRAME] = 512;
6710 ref_costs_single[BWDREF_FRAME] = 512;
6711#endif // CONFIG_EXT_REFS
6712 ref_costs_single[GOLDEN_FRAME] = 512;
6713 ref_costs_single[ALTREF_FRAME] = 512;
6714 }
6715
6716 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006717 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006718#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006719 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6720 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6721 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006722#endif // CONFIG_EXT_REFS
6723
Yaowu Xuf883b422016-08-30 14:01:10 -07006724 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006725
6726 ref_costs_comp[LAST_FRAME] =
6727#if CONFIG_EXT_REFS
6728 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6729#endif // CONFIG_EXT_REFS
6730 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6731
6732#if CONFIG_EXT_REFS
6733 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6734#endif // CONFIG_EXT_REFS
6735
6736#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006737 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6738 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6739 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6740 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006741
Yaowu Xuf883b422016-08-30 14:01:10 -07006742 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6743 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006744
Yaowu Xuf883b422016-08-30 14:01:10 -07006745 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6746 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006747
6748 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6749 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006750 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6751 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006752#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006753 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6754 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006755#endif // CONFIG_EXT_REFS
6756 } else {
6757 ref_costs_comp[LAST_FRAME] = 512;
6758#if CONFIG_EXT_REFS
6759 ref_costs_comp[LAST2_FRAME] = 512;
6760 ref_costs_comp[LAST3_FRAME] = 512;
6761 ref_costs_comp[BWDREF_FRAME] = 512;
6762 ref_costs_comp[ALTREF_FRAME] = 512;
6763#endif // CONFIG_EXT_REFS
6764 ref_costs_comp[GOLDEN_FRAME] = 512;
6765 }
6766 }
6767}
6768
6769static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6770 int mode_index,
6771 int64_t comp_pred_diff[REFERENCE_MODES],
6772 int skippable) {
6773 MACROBLOCKD *const xd = &x->e_mbd;
6774
6775 // Take a snapshot of the coding context so it can be
6776 // restored if we decide to encode this way
6777 ctx->skip = x->skip;
6778 ctx->skippable = skippable;
6779 ctx->best_mode_index = mode_index;
6780 ctx->mic = *xd->mi[0];
6781 ctx->mbmi_ext = *x->mbmi_ext;
6782 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6783 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6784 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6785}
6786
clang-format55ce9e02017-02-15 22:27:12 -08006787static void setup_buffer_inter(
6788 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6789 BLOCK_SIZE block_size, int mi_row, int mi_col,
6790 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6791 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6792 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006793 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006794 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6795 MACROBLOCKD *const xd = &x->e_mbd;
6796 MODE_INFO *const mi = xd->mi[0];
6797 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6798 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6799 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6800
6801 assert(yv12 != NULL);
6802
6803 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6804 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006805 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006806
6807 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006808 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
6809 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006810#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006811 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006812#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006813 candidates, mi_row, mi_col, NULL, NULL,
6814 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006815
6816 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006817 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6818 &frame_nearest_mv[ref_frame],
6819 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006820
Jingning Han271bb2c2016-12-14 12:34:46 -08006821// Further refinement that is encode side only to test the top few candidates
6822// in full and choose the best as the centre point for subsequent searches.
6823// The current implementation doesn't support scaling.
6824#if CONFIG_CB4X4
6825 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6826 block_size);
6827#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006828 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6829 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6830 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006831#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006832}
6833
Urvang Joshi52648442016-10-13 17:27:51 -07006834static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6835 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006836#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006837 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006838#endif // CONFIG_EXT_INTER
6839 int *rate_mv) {
6840 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006841 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006842 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6843 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6844 int bestsme = INT_MAX;
6845 int step_param;
6846 int sadpb = x->sadperbit16;
6847 MV mvp_full;
6848#if CONFIG_EXT_INTER
6849 int ref = mbmi->ref_frame[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006850#else
6851 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006852 int ref_idx = 0;
6853#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006854 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006855
Alex Converse0fa0f422017-04-24 12:51:14 -07006856 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006857 int cost_list[5];
6858
6859 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006860 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006861
6862 MV pred_mv[3];
6863 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6864 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6865 pred_mv[2] = x->pred_mv[ref];
6866
Yaowu Xuc27fc142016-08-22 16:08:15 -07006867 if (scaled_ref_frame) {
6868 int i;
6869 // Swap out the reference frame for a version that's been scaled to
6870 // match the resolution of the current frame, allowing the existing
6871 // motion search code to be used without additional modifications.
6872 for (i = 0; i < MAX_MB_PLANE; i++)
6873 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6874
Yaowu Xuf883b422016-08-30 14:01:10 -07006875 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006876 }
6877
Alex Converse0fa0f422017-04-24 12:51:14 -07006878 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006879
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006880 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006881
Yaowu Xuc27fc142016-08-22 16:08:15 -07006882 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006883 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006884 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6885 // Take wtd average of the step_params based on the last frame's
6886 // max mv magnitude and that based on the best ref mvs of the current
6887 // block for the given reference.
6888 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006889 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006890 2;
6891 } else {
6892 step_param = cpi->mv_step_param;
6893 }
6894
6895 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6896 int boffset =
6897 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006898 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6899 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006900 }
6901
6902 if (cpi->sf.adaptive_motion_search) {
6903 int bwl = b_width_log2_lookup[bsize];
6904 int bhl = b_height_log2_lookup[bsize];
6905 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6906
6907 if (tlevel < 5) step_param += 2;
6908
6909 // prev_mv_sad is not setup for dynamically scaled frames.
6910 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6911 int i;
6912 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6913 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6914 x->pred_mv[ref].row = 0;
6915 x->pred_mv[ref].col = 0;
6916 x->best_mv.as_int = INVALID_MV;
6917
6918 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006919 int j;
6920 for (j = 0; j < MAX_MB_PLANE; ++j)
6921 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006922 }
6923 return;
6924 }
6925 }
6926 }
6927 }
6928
Alex Converse0fa0f422017-04-24 12:51:14 -07006929 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006930
Yue Chene9638cc2016-10-10 12:37:54 -07006931#if CONFIG_MOTION_VAR
6932 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6933 mvp_full = mbmi->mv[0].as_mv;
6934 else
6935#endif // CONFIG_MOTION_VAR
6936 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006937
6938 mvp_full.col >>= 3;
6939 mvp_full.row >>= 3;
6940
6941 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6942
Yue Chene9638cc2016-10-10 12:37:54 -07006943#if CONFIG_MOTION_VAR
6944 switch (mbmi->motion_mode) {
6945 case SIMPLE_TRANSLATION:
6946#endif // CONFIG_MOTION_VAR
6947 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6948 sadpb, cond_cost_list(cpi, cost_list),
6949 &ref_mv, INT_MAX, 1);
6950#if CONFIG_MOTION_VAR
6951 break;
6952 case OBMC_CAUSAL:
6953 bestsme = av1_obmc_full_pixel_diamond(
6954 cpi, x, &mvp_full, step_param, sadpb,
6955 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6956 &(x->best_mv.as_mv), 0);
6957 break;
6958 default: assert("Invalid motion mode!\n");
6959 }
6960#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006961
Alex Converse0fa0f422017-04-24 12:51:14 -07006962 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006963
6964 if (bestsme < INT_MAX) {
6965 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006966#if CONFIG_MOTION_VAR
6967 switch (mbmi->motion_mode) {
6968 case SIMPLE_TRANSLATION:
6969#endif // CONFIG_MOTION_VAR
6970 if (cpi->sf.use_upsampled_references) {
6971 int best_mv_var;
6972 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6973 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006974 const int pw = block_size_wide[bsize];
6975 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07006976 // Use up-sampled reference frames.
6977 struct macroblockd_plane *const pd = &xd->plane[0];
6978 struct buf_2d backup_pred = pd->pre[ref_idx];
6979 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006980
Yue Chene9638cc2016-10-10 12:37:54 -07006981 // Set pred for Y plane
6982 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006983 &pd->pre[ref_idx], bsize, upsampled_ref->y_buffer,
Yue Chene9638cc2016-10-10 12:37:54 -07006984 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6985 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6986 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006987
Yue Chene9638cc2016-10-10 12:37:54 -07006988 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006989 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6990 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6991 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01006992 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
6993#if CONFIG_EXT_INTER
6994 NULL, 0, 0,
6995#endif
6996 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006997
Yue Chene9638cc2016-10-10 12:37:54 -07006998 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07006999 const int minc =
7000 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
7001 const int maxc =
7002 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
7003 const int minr =
7004 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
7005 const int maxr =
7006 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07007007 int this_var;
7008 MV best_mv = x->best_mv.as_mv;
7009
7010 x->best_mv = x->second_best_mv;
7011 if (x->best_mv.as_mv.row * 8 <= maxr &&
7012 x->best_mv.as_mv.row * 8 >= minr &&
7013 x->best_mv.as_mv.col * 8 <= maxc &&
7014 x->best_mv.as_mv.col * 8 >= minc) {
7015 this_var = cpi->find_fractional_mv_step(
7016 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7017 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7018 cpi->sf.mv.subpel_iters_per_step,
7019 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01007020 &dis, &x->pred_sse[ref], NULL,
7021#if CONFIG_EXT_INTER
7022 NULL, 0, 0,
7023#endif
7024 pw, ph, 1);
Yue Chene9638cc2016-10-10 12:37:54 -07007025 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
7026 x->best_mv.as_mv = best_mv;
7027 }
7028 }
7029
7030 // Restore the reference frames.
7031 pd->pre[ref_idx] = backup_pred;
7032 } else {
7033 cpi->find_fractional_mv_step(
7034 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
7035 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
7036 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01007037 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
7038#if CONFIG_EXT_INTER
7039 NULL, 0, 0,
7040#endif
7041 0, 0, 0);
Yue Chene9638cc2016-10-10 12:37:54 -07007042 }
7043#if CONFIG_MOTION_VAR
7044 break;
7045 case OBMC_CAUSAL:
7046 av1_find_best_obmc_sub_pixel_tree_up(
7047 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
7048 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7049 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7050 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
7051 cpi->sf.use_upsampled_references);
7052 break;
7053 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07007054 }
Yue Chene9638cc2016-10-10 12:37:54 -07007055#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007056 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007057 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
7058 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007059
Yue Chene9638cc2016-10-10 12:37:54 -07007060#if CONFIG_MOTION_VAR
7061 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
7062#else
7063 if (cpi->sf.adaptive_motion_search)
7064#endif // CONFIG_MOTION_VAR
7065 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007066
7067 if (scaled_ref_frame) {
7068 int i;
7069 for (i = 0; i < MAX_MB_PLANE; i++)
7070 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7071 }
7072}
7073
David Barkerac37fa32016-12-02 12:30:21 +00007074static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007075 int i;
7076 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007077 xd->plane[i].dst.buf = dst.plane[i];
7078 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007079 }
7080}
7081
Yaowu Xuc27fc142016-08-22 16:08:15 -07007082#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007083#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Urvang Joshi52648442016-10-13 17:27:51 -07007084static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007085 const uint8_t *mask, int mask_stride,
7086 BLOCK_SIZE bsize, int mi_row, int mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007087 int_mv *tmp_mv, int *rate_mv, int ref_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007088 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007089 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007090 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7091 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7092 int bestsme = INT_MAX;
7093 int step_param;
7094 int sadpb = x->sadperbit16;
7095 MV mvp_full;
7096 int ref = mbmi->ref_frame[ref_idx];
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007097 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007098
Alex Converse0fa0f422017-04-24 12:51:14 -07007099 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007100
7101 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007102 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007103 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007104
7105 MV pred_mv[3];
7106 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7107 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7108 pred_mv[2] = x->pred_mv[ref];
7109
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007110 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007111
7112 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007113 // Swap out the reference frame for a version that's been scaled to
7114 // match the resolution of the current frame, allowing the existing
7115 // motion search code to be used without additional modifications.
7116 for (i = 0; i < MAX_MB_PLANE; i++)
7117 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7118
Yaowu Xuf883b422016-08-30 14:01:10 -07007119 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007120 }
7121
Alex Converse0fa0f422017-04-24 12:51:14 -07007122 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007123
7124 // Work out the size of the first step in the mv step search.
7125 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7126 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7127 // Take wtd average of the step_params based on the last frame's
7128 // max mv magnitude and that based on the best ref mvs of the current
7129 // block for the given reference.
7130 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007131 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007132 2;
7133 } else {
7134 step_param = cpi->mv_step_param;
7135 }
7136
7137 // TODO(debargha): is show_frame needed here?
7138 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7139 int boffset =
7140 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007141 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7142 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007143 }
7144
7145 if (cpi->sf.adaptive_motion_search) {
7146 int bwl = b_width_log2_lookup[bsize];
7147 int bhl = b_height_log2_lookup[bsize];
7148 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7149
7150 if (tlevel < 5) step_param += 2;
7151
7152 // prev_mv_sad is not setup for dynamically scaled frames.
7153 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007154 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7155 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7156 x->pred_mv[ref].row = 0;
7157 x->pred_mv[ref].col = 0;
7158 tmp_mv->as_int = INVALID_MV;
7159
7160 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007161 int j;
7162 for (j = 0; j < MAX_MB_PLANE; ++j)
7163 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007164 }
7165 return;
7166 }
7167 }
7168 }
7169 }
7170
7171 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7172
7173 mvp_full.col >>= 3;
7174 mvp_full.row >>= 3;
7175
Yaowu Xuf883b422016-08-30 14:01:10 -07007176 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007177 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7178 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7179 &tmp_mv->as_mv, ref_idx);
7180
Alex Converse0fa0f422017-04-24 12:51:14 -07007181 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007182
7183 if (bestsme < INT_MAX) {
7184 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007185 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007186 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7187 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7188 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7189 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7190 cpi->sf.use_upsampled_references);
7191 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007192 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7193 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007194
7195 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7196 x->pred_mv[ref] = tmp_mv->as_mv;
7197
7198 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007199 for (i = 0; i < MAX_MB_PLANE; i++)
7200 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7201 }
7202}
7203
Sarah Parker6fdc8532016-11-16 17:47:13 -08007204static void do_masked_motion_search_indexed(
David Barkerc155e012017-05-11 13:54:54 +01007205 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007206 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007207 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007208 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7209 MACROBLOCKD *xd = &x->e_mbd;
7210 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7211 BLOCK_SIZE sb_type = mbmi->sb_type;
7212 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007213 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007214
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007215 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007216
David Barkerc155e012017-05-11 13:54:54 +01007217 if (which == 2) {
7218 int_mv frame_mv[TOTAL_REFS_PER_FRAME];
7219 MV_REFERENCE_FRAME rf[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
7220 assert(bsize >= BLOCK_8X8 || CONFIG_CB4X4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007221
David Barkerc155e012017-05-11 13:54:54 +01007222 frame_mv[rf[0]].as_int = cur_mv[0].as_int;
7223 frame_mv[rf[1]].as_int = cur_mv[1].as_int;
7224 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, mask,
7225 mask_stride, rate_mv, 0);
7226 tmp_mv[0].as_int = frame_mv[rf[0]].as_int;
7227 tmp_mv[1].as_int = frame_mv[rf[1]].as_int;
7228 } else if (which == 0) {
7229 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
7230 &tmp_mv[0], rate_mv, 0);
7231 } else if (which == 1) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007232// get the negative mask
7233#if CONFIG_COMPOUND_SEGMENT
7234 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7235 const int h = block_size_high[bsize];
7236 mask = av1_get_compound_type_mask_inverse(
7237 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7238#else
7239 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
Fergus Simpson4063a682017-02-28 16:52:22 -08007240#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007241 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
David Barkerc155e012017-05-11 13:54:54 +01007242 &tmp_mv[1], rate_mv, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007243 }
7244}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007245#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007246#endif // CONFIG_EXT_INTER
7247
7248// In some situations we want to discount tha pparent cost of a new motion
7249// vector. Where there is a subtle motion field and especially where there is
7250// low spatial complexity then it can be hard to cover the cost of a new motion
7251// vector in a single block, even if that motion vector reduces distortion.
7252// However, once established that vector may be usable through the nearest and
7253// near mv modes to reduce distortion in subsequent blocks and also improve
7254// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007255static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007256 int_mv this_mv,
7257 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7258 int ref_frame) {
7259 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7260 (this_mv.as_int != 0) &&
7261 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7262 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7263 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7264 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7265}
7266
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007267#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7268#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007269
7270// TODO(jingning): this mv clamping function should be block size dependent.
7271static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7272 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7273 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7274 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7275 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7276}
7277
7278#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007279#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007280static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007281 const BLOCK_SIZE bsize, const uint8_t *pred0,
7282 int stride0, const uint8_t *pred1, int stride1) {
7283 const struct macroblock_plane *const p = &x->plane[0];
7284 const uint8_t *src = p->src.buf;
7285 int src_stride = p->src.stride;
7286 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007287 const int bw = block_size_wide[bsize];
7288 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007289 uint32_t esq[2][4], var;
7290 int64_t tl, br;
7291
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007292#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007293 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7294 pred0 = CONVERT_TO_BYTEPTR(pred0);
7295 pred1 = CONVERT_TO_BYTEPTR(pred1);
7296 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007297#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007298
7299 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7300 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7301 stride0, &esq[0][1]);
7302 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7303 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7304 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7305 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7306 &esq[0][3]);
7307 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7308 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7309 stride1, &esq[1][1]);
7310 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7311 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7312 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7313 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7314 &esq[1][3]);
7315 (void)var;
7316
7317 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7318 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7319 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7320 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7321 return (tl + br > 0);
7322}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007323#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007324#endif // CONFIG_EXT_INTER
7325
7326#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007327static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007328 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007329 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007330 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7331 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007332 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007333 const MACROBLOCKD *xd = &x->e_mbd;
7334 int bsl = mi_width_log2_lookup[bsize];
7335 int pred_filter_search =
7336 cpi->sf.cb_pred_filter_search
7337 ? (((mi_row + mi_col) >> bsl) +
7338 get_chessboard_index(cm->current_video_frame)) &
7339 0x1
7340 : 0;
7341 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7342 const int is_comp_pred = has_second_ref(mbmi);
7343 const int this_mode = mbmi->mode;
7344 int refs[2] = { mbmi->ref_frame[0],
7345 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007346 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007347 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007348 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7349 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7350
7351#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007352 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007353#else
7354 if ((this_mode != NEWMV) || (af == lf))
7355#endif // CONFIG_EXT_INTER
7356 best_filter = af;
7357 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007358 if (is_comp_pred) {
7359 if (cpi->sf.adaptive_mode_search) {
7360#if CONFIG_EXT_INTER
7361 switch (this_mode) {
7362 case NEAREST_NEARESTMV:
7363 if (single_filter[NEARESTMV][refs[0]] ==
7364 single_filter[NEARESTMV][refs[1]])
7365 best_filter = single_filter[NEARESTMV][refs[0]];
7366 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007367 case NEAR_NEARMV:
7368 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7369 best_filter = single_filter[NEARMV][refs[0]];
7370 break;
7371 case ZERO_ZEROMV:
7372 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7373 best_filter = single_filter[ZEROMV][refs[0]];
7374 break;
7375 case NEW_NEWMV:
7376 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7377 best_filter = single_filter[NEWMV][refs[0]];
7378 break;
7379 case NEAREST_NEWMV:
7380 if (single_filter[NEARESTMV][refs[0]] ==
7381 single_filter[NEWMV][refs[1]])
7382 best_filter = single_filter[NEARESTMV][refs[0]];
7383 break;
7384 case NEAR_NEWMV:
7385 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7386 best_filter = single_filter[NEARMV][refs[0]];
7387 break;
7388 case NEW_NEARESTMV:
7389 if (single_filter[NEWMV][refs[0]] ==
7390 single_filter[NEARESTMV][refs[1]])
7391 best_filter = single_filter[NEWMV][refs[0]];
7392 break;
7393 case NEW_NEARMV:
7394 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7395 best_filter = single_filter[NEWMV][refs[0]];
7396 break;
7397 default:
7398 if (single_filter[this_mode][refs[0]] ==
7399 single_filter[this_mode][refs[1]])
7400 best_filter = single_filter[this_mode][refs[0]];
7401 break;
7402 }
7403#else
7404 if (single_filter[this_mode][refs[0]] ==
7405 single_filter[this_mode][refs[1]])
7406 best_filter = single_filter[this_mode][refs[0]];
7407#endif // CONFIG_EXT_INTER
7408 }
7409 }
Angie Chiang75c22092016-10-25 12:19:16 -07007410 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7411 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007412 }
7413 return best_filter;
7414}
Fergus Simpson4063a682017-02-28 16:52:22 -08007415#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007416
7417#if CONFIG_EXT_INTER
7418// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007419#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007420static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007421 const BLOCK_SIZE bsize, const uint8_t *const p0,
7422 const uint8_t *const p1, int *const best_wedge_sign,
7423 int *const best_wedge_index) {
7424 const MACROBLOCKD *const xd = &x->e_mbd;
7425 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007426 const int bw = block_size_wide[bsize];
7427 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007428 const int N = bw * bh;
7429 int rate;
7430 int64_t dist;
7431 int64_t rd, best_rd = INT64_MAX;
7432 int wedge_index;
7433 int wedge_sign;
7434 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7435 const uint8_t *mask;
7436 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007437#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007438 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7439 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7440#else
7441 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007442#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007443
7444 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7445 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7446 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7447 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7448
7449 int64_t sign_limit;
7450
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007451#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007452 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007453 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007454 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007455 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007456 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007457 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007458 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7459 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007460#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007461 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007462 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7463 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7464 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007465 }
7466
Yaowu Xuf883b422016-08-30 14:01:10 -07007467 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7468 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007469 (1 << WEDGE_WEIGHT_BITS) / 2;
7470
Jingning Han61418bb2017-01-23 17:12:48 -08007471 if (N < 64)
7472 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7473 else
7474 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007475
7476 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007477 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007478
7479 // TODO(jingning): Make sse2 functions support N = 16 case
7480 if (N < 64)
7481 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7482 else
7483 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007484
Yaowu Xuf883b422016-08-30 14:01:10 -07007485 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007486 if (N < 64)
7487 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7488 else
7489 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007490 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7491
7492 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7493 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7494
7495 if (rd < best_rd) {
7496 *best_wedge_index = wedge_index;
7497 *best_wedge_sign = wedge_sign;
7498 best_rd = rd;
7499 }
7500 }
7501
7502 return best_rd;
7503}
7504
7505// Choose the best wedge index the specified sign
7506static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007507 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007508 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7509 const int wedge_sign, int *const best_wedge_index) {
7510 const MACROBLOCKD *const xd = &x->e_mbd;
7511 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007512 const int bw = block_size_wide[bsize];
7513 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007514 const int N = bw * bh;
7515 int rate;
7516 int64_t dist;
7517 int64_t rd, best_rd = INT64_MAX;
7518 int wedge_index;
7519 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7520 const uint8_t *mask;
7521 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007522#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007523 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7524 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7525#else
7526 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007527#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007528
7529 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7530 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7531
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007532#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007533 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007534 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007535 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007536 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007537 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7538 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007539#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007540 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007541 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7542 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007543 }
7544
7545 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007546 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007547 if (N < 64)
7548 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7549 else
7550 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007551 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7552
7553 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7554 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7555
7556 if (rd < best_rd) {
7557 *best_wedge_index = wedge_index;
7558 best_rd = rd;
7559 }
7560 }
7561
7562 return best_rd;
7563}
7564
Yaowu Xuf883b422016-08-30 14:01:10 -07007565static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007566 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007567 const BLOCK_SIZE bsize,
7568 const uint8_t *const p0,
7569 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007570 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007571 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007572 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007573
7574 int64_t rd;
7575 int wedge_index = -1;
7576 int wedge_sign = 0;
7577
Sarah Parker42d96102017-01-31 21:05:27 -08007578 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007579
7580 if (cpi->sf.fast_wedge_sign_estimate) {
7581 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7582 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7583 } else {
7584 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7585 }
7586
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007587 mbmi->wedge_sign = wedge_sign;
7588 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007589 return rd;
7590}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007591#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007592
Sarah Parker569edda2016-12-14 14:57:38 -08007593#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07007594static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007595 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07007596 const uint8_t *const p0,
7597 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007598 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08007599 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7600 const struct buf_2d *const src = &x->plane[0].src;
7601 const int bw = block_size_wide[bsize];
7602 const int bh = block_size_high[bsize];
7603 const int N = bw * bh;
7604 int rate;
7605 uint64_t sse;
7606 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07007607 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007608 SEG_MASK_TYPE cur_mask_type;
7609 int64_t best_rd = INT64_MAX;
7610 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007611#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007612 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7613 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7614#else
7615 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007616#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007617 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7618 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7619 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7620
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007621#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007622 if (hbd) {
7623 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7624 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7625 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7626 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7627 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7628 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7629 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007630#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007631 {
7632 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7633 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7634 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7635 }
7636
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007637 // try each mask type and its inverse
7638 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007639// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007640#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007641 if (hbd)
7642 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007643 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007644 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7645 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007646#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007647 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
7648 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007649
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007650 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007651 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007652 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007653
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007654 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7655 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007656
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007657 if (rd0 < best_rd) {
7658 best_mask_type = cur_mask_type;
7659 best_rd = rd0;
7660 }
7661 }
Sarah Parker569edda2016-12-14 14:57:38 -08007662
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007663 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007664 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007665#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007666 if (hbd)
7667 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007668 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007669 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7670 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007671#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007672 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
7673 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007674
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007675 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007676}
7677#endif // CONFIG_COMPOUND_SEGMENT
7678
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007679#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07007680static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007681 const MACROBLOCK *const x,
7682 const BLOCK_SIZE bsize,
7683 const uint8_t *const p0,
7684 const uint8_t *const p1) {
7685 const MACROBLOCKD *const xd = &x->e_mbd;
7686 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7687
7688 int64_t rd;
7689 int wedge_index = -1;
7690
7691 assert(is_interintra_wedge_used(bsize));
7692
7693 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7694
7695 mbmi->interintra_wedge_sign = 0;
7696 mbmi->interintra_wedge_index = wedge_index;
7697 return rd;
7698}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007699#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08007700
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007701#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007702static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07007703 const BLOCK_SIZE bsize,
7704 const uint8_t *const p0,
7705 const uint8_t *const p1) {
7706 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007707 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07007708 switch (compound_type) {
7709#if CONFIG_WEDGE
7710 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
7711#endif // CONFIG_WEDGE
7712#if CONFIG_COMPOUND_SEGMENT
7713 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
7714#endif // CONFIG_COMPOUND_SEGMENT
7715 default: assert(0); return 0;
7716 }
7717}
7718
David Barkerc155e012017-05-11 13:54:54 +01007719static int interinter_compound_motion_search(
7720 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7721 const BLOCK_SIZE bsize, const int this_mode, int mi_row, int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007722 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007723 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7724 int_mv tmp_mv[2];
David Barkerc155e012017-05-11 13:54:54 +01007725 int tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007726 const INTERINTER_COMPOUND_DATA compound_data = {
7727#if CONFIG_WEDGE
7728 mbmi->wedge_index,
7729 mbmi->wedge_sign,
7730#endif // CONFIG_WEDGE
7731#if CONFIG_COMPOUND_SEGMENT
7732 mbmi->mask_type,
7733 xd->seg_mask,
7734#endif // CONFIG_COMPOUND_SEGMENT
7735 mbmi->interinter_compound_type
7736 };
Sarah Parker6fdc8532016-11-16 17:47:13 -08007737 if (this_mode == NEW_NEWMV) {
David Barkerc155e012017-05-11 13:54:54 +01007738 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7739 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007740 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7741 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7742 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
David Barkerc155e012017-05-11 13:54:54 +01007743 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7744 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007745 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7746 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
David Barkerc155e012017-05-11 13:54:54 +01007747 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7748 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007749 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7750 }
7751 return tmp_rate_mv;
7752}
7753
Sarah Parkerddcea392017-04-25 15:57:22 -07007754static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007755 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7756 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7757 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7758 int *strides, int mi_row, int mi_col) {
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007759 const AV1_COMMON *const cm = &cpi->common;
Sarah Parker569edda2016-12-14 14:57:38 -08007760 MACROBLOCKD *xd = &x->e_mbd;
7761 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7762 int rate_sum;
7763 int64_t dist_sum;
7764 int64_t best_rd_cur = INT64_MAX;
7765 int64_t rd = INT64_MAX;
7766 int tmp_skip_txfm_sb;
7767 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007768 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08007769
Sarah Parkerddcea392017-04-25 15:57:22 -07007770 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Sarah Parker569edda2016-12-14 14:57:38 -08007771 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7772
Sarah Parker2e604882017-01-17 17:31:25 -08007773 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07007774 use_masked_motion_search(compound_type)) {
David Barkerc155e012017-05-11 13:54:54 +01007775 *out_rate_mv = interinter_compound_motion_search(cpi, x, cur_mv, bsize,
7776 this_mode, mi_row, mi_col);
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007777 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007778 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7779 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7780 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007781 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007782 mbmi->mv[0].as_int = cur_mv[0].as_int;
7783 mbmi->mv[1].as_int = cur_mv[1].as_int;
7784 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007785 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7786#if CONFIG_SUPERTX
7787 0, 0,
7788#endif // CONFIG_SUPERTX
7789 preds0, strides, preds1,
7790 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007791 }
7792 av1_subtract_plane(x, bsize, 0);
7793 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7794 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7795 if (rd != INT64_MAX)
7796 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7797 best_rd_cur = rd;
7798
7799 } else {
David Barker426a9972017-01-27 11:03:11 +00007800 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7801#if CONFIG_SUPERTX
7802 0, 0,
7803#endif // CONFIG_SUPERTX
7804 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007805 av1_subtract_plane(x, bsize, 0);
7806 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7807 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7808 if (rd != INT64_MAX)
7809 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7810 best_rd_cur = rd;
7811 }
7812 return best_rd_cur;
7813}
Sarah Parkerddcea392017-04-25 15:57:22 -07007814#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007815#endif // CONFIG_EXT_INTER
7816
Fergus Simpson073c6f32017-02-17 12:13:48 -08007817typedef struct {
7818#if CONFIG_MOTION_VAR
7819 // Inter prediction buffers and respective strides
7820 uint8_t *above_pred_buf[MAX_MB_PLANE];
7821 int above_pred_stride[MAX_MB_PLANE];
7822 uint8_t *left_pred_buf[MAX_MB_PLANE];
7823 int left_pred_stride[MAX_MB_PLANE];
7824#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007825 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007826#if CONFIG_EXT_INTER
7827 // Pointer to array of motion vectors to use for each ref and their rates
7828 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007829 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007830 // Pointers costs of compound inter-intra and inter-inter predictions
7831 int *compmode_interintra_cost;
7832 int *compmode_interinter_cost;
7833 // Pointer to array of predicted rate-distortion
7834 // Should point to first of 2 arrays in 2D array
7835 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007836#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007837 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007838} HandleInterModeArgs;
7839
Fergus Simpson45509632017-02-22 15:30:50 -08007840static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7841 const BLOCK_SIZE bsize,
7842 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
7843 const int mi_row, const int mi_col,
7844 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007845 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007846 const MACROBLOCKD *const xd = &x->e_mbd;
7847 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7848 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7849 const int is_comp_pred = has_second_ref(mbmi);
7850 const PREDICTION_MODE this_mode = mbmi->mode;
7851#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007852 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7853#endif // CONFIG_EXT_INTER
7854 int_mv *const frame_mv = mode_mv[this_mode];
7855 const int refs[2] = { mbmi->ref_frame[0],
7856 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7857 int i;
7858
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007859 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007860
7861 if (is_comp_pred) {
7862#if CONFIG_EXT_INTER
7863 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007864 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007865 }
7866
7867 if (this_mode == NEW_NEWMV) {
7868 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7869 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7870
7871 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
David Barkerc155e012017-05-11 13:54:54 +01007872 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, NULL,
7873 0, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007874 } else {
7875 *rate_mv = 0;
7876 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007877 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007878 *rate_mv += av1_mv_bit_cost(
7879 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7880 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7881 }
7882 }
7883 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7884 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007885 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007886 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
7887 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
7888 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7889 } else {
David Barkercb03dc32017-04-07 13:05:09 +01007890 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08007891 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007892 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007893 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7894 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7895 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7896 }
7897#else
7898 // Initialize mv using single prediction mode result.
7899 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7900 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7901
7902 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07007903 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007904 } else {
7905 *rate_mv = 0;
7906 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007907 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007908 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
7909 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7910 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7911 }
7912 }
7913#endif // CONFIG_EXT_INTER
7914 } else {
7915#if CONFIG_EXT_INTER
7916 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007917 x->best_mv = args->single_newmv[refs[0]];
7918 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08007919 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007920 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
7921 args->single_newmv[refs[0]] = x->best_mv;
7922 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08007923 }
7924#else
7925 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
7926 single_newmv[refs[0]] = x->best_mv;
7927#endif // CONFIG_EXT_INTER
7928
7929 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7930
7931 frame_mv[refs[0]] = x->best_mv;
7932 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7933
7934 // Estimate the rate implications of a new mv but discount this
7935 // under certain circumstances where we want to help initiate a weak
7936 // motion field, where the distortion gain for a single block may not
7937 // be enough to overcome the cost of a new mv.
7938 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
7939 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
7940 }
7941 }
7942
7943 return 0;
7944}
7945
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007946int64_t interpolation_filter_search(
7947 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
7948 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
7949 BUFFER_SET *const orig_dst,
7950 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
7951 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
7952 int64_t *const skip_sse_sb) {
7953 const AV1_COMMON *cm = &cpi->common;
7954 MACROBLOCKD *const xd = &x->e_mbd;
7955 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7956 int i;
7957 int tmp_rate;
7958 int64_t tmp_dist;
7959
7960 (void)single_filter;
7961
7962 InterpFilter assign_filter = SWITCHABLE;
7963
7964 if (cm->interp_filter == SWITCHABLE) {
7965#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007966 assign_filter = av1_is_interp_needed(xd)
7967 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
7968 single_filter)
7969 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007970#endif // !CONFIG_DUAL_FILTER
7971 } else {
7972 assign_filter = cm->interp_filter;
7973 }
7974
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007975 set_default_interp_filters(mbmi, assign_filter);
7976
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007977 *switchable_rate = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007978 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007979 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
7980 skip_txfm_sb, skip_sse_sb);
7981 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
7982
7983 if (assign_filter == SWITCHABLE) {
7984 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007985 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007986#if CONFIG_DUAL_FILTER
7987 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7988#else
7989 const int filter_set_size = SWITCHABLE_FILTERS;
7990#endif // CONFIG_DUAL_FILTER
7991 int best_in_temp = 0;
7992#if CONFIG_DUAL_FILTER
7993 InterpFilter best_filter[4];
7994 av1_copy(best_filter, mbmi->interp_filter);
7995#else
7996 InterpFilter best_filter = mbmi->interp_filter;
7997#endif // CONFIG_DUAL_FILTER
7998 restore_dst_buf(xd, *tmp_dst);
7999 // EIGHTTAP_REGULAR mode is calculated beforehand
8000 for (i = 1; i < filter_set_size; ++i) {
8001 int tmp_skip_sb = 0;
8002 int64_t tmp_skip_sse = INT64_MAX;
8003 int tmp_rs;
8004 int64_t tmp_rd;
8005#if CONFIG_DUAL_FILTER
8006 mbmi->interp_filter[0] = filter_sets[i][0];
8007 mbmi->interp_filter[1] = filter_sets[i][1];
8008 mbmi->interp_filter[2] = filter_sets[i][0];
8009 mbmi->interp_filter[3] = filter_sets[i][1];
8010#else
8011 mbmi->interp_filter = (InterpFilter)i;
8012#endif // CONFIG_DUAL_FILTER
8013 tmp_rs = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07008014 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008015 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8016 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
8017 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
8018
8019 if (tmp_rd < *rd) {
8020 *rd = tmp_rd;
8021 *switchable_rate = av1_get_switchable_rate(cpi, xd);
8022#if CONFIG_DUAL_FILTER
8023 av1_copy(best_filter, mbmi->interp_filter);
8024#else
8025 best_filter = mbmi->interp_filter;
8026#endif // CONFIG_DUAL_FILTER
8027 *skip_txfm_sb = tmp_skip_sb;
8028 *skip_sse_sb = tmp_skip_sse;
8029 best_in_temp = !best_in_temp;
8030 if (best_in_temp) {
8031 restore_dst_buf(xd, *orig_dst);
8032 } else {
8033 restore_dst_buf(xd, *tmp_dst);
8034 }
8035 }
8036 }
8037 if (best_in_temp) {
8038 restore_dst_buf(xd, *tmp_dst);
8039 } else {
8040 restore_dst_buf(xd, *orig_dst);
8041 }
8042#if CONFIG_DUAL_FILTER
8043 av1_copy(mbmi->interp_filter, best_filter);
8044#else
8045 mbmi->interp_filter = best_filter;
8046#endif // CONFIG_DUAL_FILTER
8047 } else {
8048#if CONFIG_DUAL_FILTER
8049 for (i = 0; i < 4; ++i)
8050 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
8051#else
8052 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
8053#endif // CONFIG_DUAL_FILTER
8054 }
8055 }
8056
8057 return 0;
8058}
8059
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008060// TODO(afergs): Refactor the MBMI references in here - there's four
8061// TODO(afergs): Refactor optional args - add them to a struct or remove
8062static int64_t motion_mode_rd(
8063 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
8064 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8065 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
8066 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
8067 const int *refs, int rate_mv,
8068#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8069#if CONFIG_EXT_INTER
8070 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
8071#if CONFIG_MOTION_VAR
8072 int rate_mv_bmc,
8073#endif // CONFIG_MOTION_VAR
8074#endif // CONFIG_EXT_INTER
8075#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8076 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
8077 const AV1_COMMON *const cm = &cpi->common;
8078 MACROBLOCKD *xd = &x->e_mbd;
8079 MODE_INFO *mi = xd->mi[0];
8080 MB_MODE_INFO *mbmi = &mi->mbmi;
8081 const int is_comp_pred = has_second_ref(mbmi);
8082 const PREDICTION_MODE this_mode = mbmi->mode;
8083
8084 (void)mode_mv;
8085 (void)mi_row;
8086 (void)mi_col;
8087 (void)args;
8088 (void)refs;
8089 (void)rate_mv;
8090 (void)is_comp_pred;
8091 (void)this_mode;
8092
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008093#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8094 MOTION_MODE motion_mode, last_motion_mode_allowed;
8095 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
8096 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
8097 MB_MODE_INFO base_mbmi, best_mbmi;
8098#if CONFIG_VAR_TX
8099 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
8100#endif // CONFIG_VAR_TX
8101#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8102
8103#if CONFIG_WARPED_MOTION
8104 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
8105#endif // CONFIG_WARPED_MOTION
8106
8107#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8108 av1_invalid_rd_stats(&best_rd_stats);
8109#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8110
8111 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
8112#if CONFIG_WARPED_MOTION
8113 aom_clear_system_state();
8114 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
8115#if CONFIG_EXT_INTER
8116 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
8117#endif // CONFIG_EXT_INTER
8118#endif // CONFIG_WARPED_MOTION
8119#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8120 rate2_nocoeff = rd_stats->rate;
8121 last_motion_mode_allowed = motion_mode_allowed(
8122#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8123 0, xd->global_motion,
8124#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8125 mi);
8126 base_mbmi = *mbmi;
8127#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8128
8129#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8130 int64_t best_rd = INT64_MAX;
8131 for (motion_mode = SIMPLE_TRANSLATION;
8132 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8133 int64_t tmp_rd = INT64_MAX;
8134 int tmp_rate;
8135 int64_t tmp_dist;
8136#if CONFIG_EXT_INTER
8137 int tmp_rate2 =
8138 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
8139#else
8140 int tmp_rate2 = rate2_nocoeff;
8141#endif // CONFIG_EXT_INTER
8142
8143 *mbmi = base_mbmi;
8144 mbmi->motion_mode = motion_mode;
8145#if CONFIG_MOTION_VAR
8146 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008147#if CONFIG_EXT_INTER
8148 *mbmi = *best_bmc_mbmi;
8149 mbmi->motion_mode = OBMC_CAUSAL;
8150#endif // CONFIG_EXT_INTER
8151 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
8152 int tmp_rate_mv = 0;
8153
8154 single_motion_search(cpi, x, bsize, mi_row, mi_col,
8155#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07008156 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008157#endif // CONFIG_EXT_INTER
8158 &tmp_rate_mv);
8159 mbmi->mv[0].as_int = x->best_mv.as_int;
8160 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8161 refs[0])) {
8162 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
8163 }
8164#if CONFIG_EXT_INTER
8165 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8166#else
8167 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8168#endif // CONFIG_EXT_INTER
8169#if CONFIG_DUAL_FILTER
8170 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
8171 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
8172 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
8173 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
8174#endif // CONFIG_DUAL_FILTER
Jingning Hanc44009c2017-05-06 11:36:49 -07008175 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008176#if CONFIG_EXT_INTER
8177 } else {
Jingning Hanc44009c2017-05-06 11:36:49 -07008178 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008179#endif // CONFIG_EXT_INTER
8180 }
8181 av1_build_obmc_inter_prediction(
8182 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
8183 args->left_pred_buf, args->left_pred_stride);
8184 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8185 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8186 }
8187#endif // CONFIG_MOTION_VAR
8188
8189#if CONFIG_WARPED_MOTION
8190 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008191#if CONFIG_EXT_INTER
8192 *mbmi = *best_bmc_mbmi;
8193 mbmi->motion_mode = WARPED_CAUSAL;
8194#endif // CONFIG_EXT_INTER
8195 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8196#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07008197 for (int dir = 0; dir < 4; ++dir)
8198 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
8199 ? EIGHTTAP_REGULAR
8200 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008201#else
8202 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8203 : cm->interp_filter;
8204#endif // CONFIG_DUAL_FILTER
8205
Debargha Mukherjeee8e6cad2017-03-22 17:38:38 -07008206 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
8207 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008208 &mbmi->wm_params[0], mi_row, mi_col) == 0) {
Jingning Hanc44009c2017-05-06 11:36:49 -07008209 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008210 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8211 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8212 } else {
8213 continue;
8214 }
8215 }
8216#endif // CONFIG_WARPED_MOTION
8217 x->skip = 0;
8218
8219 rd_stats->dist = 0;
8220 rd_stats->sse = 0;
8221 rd_stats->skip = 1;
8222 rd_stats->rate = tmp_rate2;
8223 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8224#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8225 if (last_motion_mode_allowed == WARPED_CAUSAL)
8226#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8227 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8228#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8229 else
8230 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8231#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8232 }
8233#if CONFIG_WARPED_MOTION
8234 if (mbmi->motion_mode == WARPED_CAUSAL) {
8235 rd_stats->rate -= rs;
8236 }
8237#endif // CONFIG_WARPED_MOTION
8238#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8239 if (!*skip_txfm_sb) {
8240 int64_t rdcosty = INT64_MAX;
8241 int is_cost_valid_uv = 0;
8242
8243 // cost and distortion
8244 av1_subtract_plane(x, bsize, 0);
8245#if CONFIG_VAR_TX
8246 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8247 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8248 } else {
8249 int idx, idy;
8250 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8251 for (idy = 0; idy < xd->n8_h; ++idy)
8252 for (idx = 0; idx < xd->n8_w; ++idx)
8253 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8254 memset(x->blk_skip[0], rd_stats_y->skip,
8255 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8256 }
8257#else
8258 /* clang-format off */
8259 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8260/* clang-format on */
8261#endif // CONFIG_VAR_TX
8262
8263 if (rd_stats_y->rate == INT_MAX) {
8264 av1_invalid_rd_stats(rd_stats);
8265#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8266 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8267 continue;
8268 } else {
8269#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8270 restore_dst_buf(xd, *orig_dst);
8271 return INT64_MAX;
8272#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8273 }
8274#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8275 }
8276
8277 av1_merge_rd_stats(rd_stats, rd_stats_y);
8278
8279 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8280 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
8281/* clang-format off */
8282#if CONFIG_VAR_TX
8283 is_cost_valid_uv =
8284 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8285#else
8286 is_cost_valid_uv =
8287 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8288#endif // CONFIG_VAR_TX
8289 if (!is_cost_valid_uv) {
8290#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8291 continue;
8292#else
8293 restore_dst_buf(xd, *orig_dst);
8294 return INT64_MAX;
8295#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8296 }
8297 /* clang-format on */
8298 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8299#if CONFIG_RD_DEBUG
8300 // record transform block coefficient cost
8301 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8302 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8303 // here because we already collect the coefficient cost. Move this part to
8304 // other place when we need to compare non-coefficient cost.
8305 mbmi->rd_stats = *rd_stats;
8306#endif // CONFIG_RD_DEBUG
8307#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8308 if (rd_stats->skip) {
8309 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8310 rd_stats_y->rate = 0;
8311 rd_stats_uv->rate = 0;
8312 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8313 mbmi->skip = 0;
8314 // here mbmi->skip temporarily plays a role as what this_skip2 does
8315 } else if (!xd->lossless[mbmi->segment_id] &&
8316 (RDCOST(x->rdmult, x->rddiv,
8317 rd_stats_y->rate + rd_stats_uv->rate +
8318 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8319 rd_stats->dist) >=
8320 RDCOST(x->rdmult, x->rddiv,
8321 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8322 rd_stats->sse))) {
8323 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8324 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8325 rd_stats->dist = rd_stats->sse;
8326 rd_stats_y->rate = 0;
8327 rd_stats_uv->rate = 0;
8328 mbmi->skip = 1;
8329 } else {
8330 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8331 mbmi->skip = 0;
8332 }
8333 *disable_skip = 0;
8334#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8335 } else {
8336 x->skip = 1;
8337 *disable_skip = 1;
8338 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8339
8340// The cost of skip bit needs to be added.
8341#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8342 mbmi->skip = 0;
8343#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8344 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8345
8346 rd_stats->dist = *skip_sse_sb;
8347 rd_stats->sse = *skip_sse_sb;
8348 rd_stats_y->rate = 0;
8349 rd_stats_uv->rate = 0;
8350 rd_stats->skip = 1;
8351 }
8352
8353#if CONFIG_GLOBAL_MOTION
8354 if (this_mode == ZEROMV
8355#if CONFIG_EXT_INTER
8356 || this_mode == ZERO_ZEROMV
8357#endif // CONFIG_EXT_INTER
8358 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008359 if (is_nontrans_global_motion(xd)) {
8360 rd_stats->rate -= rs;
8361#if CONFIG_DUAL_FILTER
8362 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8363 ? EIGHTTAP_REGULAR
8364 : cm->interp_filter;
8365 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8366 ? EIGHTTAP_REGULAR
8367 : cm->interp_filter;
8368#else
8369 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8370 ? EIGHTTAP_REGULAR
8371 : cm->interp_filter;
8372#endif // CONFIG_DUAL_FILTER
8373 }
8374 }
8375#endif // CONFIG_GLOBAL_MOTION
8376
8377#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8378 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8379 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8380 best_mbmi = *mbmi;
8381 best_rd = tmp_rd;
8382 best_rd_stats = *rd_stats;
8383 best_rd_stats_y = *rd_stats_y;
8384 best_rd_stats_uv = *rd_stats_uv;
8385#if CONFIG_VAR_TX
8386 for (int i = 0; i < MAX_MB_PLANE; ++i)
8387 memcpy(best_blk_skip[i], x->blk_skip[i],
8388 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8389#endif // CONFIG_VAR_TX
8390 best_xskip = x->skip;
8391 best_disable_skip = *disable_skip;
8392 }
8393 }
8394
8395 if (best_rd == INT64_MAX) {
8396 av1_invalid_rd_stats(rd_stats);
8397 restore_dst_buf(xd, *orig_dst);
8398 return INT64_MAX;
8399 }
8400 *mbmi = best_mbmi;
8401 *rd_stats = best_rd_stats;
8402 *rd_stats_y = best_rd_stats_y;
8403 *rd_stats_uv = best_rd_stats_uv;
8404#if CONFIG_VAR_TX
8405 for (int i = 0; i < MAX_MB_PLANE; ++i)
8406 memcpy(x->blk_skip[i], best_blk_skip[i],
8407 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8408#endif // CONFIG_VAR_TX
8409 x->skip = best_xskip;
8410 *disable_skip = best_disable_skip;
8411#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8412
8413 restore_dst_buf(xd, *orig_dst);
8414 return 0;
8415}
8416
Yaowu Xuc27fc142016-08-22 16:08:15 -07008417static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08008418 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
8419 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008420 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008421 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008422 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008423 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008424 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008425 MODE_INFO *mi = xd->mi[0];
8426 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008427 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8428 const int is_comp_pred = has_second_ref(mbmi);
8429 const int this_mode = mbmi->mode;
8430 int_mv *frame_mv = mode_mv[this_mode];
8431 int i;
8432 int refs[2] = { mbmi->ref_frame[0],
8433 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8434 int_mv cur_mv[2];
8435 int rate_mv = 0;
8436#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008437 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008438 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008439 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008440#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008441 const unsigned int *const interintra_mode_cost =
8442 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008443#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008444 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07008445 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008446#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008447 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008448#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008449#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008450 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8451#else
8452 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008453#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008454 uint8_t *tmp_buf;
8455
Yue Chencb60b182016-10-13 15:18:22 -07008456#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008457#if CONFIG_EXT_INTER
8458 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008459 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008460#if CONFIG_MOTION_VAR
8461 int rate_mv_bmc;
8462#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008463#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008464#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008465 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008466 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008468
8469 int skip_txfm_sb = 0;
8470 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008471 int16_t mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008472
8473#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008474 *args->compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008475 mbmi->use_wedge_interintra = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008476 *args->compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008477 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008478
8479 // is_comp_interintra_pred implies !is_comp_pred
8480 assert(!is_comp_interintra_pred || (!is_comp_pred));
8481 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8482 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8483#endif // CONFIG_EXT_INTER
8484
Yaowu Xuc27fc142016-08-22 16:08:15 -07008485#if CONFIG_EXT_INTER
8486 if (is_comp_pred)
8487 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8488 else
8489#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008490 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8491 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008492
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008493#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008494 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8495 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8496 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008497#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008498 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008499 // Make sure that we didn't leave the plane destination buffers set
8500 // to tmp_buf at the end of the last iteration
8501 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008502
Yue Chen69f18e12016-09-08 14:48:15 -07008503#if CONFIG_WARPED_MOTION
8504 mbmi->num_proj_ref[0] = 0;
8505 mbmi->num_proj_ref[1] = 0;
8506#endif // CONFIG_WARPED_MOTION
8507
Yaowu Xuc27fc142016-08-22 16:08:15 -07008508 if (is_comp_pred) {
8509 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8510 frame_mv[refs[1]].as_int == INVALID_MV)
8511 return INT64_MAX;
8512 }
8513
Yue Chene9638cc2016-10-10 12:37:54 -07008514 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008515 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08008516 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008517 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008518 if (ret_val != 0)
8519 return ret_val;
8520 else
8521 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008522 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008523 for (i = 0; i < is_comp_pred + 1; ++i) {
8524 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07008525 // Clip "next_nearest" so that it does not extend to far out of image
8526 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008527 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008528 mbmi->mv[i].as_int = cur_mv[i].as_int;
8529 }
8530
Yaowu Xuc27fc142016-08-22 16:08:15 -07008531#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008532 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008533#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008534 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008535#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008536 {
8537#if !CONFIG_EXT_INTER
8538 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008539#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008540 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8541 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8542 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8543
8544 for (i = 0; i < 2; ++i) {
8545 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008546 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008547 mbmi->mv[i].as_int = cur_mv[i].as_int;
8548 }
8549 }
8550 }
8551
8552#if CONFIG_EXT_INTER
8553 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008554 if (this_mode == NEAREST_NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008555 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8556
8557 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8558 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008559 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008560 mbmi->mv[0].as_int = cur_mv[0].as_int;
8561 }
8562
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008563 if (this_mode == NEW_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008564 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8565
8566 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8567 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008568 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008569 mbmi->mv[1].as_int = cur_mv[1].as_int;
8570 }
8571 }
8572
8573 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01008574 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008575 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008576 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008577
8578 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8579 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008580 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008581 mbmi->mv[0].as_int = cur_mv[0].as_int;
8582 }
8583
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008584 if (this_mode == NEW_NEARMV || this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008585 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008586
8587 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8588 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008589 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008590 mbmi->mv[1].as_int = cur_mv[1].as_int;
8591 }
8592 }
8593#else
8594 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008595 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008596 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8597 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8598 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8599 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8600
8601 for (i = 0; i < 2; ++i) {
8602 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008603 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008604 mbmi->mv[i].as_int = cur_mv[i].as_int;
8605 }
8606 }
8607 }
8608#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008609
8610 // do first prediction into the destination buffer. Do the next
8611 // prediction into a temporary buffer. Then keep track of which one
8612 // of these currently holds the best predictor, and use the other
8613 // one for future predictions. In the end, copy from tmp_buf to
8614 // dst if necessary.
8615 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008616 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8617 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008618 }
8619 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008620 orig_dst.plane[i] = xd->plane[i].dst.buf;
8621 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008622 }
8623
8624 // We don't include the cost of the second reference here, because there
8625 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8626 // words if you present them in that order, the second one is always known
8627 // if the first is known.
8628 //
8629 // Under some circumstances we discount the cost of new mv mode to encourage
8630 // initiation of a motion field.
8631 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8632 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01008633#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008634 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01008635 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8636 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
8637 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008638#else
Angie Chiang76159122016-11-09 12:13:22 -08008639 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8640 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008641#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008642 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008643 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008644 }
8645
Angie Chiang76159122016-11-09 12:13:22 -08008646 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008647#if CONFIG_EXT_INTER
8648 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8649#else
8650 mbmi->mode != NEARESTMV
8651#endif // CONFIG_EXT_INTER
8652 )
8653 return INT64_MAX;
8654
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008655 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008656 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8657 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008658 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008659
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008661#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008662 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008663 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008664 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008665#if CONFIG_MOTION_VAR
8666 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008667#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008668#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008669
Sarah Parker6fdc8532016-11-16 17:47:13 -08008670 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008671 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008672 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008673 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8674 INTERINTER_COMPOUND_DATA best_compound_data;
8675 int_mv best_mv[2];
8676 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008677 int tmp_skip_txfm_sb;
8678 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07008679 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008680 uint8_t pred0[2 * MAX_SB_SQUARE];
8681 uint8_t pred1[2 * MAX_SB_SQUARE];
8682 uint8_t *preds0[1] = { pred0 };
8683 uint8_t *preds1[1] = { pred1 };
8684 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008685 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008686 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008687 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008688
Sarah Parker6fdc8532016-11-16 17:47:13 -08008689 best_mv[0].as_int = cur_mv[0].as_int;
8690 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008691 memset(&best_compound_data, 0, sizeof(best_compound_data));
8692#if CONFIG_COMPOUND_SEGMENT
8693 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
8694 best_compound_data.seg_mask = tmp_mask_buf;
8695#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008696
Sarah Parker42d96102017-01-31 21:05:27 -08008697 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07008698 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8699 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008700 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008701 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008702 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008703 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008704 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008705 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008706
Sarah Parker6fdc8532016-11-16 17:47:13 -08008707 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008708 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008709 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008710 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008711 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008712 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008713 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008714 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008715 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08008716 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008717
Sarah Parker6fdc8532016-11-16 17:47:13 -08008718 switch (cur_type) {
8719 case COMPOUND_AVERAGE:
Jingning Hanc44009c2017-05-06 11:36:49 -07008720 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8721 bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008722 av1_subtract_plane(x, bsize, 0);
8723 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8724 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8725 INT64_MAX);
8726 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008727 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008728 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008729 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008730 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008731#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008732 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008733 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8734 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008735 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00008736 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8737 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008738 }
8739 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008740#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08008741#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008742 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008743 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8744 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008745 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08008746 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8747 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008748 }
8749 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008750#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008751 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008752 }
Sarah Parker2e604882017-01-17 17:31:25 -08008753
8754 if (best_rd_cur < best_rd_compound) {
8755 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008756#if CONFIG_WEDGE
8757 best_compound_data.wedge_index = mbmi->wedge_index;
8758 best_compound_data.wedge_sign = mbmi->wedge_sign;
8759#endif // CONFIG_WEDGE
8760#if CONFIG_COMPOUND_SEGMENT
8761 best_compound_data.mask_type = mbmi->mask_type;
8762 memcpy(best_compound_data.seg_mask, xd->seg_mask,
8763 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8764#endif // CONFIG_COMPOUND_SEGMENT
8765 best_compound_data.interinter_compound_type =
8766 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08008767 if (have_newmv_in_inter_mode(this_mode)) {
8768 if (use_masked_motion_search(cur_type)) {
8769 best_tmp_rate_mv = tmp_rate_mv;
8770 best_mv[0].as_int = mbmi->mv[0].as_int;
8771 best_mv[1].as_int = mbmi->mv[1].as_int;
8772 } else {
8773 best_mv[0].as_int = cur_mv[0].as_int;
8774 best_mv[1].as_int = cur_mv[1].as_int;
8775 }
8776 }
8777 }
8778 // reset to original mvs for next iteration
8779 mbmi->mv[0].as_int = cur_mv[0].as_int;
8780 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008782#if CONFIG_WEDGE
8783 mbmi->wedge_index = best_compound_data.wedge_index;
8784 mbmi->wedge_sign = best_compound_data.wedge_sign;
8785#endif // CONFIG_WEDGE
8786#if CONFIG_COMPOUND_SEGMENT
8787 mbmi->mask_type = best_compound_data.mask_type;
8788 memcpy(xd->seg_mask, best_compound_data.seg_mask,
8789 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8790#endif // CONFIG_COMPOUND_SEGMENT
8791 mbmi->interinter_compound_type =
8792 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008793 if (have_newmv_in_inter_mode(this_mode)) {
8794 mbmi->mv[0].as_int = best_mv[0].as_int;
8795 mbmi->mv[1].as_int = best_mv[1].as_int;
8796 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8797 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008798 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008799 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8800 rate_mv = best_tmp_rate_mv;
8801 }
8802 }
8803
8804 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008805 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008806 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008807 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008808
8809 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008810
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008811 *args->compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008812 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008813 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01008814 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008815 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01008816 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008817 }
8818
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008819#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008820 if (is_comp_interintra_pred) {
8821 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8822 int64_t best_interintra_rd = INT64_MAX;
8823 int rmode, rate_sum;
8824 int64_t dist_sum;
8825 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008826 int tmp_rate_mv = 0;
8827 int tmp_skip_txfm_sb;
8828 int64_t tmp_skip_sse_sb;
8829 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8830 uint8_t *intrapred;
8831
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008832#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008833 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8834 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8835 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008836#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008837 intrapred = intrapred_;
8838
Emil Keyder01770b32017-01-20 18:03:11 -05008839 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840 for (j = 0; j < MAX_MB_PLANE; j++) {
8841 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8842 xd->plane[j].dst.stride = bw;
8843 }
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008844 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst, bsize);
David Barkerac37fa32016-12-02 12:30:21 +00008845 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008846 mbmi->ref_frame[1] = INTRA_FRAME;
8847 mbmi->use_wedge_interintra = 0;
8848
8849 for (j = 0; j < INTERINTRA_MODES; ++j) {
8850 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8851 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008852 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8853 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008854 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008855 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8856 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8857 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
8858 if (rd < best_interintra_rd) {
8859 best_interintra_rd = rd;
8860 best_interintra_mode = mbmi->interintra_mode;
8861 }
8862 }
8863 mbmi->interintra_mode = best_interintra_mode;
8864 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008865 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8866 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008867 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8868 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008869 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8870 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8871 if (rd != INT64_MAX)
8872 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
8873 best_interintra_rd = rd;
8874
8875 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008876 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008877 return INT64_MAX;
8878 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008879#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008880 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008881 int64_t best_interintra_rd_nowedge = INT64_MAX;
8882 int64_t best_interintra_rd_wedge = INT64_MAX;
8883 int_mv tmp_mv;
8884 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008885 if (rd != INT64_MAX)
8886 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
8887 dist_sum);
8888 best_interintra_rd_nowedge = rd;
8889
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008890 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07008891 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8892 mbmi->use_wedge_interintra = 1;
8893
Yaowu Xuf883b422016-08-30 14:01:10 -07008894 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8895 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008896
8897 best_interintra_rd_wedge =
8898 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8899
8900 best_interintra_rd_wedge +=
8901 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
8902 // Refine motion vector.
8903 if (have_newmv_in_inter_mode(this_mode)) {
8904 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008905 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008906 mbmi->interintra_wedge_index, 1, bsize);
8907 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07008908 &tmp_mv, &tmp_rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008909 mbmi->mv[0].as_int = tmp_mv.as_int;
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008910 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8911 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008912 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8913 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8914 rd = RDCOST(x->rdmult, x->rddiv,
8915 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8916 if (rd < best_interintra_rd_wedge) {
8917 best_interintra_rd_wedge = rd;
8918 } else {
8919 tmp_mv.as_int = cur_mv[0].as_int;
8920 tmp_rate_mv = rate_mv;
8921 }
8922 } else {
8923 tmp_mv.as_int = cur_mv[0].as_int;
8924 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008925 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008926 }
8927 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008928 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008929 rd =
8930 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8931 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8932 if (rd != INT64_MAX)
8933 rd = RDCOST(x->rdmult, x->rddiv,
8934 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8935 best_interintra_rd_wedge = rd;
8936 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8937 mbmi->use_wedge_interintra = 1;
8938 best_interintra_rd = best_interintra_rd_wedge;
8939 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008940 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008941 rate_mv = tmp_rate_mv;
8942 } else {
8943 mbmi->use_wedge_interintra = 0;
8944 best_interintra_rd = best_interintra_rd_nowedge;
8945 mbmi->mv[0].as_int = cur_mv[0].as_int;
8946 }
8947 } else {
8948 mbmi->use_wedge_interintra = 0;
8949 best_interintra_rd = best_interintra_rd_nowedge;
8950 }
8951 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008952#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008953
8954 pred_exists = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008955 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008956 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008957 *args->compmode_interintra_cost +=
Fergus Simpson073c6f32017-02-17 12:13:48 -08008958 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008959 if (is_interintra_wedge_used(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008960 *args->compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008961 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8962 if (mbmi->use_wedge_interintra) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008963 *args->compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008964 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008965 }
8966 }
8967 } else if (is_interintra_allowed(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008968 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008969 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008970 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008971#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008972
Angie Chiang75c22092016-10-25 12:19:16 -07008973 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008974 int tmp_rate;
8975 int64_t tmp_dist;
Jingning Hanc44009c2017-05-06 11:36:49 -07008976 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008977 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8978 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8979 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
8980 }
Angie Chiang75c22092016-10-25 12:19:16 -07008981#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008982
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008983 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008984#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008985 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008986#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008987 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008988#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008989
8990#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008991 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008992 if (is_comp_pred) {
8993 const int mode0 = compound_ref0_mode(this_mode);
8994 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008995 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8996 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008997 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008998 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008999 return INT64_MAX;
9000 }
9001 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009002 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009003 }
9004 }
9005#endif // CONFIG_EXT_INTER
9006
9007 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
9008 // if current pred_error modeled rd is substantially more than the best
9009 // so far, do not bother doing full rd
9010 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00009011 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009012 return INT64_MAX;
9013 }
9014 }
9015
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009016 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
9017 disable_skip, mode_mv, mi_row, mi_col, args,
9018 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07009019#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009020#if CONFIG_EXT_INTER
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009021 rate2_bmc_nocoeff, &best_bmc_mbmi,
Yue Chencb60b182016-10-13 15:18:22 -07009022#if CONFIG_MOTION_VAR
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009023 rate_mv_bmc,
Yue Chencb60b182016-10-13 15:18:22 -07009024#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07009025#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07009026#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08009027 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
9028 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08009029
Yaowu Xuc27fc142016-08-22 16:08:15 -07009030 return 0; // The rate-distortion cost will be re-calculated by caller.
9031}
9032
Alex Converse28744302017-04-13 14:46:22 -07009033#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07009034static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009035 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07009036 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07009037 const AV1_COMMON *const cm = &cpi->common;
9038 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
9039
Alex Converse28744302017-04-13 14:46:22 -07009040 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07009041 const TileInfo *tile = &xd->tile;
9042 MODE_INFO *const mi = xd->mi[0];
9043 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
9044 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
9045 const int w = block_size_wide[bsize];
9046 const int h = block_size_high[bsize];
9047 const int sb_row = mi_row / MAX_MIB_SIZE;
Alex Converse861d7072017-05-15 14:19:53 -07009048 const int sb_col = mi_col / MAX_MIB_SIZE;
Alex Converse3d8adf32017-04-24 12:35:42 -07009049
Alex Converse44c2bad2017-05-11 09:36:10 -07009050 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9051 MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
9052 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9053 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9054 mbmi_ext->ref_mv_stack[ref_frame],
9055#if CONFIG_EXT_INTER
9056 mbmi_ext->compound_mode_context,
9057#endif // CONFIG_EXT_INTER
9058 candidates, mi_row, mi_col, NULL, NULL,
9059 mbmi_ext->mode_context);
9060
9061 int_mv nearestmv, nearmv;
9062 av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
9063
9064 int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
9065 if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
9066 mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
Alex Converse3d8adf32017-04-24 12:35:42 -07009067
Alex Converse3d8adf32017-04-24 12:35:42 -07009068 struct buf_2d yv12_mb[MAX_MB_PLANE];
9069 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
9070 for (int i = 0; i < MAX_MB_PLANE; ++i) {
9071 xd->plane[i].pre[0] = yv12_mb[i];
9072 }
9073
Alex Converse861d7072017-05-15 14:19:53 -07009074 enum IntrabcMotionDirection {
9075 IBC_MOTION_ABOVE,
9076 IBC_MOTION_LEFT,
9077 IBC_MOTION_DIRECTIONS
9078 };
Alex Converse3d8adf32017-04-24 12:35:42 -07009079
Alex Converse3d8adf32017-04-24 12:35:42 -07009080 MB_MODE_INFO *mbmi = &mi->mbmi;
9081 MB_MODE_INFO best_mbmi = *mbmi;
9082 RD_STATS best_rdcost = *rd_cost;
9083 int best_skip = x->skip;
Alex Converse861d7072017-05-15 14:19:53 -07009084
9085 for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
9086 dir < IBC_MOTION_DIRECTIONS; ++dir) {
9087 const MvLimits tmp_mv_limits = x->mv_limits;
9088 switch (dir) {
9089 case IBC_MOTION_ABOVE:
9090 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
9091 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
9092 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
9093 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
9094 break;
9095 case IBC_MOTION_LEFT:
9096 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
9097 x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
9098 // TODO(aconverse@google.com): Minimize the overlap between above and
9099 // left areas.
9100 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
9101 int bottom_coded_mi_edge =
9102 AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
9103 x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
9104 break;
9105 default: assert(0);
9106 }
9107 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
9108 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
9109 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
9110 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
9111 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
9112
9113 if (x->mv_limits.col_max < x->mv_limits.col_min ||
9114 x->mv_limits.row_max < x->mv_limits.row_min) {
9115 x->mv_limits = tmp_mv_limits;
9116 continue;
9117 }
9118
9119 int step_param = cpi->mv_step_param;
9120 MV mvp_full = dv_ref.as_mv;
9121 mvp_full.col >>= 3;
9122 mvp_full.row >>= 3;
9123 int sadpb = x->sadperbit16;
9124 int cost_list[5];
9125 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
9126 sadpb, cond_cost_list(cpi, cost_list),
9127 &dv_ref.as_mv, INT_MAX, 1);
9128
9129 x->mv_limits = tmp_mv_limits;
9130 if (bestsme == INT_MAX) continue;
9131 mvp_full = x->best_mv.as_mv;
9132 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
9133 if (mv_check_bounds(&x->mv_limits, &dv)) continue;
9134 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
9135
Alex Converse3d8adf32017-04-24 12:35:42 -07009136#if CONFIG_PALETTE
Alex Converse861d7072017-05-15 14:19:53 -07009137 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
Alex Converse3d8adf32017-04-24 12:35:42 -07009138#endif
Alex Converse861d7072017-05-15 14:19:53 -07009139 mbmi->use_intrabc = 1;
9140 mbmi->mode = DC_PRED;
9141 mbmi->uv_mode = DC_PRED;
9142 mbmi->mv[0].as_mv = dv;
Alex Converse3d8adf32017-04-24 12:35:42 -07009143#if CONFIG_DUAL_FILTER
Alex Converse861d7072017-05-15 14:19:53 -07009144 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07009145#else
Alex Converse861d7072017-05-15 14:19:53 -07009146 mbmi->interp_filter = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07009147#endif
Alex Converse861d7072017-05-15 14:19:53 -07009148 mbmi->skip = 0;
9149 x->skip = 0;
9150 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Alex Converse3d8adf32017-04-24 12:35:42 -07009151
Alex Converse861d7072017-05-15 14:19:53 -07009152 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
9153 x->mvcost, MV_COST_WEIGHT);
9154 const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
9155 const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
9156 const int rate_mode =
9157 cpi->y_mode_costs[A][L][DC_PRED] + av1_cost_bit(INTRABC_PROB, 1);
Alex Converse3d8adf32017-04-24 12:35:42 -07009158
Alex Converse861d7072017-05-15 14:19:53 -07009159 RD_STATS rd_stats, rd_stats_uv;
9160 av1_subtract_plane(x, bsize, 0);
9161 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
9162 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
9163 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
Alex Converse3d8adf32017-04-24 12:35:42 -07009164#if CONFIG_RD_DEBUG
Alex Converse861d7072017-05-15 14:19:53 -07009165 mbmi->rd_stats = rd_stats;
Alex Converse3d8adf32017-04-24 12:35:42 -07009166#endif
9167
Alex Converse861d7072017-05-15 14:19:53 -07009168 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Alex Converse3d8adf32017-04-24 12:35:42 -07009169
Alex Converse861d7072017-05-15 14:19:53 -07009170 RD_STATS rdc_noskip;
9171 av1_init_rd_stats(&rdc_noskip);
9172 rdc_noskip.rate =
9173 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
9174 rdc_noskip.dist = rd_stats.dist;
9175 rdc_noskip.rdcost =
9176 RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
9177 if (rdc_noskip.rdcost < best_rd) {
9178 best_rd = rdc_noskip.rdcost;
9179 best_mbmi = *mbmi;
9180 best_skip = x->skip;
9181 best_rdcost = rdc_noskip;
9182 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009183
Alex Converse861d7072017-05-15 14:19:53 -07009184 x->skip = 1;
9185 mbmi->skip = 1;
9186 RD_STATS rdc_skip;
9187 av1_init_rd_stats(&rdc_skip);
9188 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
9189 rdc_skip.dist = rd_stats.sse;
9190 rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
9191 if (rdc_skip.rdcost < best_rd) {
9192 best_rd = rdc_skip.rdcost;
9193 best_mbmi = *mbmi;
9194 best_skip = x->skip;
9195 best_rdcost = rdc_skip;
9196 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009197 }
9198 *mbmi = best_mbmi;
9199 *rd_cost = best_rdcost;
9200 x->skip = best_skip;
9201 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07009202}
9203#endif // CONFIG_INTRABC
9204
Urvang Joshi52648442016-10-13 17:27:51 -07009205void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009206 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07009207 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9208 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009209 MACROBLOCKD *const xd = &x->e_mbd;
9210 struct macroblockd_plane *const pd = xd->plane;
9211 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9212 int y_skip = 0, uv_skip = 0;
9213 int64_t dist_y = 0, dist_uv = 0;
9214 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009215 const int unify_bsize = CONFIG_CB4X4;
9216
Yaowu Xuc27fc142016-08-22 16:08:15 -07009217 ctx->skip = 0;
9218 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009219 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07009220#if CONFIG_INTRABC
9221 xd->mi[0]->mbmi.use_intrabc = 0;
Alex Converse44c2bad2017-05-11 09:36:10 -07009222 xd->mi[0]->mbmi.mv[0].as_int = 0;
Alex Converse28744302017-04-13 14:46:22 -07009223#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07009224
Alex Conversed1b6fad2017-04-26 15:39:37 -07009225 const int64_t intra_yrd =
9226 (bsize >= BLOCK_8X8 || unify_bsize)
9227 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9228 &y_skip, bsize, best_rd)
9229 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
9230 &dist_y, &y_skip, best_rd);
9231
9232 if (intra_yrd < best_rd) {
9233 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9234 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009235
9236#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009237#if !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009238 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08009239#endif // !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009240 if (!x->skip_chroma_rd)
9241 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9242 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009243#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07009244 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9245 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009246#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009247
Alex Conversed1b6fad2017-04-26 15:39:37 -07009248 if (y_skip && uv_skip) {
9249 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
9250 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9251 rd_cost->dist = dist_y + dist_uv;
9252 } else {
9253 rd_cost->rate =
9254 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9255 rd_cost->dist = dist_y + dist_uv;
9256 }
9257 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009258 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07009259 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009260 }
9261
Alex Converse28744302017-04-13 14:46:22 -07009262#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07009263 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
9264 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07009265 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
9266 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07009267 assert(rd_cost->rate != INT_MAX);
9268 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07009269 }
9270#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07009271 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07009272
Yaowu Xuc27fc142016-08-22 16:08:15 -07009273 ctx->mic = *xd->mi[0];
9274 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009275}
9276
Yaowu Xuc27fc142016-08-22 16:08:15 -07009277// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009278int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009279 return (cpi->oxcf.pass == 2) &&
9280 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9281 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9282}
9283
9284// Checks to see if a super block is on a horizontal image edge.
9285// In most cases this is the "real" edge unless there are formatting
9286// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009287int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009288 int top_edge = 0;
9289 int bottom_edge = cpi->common.mi_rows;
9290 int is_active_h_edge = 0;
9291
9292 // For two pass account for any formatting bars detected.
9293 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009294 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009295
9296 // The inactive region is specified in MBs not mi units.
9297 // The image edge is in the following MB row.
9298 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9299
9300 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009301 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009302 }
9303
9304 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9305 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9306 is_active_h_edge = 1;
9307 }
9308 return is_active_h_edge;
9309}
9310
9311// Checks to see if a super block is on a vertical image edge.
9312// In most cases this is the "real" edge unless there are formatting
9313// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009314int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009315 int left_edge = 0;
9316 int right_edge = cpi->common.mi_cols;
9317 int is_active_v_edge = 0;
9318
9319 // For two pass account for any formatting bars detected.
9320 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009321 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009322
9323 // The inactive region is specified in MBs not mi units.
9324 // The image edge is in the following MB row.
9325 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9326
9327 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009328 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009329 }
9330
9331 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9332 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9333 is_active_v_edge = 1;
9334 }
9335 return is_active_v_edge;
9336}
9337
9338// Checks to see if a super block is at the edge of the active image.
9339// In most cases this is the "real" edge unless there are formatting
9340// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009341int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009342 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9343 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009344}
9345
Urvang Joshib100db72016-10-12 16:28:56 -07009346#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009347static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009348 MACROBLOCKD *const xd = &x->e_mbd;
9349 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9350 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9351 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009352 int src_stride = x->plane[1].src.stride;
9353 const uint8_t *const src_u = x->plane[1].src.buf;
9354 const uint8_t *const src_v = x->plane[2].src.buf;
9355 float *const data = x->palette_buffer->kmeans_data_buf;
9356 float centroids[2 * PALETTE_MAX_SIZE];
9357 uint8_t *const color_map = xd->plane[1].color_index_map;
9358 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009359#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009360 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9361 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009362#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009363 int plane_block_width, plane_block_height, rows, cols;
9364 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9365 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009366 (void)cpi;
9367
9368 for (r = 0; r < rows; ++r) {
9369 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009370#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009371 if (cpi->common.use_highbitdepth) {
9372 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9373 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9374 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009375#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009376 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9377 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009378#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009379 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009380#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009381 }
9382 }
9383
9384 for (r = 1; r < 3; ++r) {
9385 for (c = 0; c < pmi->palette_size[1]; ++c) {
9386 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9387 }
9388 }
9389
Yaowu Xuf883b422016-08-30 14:01:10 -07009390 av1_calc_indices(data, centroids, color_map, rows * cols,
9391 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009392 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9393 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009394}
Urvang Joshib100db72016-10-12 16:28:56 -07009395#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009396
hui su5db97432016-10-14 16:10:14 -07009397#if CONFIG_FILTER_INTRA
9398static void pick_filter_intra_interframe(
9399 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009400 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9401 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9402 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009403#if CONFIG_EXT_INTRA
9404 int8_t *uv_angle_delta,
9405#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009406#if CONFIG_PALETTE
9407 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9408#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009409 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9410 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9411 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9412#if CONFIG_SUPERTX
9413 int *returnrate_nocoef,
9414#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009415 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009416 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009417 MACROBLOCKD *const xd = &x->e_mbd;
9418 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009419#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009420 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009421#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009422 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9423 int dc_mode_index;
9424 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009425 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9426 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009427 TX_SIZE uv_tx;
9428
9429 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009430 if (av1_mode_order[i].mode == DC_PRED &&
9431 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009432 break;
9433 dc_mode_index = i;
9434 assert(i < MAX_MODES);
9435
9436 // TODO(huisu): use skip_mask for further speedup.
9437 (void)skip_mask;
9438 mbmi->mode = DC_PRED;
9439 mbmi->uv_mode = DC_PRED;
9440 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009441 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009442 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9443 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009444 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009445 return;
hui su5db97432016-10-14 16:10:14 -07009446 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009447 if (rate_y == INT_MAX) return;
9448
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009449 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9450 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009451 if (rate_uv_intra[uv_tx] == INT_MAX) {
9452 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9453 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9454 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009455#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009456 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009457#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009458 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9459#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009460 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009461#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009462 }
9463
9464 rate_uv = rate_uv_tokenonly[uv_tx];
9465 distortion_uv = dist_uv[uv_tx];
9466 skippable = skippable && skip_uv[uv_tx];
9467 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009468#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009469 if (cm->allow_screen_content_tools) {
9470 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9471 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9472 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9473 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9474 }
Urvang Joshib100db72016-10-12 16:28:56 -07009475#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009476#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009477 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009478#endif // CONFIG_EXT_INTRA
9479 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9480 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9481 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9482 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9483 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009484 }
9485
9486 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9487 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009488#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07009489 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
9490 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07009491 rate2 += av1_cost_bit(
9492 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009493#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009494
9495 if (!xd->lossless[mbmi->segment_id]) {
9496 // super_block_yrd above includes the cost of the tx_size in the
9497 // tokenonly rate, but for intra blocks, tx_size is always coded
9498 // (prediction granularity), so we account for it in the full rate,
9499 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009500 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009501 }
9502
hui su5db97432016-10-14 16:10:14 -07009503 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9504 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9505 rate2 += write_uniform_cost(
9506 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9507#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009508 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07009509 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9510 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009511 }
hui su5db97432016-10-14 16:10:14 -07009512#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009514 rate2 +=
9515 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9516 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9517 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9518 rate2 +=
9519 write_uniform_cost(FILTER_INTRA_MODES,
9520 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009521 }
9522 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009523 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9524 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009525
9526 rate2 += ref_costs_single[INTRA_FRAME];
9527
9528 if (skippable) {
9529 rate2 -= (rate_y + rate_uv);
9530 rate_y = 0;
9531 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009532 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009533 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009534 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009535 }
9536 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009537
9538 if (this_rd < *best_intra_rd) {
9539 *best_intra_rd = this_rd;
9540 *best_intra_mode = mbmi->mode;
9541 }
9542 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009543 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009544
9545 if (this_rd < *best_rd) {
9546 *best_mode_index = dc_mode_index;
9547 mbmi->mv[0].as_int = 0;
9548 rd_cost->rate = rate2;
9549#if CONFIG_SUPERTX
9550 if (x->skip)
9551 *returnrate_nocoef = rate2;
9552 else
9553 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009554 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9555 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9556 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009557#endif // CONFIG_SUPERTX
9558 rd_cost->dist = distortion2;
9559 rd_cost->rdcost = this_rd;
9560 *best_rd = this_rd;
9561 *best_mbmode = *mbmi;
9562 *best_skip2 = 0;
9563 *best_mode_skippable = skippable;
9564 }
9565}
hui su5db97432016-10-14 16:10:14 -07009566#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009567
Yue Chencb60b182016-10-13 15:18:22 -07009568#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009569static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9570 const MACROBLOCKD *xd, int mi_row,
9571 int mi_col, const uint8_t *above,
9572 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009573 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009574#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009575
Urvang Joshi52648442016-10-13 17:27:51 -07009576void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009577 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009578 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009579#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009580 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009581#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009582 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9583 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009584 const AV1_COMMON *const cm = &cpi->common;
9585 const RD_OPT *const rd_opt = &cpi->rd;
9586 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009587 MACROBLOCKD *const xd = &x->e_mbd;
9588 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009589#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009590 const int try_palette =
9591 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009592 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009593#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009594 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9595 const struct segmentation *const seg = &cm->seg;
9596 PREDICTION_MODE this_mode;
9597 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9598 unsigned char segment_id = mbmi->segment_id;
9599 int comp_pred, i, k;
9600 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9601 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009602 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009603#if CONFIG_EXT_INTER
9604 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
9605 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009606#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009607 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9608 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009609 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009610#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009611 AOM_LAST2_FLAG,
9612 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009613#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009614 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009615#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009616 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009617#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009618 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009619 };
9620 int64_t best_rd = best_rd_so_far;
9621 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9622 int64_t best_pred_diff[REFERENCE_MODES];
9623 int64_t best_pred_rd[REFERENCE_MODES];
9624 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009625 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9626 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009627 int best_mode_skippable = 0;
9628 int midx, best_mode_index = -1;
9629 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9630 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009631 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009632 int64_t best_intra_rd = INT64_MAX;
9633 unsigned int best_pred_sse = UINT_MAX;
9634 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009635 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9636 int64_t dist_uvs[TX_SIZES_ALL];
9637 int skip_uvs[TX_SIZES_ALL];
9638 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009639#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009640 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009641#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009642#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009643 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009644 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009645 uint8_t directional_mode_skip_mask[INTRA_MODES];
9646#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009647#if CONFIG_FILTER_INTRA
9648 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009649 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009650#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009651 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009652 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9653 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9654 int best_skip2 = 0;
9655 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009656 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Yue Chen4d26acb2017-05-01 12:28:34 -07009657#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009658 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9659 int64_t best_single_inter_rd = INT64_MAX;
Yue Chen4d26acb2017-05-01 12:28:34 -07009660#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009661 int mode_skip_start = sf->mode_skip_start + 1;
9662 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9663 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9664 int64_t mode_threshold[MAX_MODES];
9665 int *mode_map = tile_data->mode_map[bsize];
9666 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009667#if CONFIG_PVQ
9668 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009669#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009670
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009671 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009672#if CONFIG_MOTION_VAR
9673 { NULL },
9674 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9675 { NULL },
9676 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9677#endif // CONFIG_MOTION_VAR
9678#if CONFIG_EXT_INTER
9679 NULL,
9680 NULL,
9681 NULL,
9682 NULL,
9683 NULL,
9684#else // CONFIG_EXT_INTER
9685 NULL,
9686#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009687 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009688 };
9689
Urvang Joshib100db72016-10-12 16:28:56 -07009690#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009691 const int rows = block_size_high[bsize];
9692 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009693#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9694#if CONFIG_PALETTE
9695 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009696 const MODE_INFO *above_mi = xd->above_mi;
9697 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009698#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009699#if CONFIG_MOTION_VAR
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009700#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9702 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9703#else
9704 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9705 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009706#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009707 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9708 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009709 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9710 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9711 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9712 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009713
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009714#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009715 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9716 int len = sizeof(uint16_t);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009717 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9718 args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9719 args.above_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009720 CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009721 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9722 args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9723 args.left_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009724 CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009725 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009726#endif // CONFIG_HIGHBITDEPTH
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009727 args.above_pred_buf[0] = tmp_buf1;
9728 args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
9729 args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9730 args.left_pred_buf[0] = tmp_buf2;
9731 args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
9732 args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009733#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009734 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009735#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009736#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009737
Yaowu Xuf883b422016-08-30 14:01:10 -07009738 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009739
Urvang Joshib100db72016-10-12 16:28:56 -07009740#if CONFIG_PALETTE
9741 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07009742 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009743 if (above_mi)
9744 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9745 if (left_mi)
9746 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9747 }
Urvang Joshib100db72016-10-12 16:28:56 -07009748#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009749
Yaowu Xuc27fc142016-08-22 16:08:15 -07009750 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9751 &comp_mode_p);
9752
9753 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009754 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009755 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9756 for (i = 0; i < MB_MODE_COUNT; ++i) {
9757 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009758 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009759 }
9760 }
9761
9762 rd_cost->rate = INT_MAX;
9763#if CONFIG_SUPERTX
9764 *returnrate_nocoef = INT_MAX;
9765#endif // CONFIG_SUPERTX
9766
9767 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9768 x->pred_mv_sad[ref_frame] = INT_MAX;
9769 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009770#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009771 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009772#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009773 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9774 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9775 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9776 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9777 }
9778 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009779#if CONFIG_GLOBAL_MOTION
9780 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009781 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009782 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9783 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009784 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009785#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009786 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009787#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009788#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009789 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009790#if CONFIG_GLOBAL_MOTION
9791 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009792 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009793 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9794 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009795 .as_int;
9796#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009797 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009798#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009799#endif // CONFIG_EXT_INTER
9800 }
9801
Yaowu Xuc27fc142016-08-22 16:08:15 -07009802 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9803 MODE_INFO *const mi = xd->mi[0];
9804 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9805 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009806 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9807 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009808#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009809 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009810#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009811 candidates, mi_row, mi_col, NULL, NULL,
9812 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009813 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9814 MV_REFERENCE_FRAME rf[2];
9815 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009816 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9817 frame_mv[ZEROMV][rf[0]].as_int ||
9818 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9819 frame_mv[ZEROMV][rf[0]].as_int ||
9820 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9821 frame_mv[ZEROMV][rf[1]].as_int ||
9822 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009823 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9824 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009825 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009826
Yue Chencb60b182016-10-13 15:18:22 -07009827#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009828 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Yue Chenf7ba6472017-04-19 11:08:58 -07009829 if (check_num_overlappable_neighbors(mbmi) &&
9830 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009831 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9832 args.above_pred_buf, dst_width1,
9833 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009834 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009835 args.left_pred_buf, dst_width2,
9836 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07009837 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
9838 mi_col);
Yue Chen5329a2b2017-02-28 17:33:00 +08009839 x->mask_buf = mask2d_buf;
9840 x->wsrc_buf = weighted_src_buf;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009841 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9842 args.above_pred_stride[0], args.left_pred_buf[0],
9843 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009844 }
Yue Chencb60b182016-10-13 15:18:22 -07009845#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009846
9847 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9848 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9849// Skip checking missing references in both single and compound reference
9850// modes. Note that a mode will be skipped iff both reference frames
9851// are masked out.
9852#if CONFIG_EXT_REFS
9853 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9854 ref_frame_skip_mask[0] |= (1 << ref_frame);
9855 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9856 } else {
9857#endif // CONFIG_EXT_REFS
9858 ref_frame_skip_mask[0] |= (1 << ref_frame);
9859 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9860#if CONFIG_EXT_REFS
9861 }
9862#endif // CONFIG_EXT_REFS
9863 } else {
9864 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9865 // Skip fixed mv modes for poor references
9866 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9867 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9868 break;
9869 }
9870 }
9871 }
9872 // If the segment reference frame feature is enabled....
9873 // then do nothing if the current ref frame is not allowed..
9874 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9875 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9876 ref_frame_skip_mask[0] |= (1 << ref_frame);
9877 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9878 }
9879 }
9880
9881 // Disable this drop out case if the ref frame
9882 // segment level feature is enabled for this segment. This is to
9883 // prevent the possibility that we end up unable to pick any mode.
9884 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9885 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9886 // unless ARNR filtering is enabled in which case we want
9887 // an unfiltered alternative. We allow near/nearest as well
9888 // because they may result in zero-zero MVs but be cheaper.
9889 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009890 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009891 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9892#if CONFIG_EXT_REFS
9893 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9894 (1 << BWDREF_FRAME) |
9895#endif // CONFIG_EXT_REFS
9896 (1 << GOLDEN_FRAME);
9897 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9898 // TODO(zoeliu): To further explore whether following needs to be done for
9899 // BWDREF_FRAME as well.
9900 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009901#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009902 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009903 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009904 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009905 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009906#else
9907 zeromv.as_int = 0;
9908#endif // CONFIG_GLOBAL_MOTION
9909 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009910 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009911 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009912 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9913#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009914 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009915 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009916 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009917 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9918#endif // CONFIG_EXT_INTER
9919 }
9920 }
9921
9922 if (cpi->rc.is_src_frame_alt_ref) {
9923 if (sf->alt_ref_search_fp) {
9924 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9925 mode_skip_mask[ALTREF_FRAME] = 0;
9926 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9927 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9928 }
9929 }
9930
9931 if (sf->alt_ref_search_fp)
9932 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9933 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9934 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9935
9936 if (sf->adaptive_mode_search) {
9937 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9938 cpi->rc.frames_since_golden >= 3)
Yaowu Xu36bad472017-05-16 18:29:53 -07009939 if ((x->pred_mv_sad[GOLDEN_FRAME] >> 1) > x->pred_mv_sad[LAST_FRAME])
Yaowu Xuc27fc142016-08-22 16:08:15 -07009940 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9941 }
9942
9943 if (bsize > sf->max_intra_bsize) {
9944 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9945 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9946 }
9947
9948 mode_skip_mask[INTRA_FRAME] |=
9949 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9950
9951 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9952 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9953 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9954
9955 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9956 while (midx > 4) {
9957 uint8_t end_pos = 0;
9958 for (i = 5; i < midx; ++i) {
9959 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9960 uint8_t tmp = mode_map[i];
9961 mode_map[i] = mode_map[i - 1];
9962 mode_map[i - 1] = tmp;
9963 end_pos = i;
9964 }
9965 }
9966 midx = end_pos;
9967 }
9968
9969 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9970 x->use_default_intra_tx_type = 1;
9971 else
9972 x->use_default_intra_tx_type = 0;
9973
9974 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9975 x->use_default_inter_tx_type = 1;
9976 else
9977 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009978#if CONFIG_PVQ
9979 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009980#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009981#if CONFIG_EXT_INTER
9982 for (i = 0; i < MB_MODE_COUNT; ++i)
9983 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9984 modelled_rd[i][ref_frame] = INT64_MAX;
9985#endif // CONFIG_EXT_INTER
9986
9987 for (midx = 0; midx < MAX_MODES; ++midx) {
9988 int mode_index;
9989 int mode_excluded = 0;
9990 int64_t this_rd = INT64_MAX;
9991 int disable_skip = 0;
9992 int compmode_cost = 0;
9993#if CONFIG_EXT_INTER
9994 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009995 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009996#endif // CONFIG_EXT_INTER
9997 int rate2 = 0, rate_y = 0, rate_uv = 0;
9998 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9999 int skippable = 0;
10000 int this_skip2 = 0;
10001 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010002 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -070010003#if CONFIG_PVQ
10004 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080010005#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070010006 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -070010007 this_mode = av1_mode_order[mode_index].mode;
10008 ref_frame = av1_mode_order[mode_index].ref_frame[0];
10009 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010010 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010011
10012#if CONFIG_EXT_INTER
10013 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
10014 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080010015 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010016 if (!is_interintra_allowed_bsize(bsize)) continue;
10017 }
10018
10019 if (is_inter_compound_mode(this_mode)) {
10020 frame_mv[this_mode][ref_frame].as_int =
10021 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
10022 frame_mv[this_mode][second_ref_frame].as_int =
10023 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
10024 }
10025#endif // CONFIG_EXT_INTER
10026
10027 // Look at the reference frame of the best mode so far and set the
10028 // skip mask to look at a subset of the remaining modes.
10029 if (midx == mode_skip_start && best_mode_index >= 0) {
10030 switch (best_mbmode.ref_frame[0]) {
10031 case INTRA_FRAME: break;
10032 case LAST_FRAME:
10033 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
10034 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10035 break;
10036#if CONFIG_EXT_REFS
10037 case LAST2_FRAME:
10038 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
10039 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10040 break;
10041 case LAST3_FRAME:
10042 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
10043 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10044 break;
10045#endif // CONFIG_EXT_REFS
10046 case GOLDEN_FRAME:
10047 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
10048 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10049 break;
10050#if CONFIG_EXT_REFS
10051 case BWDREF_FRAME:
10052 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
10053 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10054 break;
10055#endif // CONFIG_EXT_REFS
10056 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
10057#if CONFIG_EXT_REFS
10058 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
10059#endif // CONFIG_EXT_REFS
10060 break;
Emil Keyder01770b32017-01-20 18:03:11 -050010061 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070010062 case TOTAL_REFS_PER_FRAME:
10063 assert(0 && "Invalid Reference frame");
10064 break;
10065 }
10066 }
10067
10068 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070010069 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010070 continue;
10071
10072 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
10073
10074 // Test best rd so far against threshold for trying this mode.
10075 if (best_mode_skippable && sf->schedule_mode_search)
10076 mode_threshold[mode_index] <<= 1;
10077
10078 if (best_rd < mode_threshold[mode_index]) continue;
10079
Yunqing Wangff4fa062017-04-21 10:56:08 -070010080 // This is only used in motion vector unit test.
10081 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
10082
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020010083#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
10084#if CONFIG_EXT_REFS
10085 if (cpi->oxcf.pass == 0) {
10086 // Complexity-compression trade-offs
10087 // if (ref_frame == ALTREF_FRAME) continue;
10088 // if (ref_frame == BWDREF_FRAME) continue;
10089 if (second_ref_frame == ALTREF_FRAME) continue;
10090 // if (second_ref_frame == BWDREF_FRAME) continue;
10091 }
10092#endif
10093#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010094 comp_pred = second_ref_frame > INTRA_FRAME;
10095 if (comp_pred) {
10096 if (!cpi->allow_comp_inter_inter) continue;
10097
10098 // Skip compound inter modes if ARF is not available.
10099 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10100
10101 // Do not allow compound prediction if the segment level reference frame
10102 // feature is in use as in this case there can only be one reference.
10103 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10104
10105 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10106 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10107 continue;
10108
10109 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10110 } else {
10111 if (ref_frame != INTRA_FRAME)
10112 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10113 }
10114
10115 if (ref_frame == INTRA_FRAME) {
10116 if (sf->adaptive_mode_search)
10117 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10118 continue;
10119
10120 if (this_mode != DC_PRED) {
10121 // Disable intra modes other than DC_PRED for blocks with low variance
10122 // Threshold for intra skipping based on source variance
10123 // TODO(debargha): Specialize the threshold for super block sizes
10124 const unsigned int skip_intra_var_thresh = 64;
10125 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10126 x->source_variance < skip_intra_var_thresh)
10127 continue;
10128 // Only search the oblique modes if the best so far is
10129 // one of the neighboring directional modes
10130 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10131 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10132 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10133 continue;
10134 }
10135 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10136 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10137 }
10138 }
Sarah Parkere5299862016-08-16 14:57:37 -070010139#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010140 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010141 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010142 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010143#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010144 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010145#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010146 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10147 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010148#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010149 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010150#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010151 frame_mv, this_mode, ref_frames, bsize, -1,
10152 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010153 continue;
10154 }
10155
10156 mbmi->mode = this_mode;
10157 mbmi->uv_mode = DC_PRED;
10158 mbmi->ref_frame[0] = ref_frame;
10159 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010160#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010161 pmi->palette_size[0] = 0;
10162 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010163#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010164#if CONFIG_FILTER_INTRA
10165 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10166 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10167#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010168 // Evaluate all sub-pel filters irrespective of whether we can use
10169 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010170
10171 set_default_interp_filters(mbmi, cm->interp_filter);
10172
Yaowu Xuc27fc142016-08-22 16:08:15 -070010173 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010174 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010175
10176 x->skip = 0;
10177 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10178
10179 // Select prediction reference frames.
10180 for (i = 0; i < MAX_MB_PLANE; i++) {
10181 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10182 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10183 }
10184
Yue Chen4d26acb2017-05-01 12:28:34 -070010185#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010186 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yue Chen4d26acb2017-05-01 12:28:34 -070010187#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010188
10189 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010190 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010191 TX_SIZE uv_tx;
10192 struct macroblockd_plane *const pd = &xd->plane[1];
10193#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010194 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010195 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010196 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010197 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010198 if (!angle_stats_ready) {
10199 const int src_stride = x->plane[0].src.stride;
10200 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010201#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010202 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -070010203 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010204 directional_mode_skip_mask);
10205 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010206#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -070010207 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010208 directional_mode_skip_mask);
10209 angle_stats_ready = 1;
10210 }
10211 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010212 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -070010213 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
10214 intra_mode_cost[mbmi->mode], best_rd,
10215 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010216 } else {
10217 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010218 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010219 }
10220#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010221 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010222#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010223 rate_y = rd_stats_y.rate;
10224 distortion_y = rd_stats_y.dist;
10225 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010226
10227 if (rate_y == INT_MAX) continue;
10228
hui su5db97432016-10-14 16:10:14 -070010229#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010230 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010231#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010232
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010233 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10234 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010235 if (rate_uv_intra[uv_tx] == INT_MAX) {
10236 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010237 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10238 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010239#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010240 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010241#endif // CONFIG_PALETTE
10242
Yaowu Xuc27fc142016-08-22 16:08:15 -070010243#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010244 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10245#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010246#if CONFIG_FILTER_INTRA
10247 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10248#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010249 }
10250
10251 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010252 distortion_uv = dist_uvs[uv_tx];
10253 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010254 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010255#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010256 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010257 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10258 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10259 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10260 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10261 }
Urvang Joshib100db72016-10-12 16:28:56 -070010262#endif // CONFIG_PALETTE
10263
Yaowu Xuc27fc142016-08-22 16:08:15 -070010264#if CONFIG_EXT_INTRA
10265 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010266#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010267#if CONFIG_FILTER_INTRA
10268 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10269 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10270 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10271 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10272 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10273 }
10274#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010275
Jingning Han36fe3202017-02-20 22:31:49 -080010276#if CONFIG_CB4X4
10277 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10278 if (!x->skip_chroma_rd)
10279 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10280#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010281 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10282 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010283#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010284
Urvang Joshib100db72016-10-12 16:28:56 -070010285#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010286 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010287 rate2 += av1_cost_bit(
10288 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -070010289 }
Urvang Joshib100db72016-10-12 16:28:56 -070010290#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010291
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010292 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010293 // super_block_yrd above includes the cost of the tx_size in the
10294 // tokenonly rate, but for intra blocks, tx_size is always coded
10295 // (prediction granularity), so we account for it in the full rate,
10296 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010297 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010298 }
10299#if CONFIG_EXT_INTRA
10300 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -080010301#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010302 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -070010303 const int p_angle =
10304 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -070010305 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010306 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010307#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -070010308 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10309 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010310 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010311 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su0a6731f2017-04-26 15:23:47 -070010312 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10313 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010314 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010315#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010316#if CONFIG_FILTER_INTRA
10317 if (mbmi->mode == DC_PRED) {
10318 rate2 +=
10319 av1_cost_bit(cm->fc->filter_intra_probs[0],
10320 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10321 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10322 rate2 += write_uniform_cost(
10323 FILTER_INTRA_MODES,
10324 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10325 }
10326 }
10327 if (mbmi->uv_mode == DC_PRED) {
10328 rate2 +=
10329 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10330 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10331 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10332 rate2 += write_uniform_cost(
10333 FILTER_INTRA_MODES,
10334 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10335 }
10336#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -070010337 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010338 rate2 += intra_cost_penalty;
10339 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010340 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010341 int_mv backup_ref_mv[2];
10342
Jingning Hanc41a5492017-02-24 11:18:52 -080010343#if !SUB8X8_COMP_REF
Jingning Han69d21012017-05-14 16:51:27 -070010344 if (bsize == BLOCK_4X4 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010345#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010346
Yaowu Xuc27fc142016-08-22 16:08:15 -070010347 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10348 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yue Chen4d26acb2017-05-01 12:28:34 -070010349#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010350 if (second_ref_frame == INTRA_FRAME) {
10351 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010352 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010353// TODO(debargha|geza.lore):
10354// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010355#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010356 mbmi->angle_delta[0] = 0;
10357 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010358#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010359 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010360#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010361#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010362#if CONFIG_FILTER_INTRA
10363 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10364 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10365#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010366 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010367#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010368 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010369 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010370
David Barker404b2e82017-03-27 13:07:47 +010010371#if CONFIG_EXT_INTER
10372 if (comp_pred) {
10373 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +010010374 int ref_mv_idx = 0;
10375 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10376 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10377 // mbmi->ref_mv_idx (like NEWMV)
10378 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10379 ref_mv_idx = 1;
10380
10381 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10382 int_mv this_mv =
10383 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +010010384 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10385 xd->n8_h << MI_SIZE_LOG2, xd);
10386 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10387 }
David Barker3dfba992017-04-03 16:10:09 +010010388 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10389 int_mv this_mv =
10390 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +010010391 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10392 xd->n8_h << MI_SIZE_LOG2, xd);
10393 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10394 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010395 }
David Barker404b2e82017-03-27 13:07:47 +010010396 } else {
10397#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -070010398 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +010010399 int ref;
10400 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10401 int_mv this_mv =
10402 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10403 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10404 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10405 xd->n8_h << MI_SIZE_LOG2, xd);
10406 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10407 }
10408 }
10409#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010410 }
David Barker404b2e82017-03-27 13:07:47 +010010411#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010412 {
10413 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10414 av1_init_rd_stats(&rd_stats);
10415 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010416
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010417 // Point to variables that are maintained between loop iterations
10418 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010419#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010420 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010421 args.compmode_interintra_cost = &compmode_interintra_cost;
10422 args.compmode_interinter_cost = &compmode_interinter_cost;
10423 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010424#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010425 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10426 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010427 mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010428// Prevent pointers from escaping local scope
Yaowu Xuc27fc142016-08-22 16:08:15 -070010429#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010430 args.compmode_interintra_cost = NULL;
10431 args.compmode_interinter_cost = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010432#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010433
10434 rate2 = rd_stats.rate;
10435 skippable = rd_stats.skip;
10436 distortion2 = rd_stats.dist;
10437 total_sse = rd_stats.sse;
10438 rate_y = rd_stats_y.rate;
10439 rate_uv = rd_stats_uv.rate;
10440 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010441
David Barker404b2e82017-03-27 13:07:47 +010010442// TODO(jingning): This needs some refactoring to improve code quality
10443// and reduce redundant steps.
10444#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010445 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +010010446 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10447 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10448 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10449#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010450 if ((mbmi->mode == NEARMV &&
10451 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10452 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
David Barker404b2e82017-03-27 13:07:47 +010010453#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010454 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10455 MB_MODE_INFO backup_mbmi = *mbmi;
10456 int backup_skip = x->skip;
10457 int64_t tmp_ref_rd = this_rd;
10458 int ref_idx;
10459
Yue Chen6e601e92016-12-05 18:19:00 -080010460// TODO(jingning): This should be deprecated shortly.
10461#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010462 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010463#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010464 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010465#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010466 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010467 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010468
10469 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010470 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010471 // Dummy
10472 int_mv backup_fmv[2];
10473 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10474 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10475
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010476 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010477
10478 if (this_rd < INT64_MAX) {
10479 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10480 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10481 tmp_ref_rd =
10482 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010483 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010484 distortion2);
10485 else
10486 tmp_ref_rd =
10487 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010488 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010489 rate_y - rate_uv,
10490 total_sse);
10491 }
10492#if CONFIG_VAR_TX
10493 for (i = 0; i < MAX_MB_PLANE; ++i)
10494 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10495 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010496#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010497
10498 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10499 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010500 int dummy_disable_skip = 0;
10501 int ref;
10502 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010503 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010504#if CONFIG_EXT_INTER
10505 int tmp_compmode_interintra_cost = 0;
10506 int tmp_compmode_interinter_cost = 0;
10507#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010508
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010509 av1_invalid_rd_stats(&tmp_rd_stats);
Jingning Han52617b22017-04-11 12:50:08 -070010510 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010511
Yaowu Xuc27fc142016-08-22 16:08:15 -070010512 mbmi->ref_mv_idx = 1 + ref_idx;
10513
David Barker3dfba992017-04-03 16:10:09 +010010514#if CONFIG_EXT_INTER
10515 if (comp_pred) {
10516 int ref_mv_idx = mbmi->ref_mv_idx;
10517 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10518 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10519 // mbmi->ref_mv_idx (like NEWMV)
10520 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10521 ref_mv_idx = 1 + mbmi->ref_mv_idx;
10522
10523 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10524 int_mv this_mv =
10525 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10526 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10527 xd->n8_h << MI_SIZE_LOG2, xd);
10528 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10529 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
10530 int_mv this_mv =
10531 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10532 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10533 xd->n8_h << MI_SIZE_LOG2, xd);
10534 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10535 }
10536
10537 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10538 int_mv this_mv =
10539 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
10540 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10541 xd->n8_h << MI_SIZE_LOG2, xd);
10542 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10543 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10544 int_mv this_mv =
10545 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10546 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10547 xd->n8_h << MI_SIZE_LOG2, xd);
10548 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10549 }
10550 } else {
10551#endif // CONFIG_EXT_INTER
10552 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10553 int_mv this_mv =
10554 (ref == 0)
10555 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10556 .this_mv
10557 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10558 .comp_mv;
10559 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10560 xd->n8_h << MI_SIZE_LOG2, xd);
10561 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10562 }
10563#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010564 }
David Barker3dfba992017-04-03 16:10:09 +010010565#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010566
10567 cur_mv =
10568 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10569 .this_mv;
10570 clamp_mv2(&cur_mv.as_mv, xd);
10571
Alex Converse0fa0f422017-04-24 12:51:14 -070010572 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010573 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010574#if CONFIG_EXT_INTER
10575 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -080010576#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010577
10578 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010579 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010580
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010581 // Point to variables that are not maintained between iterations
10582 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010583#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010584 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010585 args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
10586 args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
10587 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010588#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010589 tmp_alt_rd = handle_inter_mode(
10590 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10591 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010592 // Prevent pointers from escaping local scope
10593 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010594#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010595 args.single_newmv_rate = NULL;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010596 args.compmode_interintra_cost = NULL;
10597 args.compmode_interinter_cost = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010598#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010599 }
10600
10601 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10602 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010603 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10604 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010605 tmp_rd_stats.rate +=
10606 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10607 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010608 }
10609
10610 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10611 mbmi->ref_mv_idx + idx_offset + 1 &&
10612 ref_idx < ref_set - 1) {
10613 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010614 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10615 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010616 tmp_rd_stats.rate +=
10617 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10618 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010619 }
10620
10621 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010622#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010623 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10624 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010625#else
Angie Chiang76159122016-11-09 12:13:22 -080010626 if (RDCOST(x->rdmult, x->rddiv,
10627 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10628 tmp_rd_stats.dist) <
10629 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010630 tmp_alt_rd =
10631 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010632 tmp_rd_stats.rate +
10633 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10634 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010635 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010636 tmp_alt_rd =
10637 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010638 tmp_rd_stats.rate +
10639 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10640 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10641 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010642#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010643 }
10644
10645 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010646 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010647 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010648 distortion2 = tmp_rd_stats.dist;
10649 skippable = tmp_rd_stats.skip;
10650 rate_y = tmp_rd_stats_y.rate;
10651 rate_uv = tmp_rd_stats_uv.rate;
10652 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010653 this_rd = tmp_alt_rd;
10654 tmp_ref_rd = tmp_alt_rd;
10655 backup_mbmi = *mbmi;
10656 backup_skip = x->skip;
10657#if CONFIG_VAR_TX
10658 for (i = 0; i < MAX_MB_PLANE; ++i)
10659 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10660 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010661#endif // CONFIG_VAR_TX
Yue Chen6e601e92016-12-05 18:19:00 -080010662#if CONFIG_EXT_INTER
10663 compmode_interintra_cost = tmp_compmode_interintra_cost;
10664 compmode_interinter_cost = tmp_compmode_interinter_cost;
Fergus Simpson4063a682017-02-28 16:52:22 -080010665#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010666 } else {
10667 *mbmi = backup_mbmi;
10668 x->skip = backup_skip;
10669 }
10670 }
10671
10672 frame_mv[NEARMV][ref_frame] = backup_mv;
10673 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10674 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10675#if CONFIG_VAR_TX
10676 for (i = 0; i < MAX_MB_PLANE; ++i)
10677 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10678 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010679#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010680 }
10681 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10682 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010683
10684 if (this_rd == INT64_MAX) continue;
10685
Jingning Hanc41a5492017-02-24 11:18:52 -080010686#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010687 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010688#else
Jingning Han69d21012017-05-14 16:51:27 -070010689 if (mbmi->sb_type != BLOCK_4X4)
Jingning Hanc41a5492017-02-24 11:18:52 -080010690 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010691#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010692
10693 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10694 }
10695
10696#if CONFIG_EXT_INTER
10697 rate2 += compmode_interintra_cost;
10698 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010699#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10700 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10701#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010702 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010703#endif // CONFIG_EXT_INTER
10704
10705 // Estimate the reference frame signaling cost and add it
10706 // to the rolling cost variable.
10707 if (comp_pred) {
10708 rate2 += ref_costs_comp[ref_frame];
10709#if CONFIG_EXT_REFS
10710 rate2 += ref_costs_comp[second_ref_frame];
10711#endif // CONFIG_EXT_REFS
10712 } else {
10713 rate2 += ref_costs_single[ref_frame];
10714 }
10715
Yue Chen69f18e12016-09-08 14:48:15 -070010716#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010717 if (ref_frame == INTRA_FRAME) {
10718#else
10719 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010720#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010721 if (skippable) {
10722 // Back out the coefficient coding costs
10723 rate2 -= (rate_y + rate_uv);
10724 rate_y = 0;
10725 rate_uv = 0;
10726 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010727 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010728 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010729 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10730 distortion2) <
10731 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010732 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010733 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010734 } else {
10735 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010736 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010737 distortion2 = total_sse;
10738 assert(total_sse >= 0);
10739 rate2 -= (rate_y + rate_uv);
10740 this_skip2 = 1;
10741 rate_y = 0;
10742 rate_uv = 0;
10743 }
10744 } else {
10745 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010746 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010747 }
10748
10749 // Calculate the final RD estimate for this mode.
10750 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010751#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010752 } else {
10753 this_skip2 = mbmi->skip;
10754 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10755 if (this_skip2) {
10756 rate_y = 0;
10757 rate_uv = 0;
10758 }
Yue Chen69f18e12016-09-08 14:48:15 -070010759#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010760 }
10761
Yaowu Xuc27fc142016-08-22 16:08:15 -070010762 if (ref_frame == INTRA_FRAME) {
10763 // Keep record of best intra rd
10764 if (this_rd < best_intra_rd) {
10765 best_intra_rd = this_rd;
10766 best_intra_mode = mbmi->mode;
10767 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010768#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Emil Keyder01770b32017-01-20 18:03:11 -050010769 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010770 if (this_rd < best_single_inter_rd) {
10771 best_single_inter_rd = this_rd;
10772 best_single_inter_ref = mbmi->ref_frame[0];
10773 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010774#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010775 }
10776
10777 if (!disable_skip && ref_frame == INTRA_FRAME) {
10778 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010779 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010780 }
10781
10782 // Did this mode help.. i.e. is it the new best mode
10783 if (this_rd < best_rd || x->skip) {
10784 if (!mode_excluded) {
10785 // Note index of best mode so far
10786 best_mode_index = mode_index;
10787
10788 if (ref_frame == INTRA_FRAME) {
10789 /* required for left and above block mv */
10790 mbmi->mv[0].as_int = 0;
10791 } else {
10792 best_pred_sse = x->pred_sse[ref_frame];
10793 }
10794
10795 rd_cost->rate = rate2;
10796#if CONFIG_SUPERTX
10797 if (x->skip)
10798 *returnrate_nocoef = rate2;
10799 else
10800 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010801 *returnrate_nocoef -= av1_cost_bit(
10802 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10803 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10804 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010805#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -070010806#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10807 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -080010808 const MOTION_MODE motion_allowed = motion_mode_allowed(
10809#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10810 0, xd->global_motion,
10811#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10812 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -080010813 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -070010814 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -080010815 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010816 *returnrate_nocoef -=
10817 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -070010818#else
10819 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010820#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010821#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010822#endif // CONFIG_SUPERTX
10823 rd_cost->dist = distortion2;
10824 rd_cost->rdcost = this_rd;
10825 best_rd = this_rd;
10826 best_mbmode = *mbmi;
10827 best_skip2 = this_skip2;
10828 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010829 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10830 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010831 best_rate_uv = rate_uv;
10832
10833#if CONFIG_VAR_TX
10834 for (i = 0; i < MAX_MB_PLANE; ++i)
10835 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10836 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010837#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010838 }
10839 }
10840
10841 /* keep record of best compound/single-only prediction */
10842 if (!disable_skip && ref_frame != INTRA_FRAME) {
10843 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10844
10845 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10846 single_rate = rate2 - compmode_cost;
10847 hybrid_rate = rate2;
10848 } else {
10849 single_rate = rate2;
10850 hybrid_rate = rate2 + compmode_cost;
10851 }
10852
10853 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10854 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10855
10856 if (!comp_pred) {
10857 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10858 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10859 } else {
10860 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10861 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10862 }
10863 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10864 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10865 }
10866
Yaowu Xuc27fc142016-08-22 16:08:15 -070010867 if (x->skip && !comp_pred) break;
10868 }
10869
10870 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10871 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10872 is_inter_mode(best_mbmode.mode)) ||
10873 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10874 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010875 int skip_blk = 0;
10876 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010877
10878 x->use_default_inter_tx_type = 0;
10879 x->use_default_intra_tx_type = 0;
10880
10881 *mbmi = best_mbmode;
10882
10883 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10884
10885 // Select prediction reference frames.
10886 for (i = 0; i < MAX_MB_PLANE; i++) {
10887 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10888 if (has_second_ref(mbmi))
10889 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10890 }
10891
10892 if (is_inter_mode(mbmi->mode)) {
Jingning Hanc44009c2017-05-06 11:36:49 -070010893 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -070010894#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010895 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -080010896 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010897 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10898 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010899 }
Yue Chencb60b182016-10-13 15:18:22 -070010900#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010901 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010902#if CONFIG_VAR_TX
10903 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010904 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010905 } else {
10906 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010907 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010908 for (idy = 0; idy < xd->n8_h; ++idy)
10909 for (idx = 0; idx < xd->n8_w; ++idx)
10910 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010911 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010912 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10913 }
10914
Angie Chiangb5dda482016-11-02 16:19:58 -070010915 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010916#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010917 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010918 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010919#endif // CONFIG_VAR_TX
10920 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010921 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010922 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010923 }
10924
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010925 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10926 (rd_stats_y.dist + rd_stats_uv.dist)) >
10927 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010928 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010929 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10930 rd_stats_uv.rate = 0;
10931 rd_stats_y.dist = rd_stats_y.sse;
10932 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010933 } else {
10934 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010935 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010936 }
10937
10938 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010939 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10940 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010941#if CONFIG_VAR_TX
10942 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080010943#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010944 best_mbmode.tx_type = mbmi->tx_type;
10945 best_mbmode.tx_size = mbmi->tx_size;
10946#if CONFIG_VAR_TX
10947 for (idy = 0; idy < xd->n8_h; ++idy)
10948 for (idx = 0; idx < xd->n8_w; ++idx)
10949 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
10950
10951 for (i = 0; i < MAX_MB_PLANE; ++i)
10952 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10953 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070010954
10955 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080010956#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010957 rd_cost->rate +=
10958 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
10959 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010960 rd_cost->rdcost =
10961 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
10962 best_skip2 = skip_blk;
10963 }
10964 }
10965
Urvang Joshib100db72016-10-12 16:28:56 -070010966#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010967 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -070010968 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010969 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010970#if CONFIG_SUPERTX
10971 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010972#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080010973 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10974 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010975 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010976 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010977 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010978 uint8_t *const best_palette_color_map =
10979 x->palette_buffer->best_palette_color_map;
10980 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010981 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010982
10983 mbmi->mode = DC_PRED;
10984 mbmi->uv_mode = DC_PRED;
10985 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010986 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010987 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010988 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10989 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10990 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010991 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10992 memcpy(color_map, best_palette_color_map,
10993 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010994 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10995 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010996 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10997 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010998 if (rate_uv_intra[uv_tx] == INT_MAX) {
10999 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070011000 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
11001 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011002 pmi_uv[uv_tx] = *pmi;
11003#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011004 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
11005#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011006#if CONFIG_FILTER_INTRA
11007 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
11008#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011009 }
11010 mbmi->uv_mode = mode_uv[uv_tx];
11011 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080011012 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011013 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
11014 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
11015 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080011016 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011017#if CONFIG_EXT_INTRA
11018 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011019#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011020#if CONFIG_FILTER_INTRA
11021 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
11022 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
11023 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
11024 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
11025 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
11026 }
11027#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011028 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
11029 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
11030 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011031 rate2 += ref_costs_single[INTRA_FRAME];
11032
11033 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011034 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011035#if CONFIG_SUPERTX
11036 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080011037#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011038 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011039 } else {
11040#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011041 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080011042#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011043 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011044 }
11045 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11046 if (this_rd < best_rd) {
11047 best_mode_index = 3;
11048 mbmi->mv[0].as_int = 0;
11049 rd_cost->rate = rate2;
11050#if CONFIG_SUPERTX
11051 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011052#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011053 rd_cost->dist = distortion2;
11054 rd_cost->rdcost = this_rd;
11055 best_rd = this_rd;
11056 best_mbmode = *mbmi;
11057 best_skip2 = 0;
11058 best_mode_skippable = skippable;
11059 }
11060 }
11061PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070011062#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011063
hui su5db97432016-10-14 16:10:14 -070011064#if CONFIG_FILTER_INTRA
11065 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070011066 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070011067 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070011068#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080011069 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070011070#endif // CONFIG_PALETTE
11071 !dc_skipped && best_mode_index >= 0 &&
11072 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070011073 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080011074 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
11075 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070011076#if CONFIG_EXT_INTRA
11077 uv_angle_delta,
11078#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070011079#if CONFIG_PALETTE
11080 pmi_uv, palette_ctx,
11081#endif // CONFIG_PALETTE
11082 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011083 &best_mode_index, &best_skip2, &best_mode_skippable,
11084#if CONFIG_SUPERTX
11085 returnrate_nocoef,
11086#endif // CONFIG_SUPERTX
11087 best_pred_rd, &best_mbmode, rd_cost);
11088 }
hui su5db97432016-10-14 16:10:14 -070011089#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011090
11091 // The inter modes' rate costs are not calculated precisely in some cases.
11092 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11093 // ZEROMV. Here, checks are added for those cases, and the mode decisions
11094 // are corrected.
11095 if (best_mbmode.mode == NEWMV
11096#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070011097 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011098#endif // CONFIG_EXT_INTER
11099 ) {
11100 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11101 best_mbmode.ref_frame[1] };
11102 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011103 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070011104 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011105#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011106 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11107 cm->allow_high_precision_mv, bsize,
11108 mi_col, mi_row, 0)
11109 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011110 zeromv[1].as_int = comp_pred_mode
11111 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11112 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011113 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011114 .as_int
11115 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011116#else
11117 zeromv[0].as_int = 0;
11118 zeromv[1].as_int = 0;
11119#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011120 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011121 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011122 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011123 : INT_MAX;
11124
11125 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11126 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11127 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11128 best_mbmode.mode = NEARMV;
11129 best_mbmode.ref_mv_idx = i;
11130 }
11131 }
11132
11133 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11134 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011135 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011136 best_mbmode.mode = ZEROMV;
11137 } else {
11138 int_mv nearestmv[2];
11139 int_mv nearmv[2];
11140
11141#if CONFIG_EXT_INTER
11142 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11143 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11144 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11145 } else {
11146 nearmv[0] = frame_mv[NEARMV][refs[0]];
11147 nearmv[1] = frame_mv[NEARMV][refs[1]];
11148 }
11149#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011150 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011151 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011152 : INT_MAX;
11153
11154 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11155 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11156 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11157
11158 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11159 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11160 best_mbmode.mode = NEARMV;
11161 best_mbmode.ref_mv_idx = i;
11162 }
11163 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011164#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011165 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11166 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11167 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11168 } else {
11169 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11170 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11171 }
11172
11173 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011174 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011175#if CONFIG_EXT_INTER
11176 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011177 } else {
11178 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
11179 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
11180 : INT_MAX;
11181
11182 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11183 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11184 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11185
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -070011186 // Try switching to the NEAR_NEARMV mode
11187 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011188 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11189 best_mbmode.mode = NEAR_NEARMV;
11190 best_mbmode.ref_mv_idx = i;
11191 }
11192 }
11193
David Barker3dfba992017-04-03 16:10:09 +010011194 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010011195 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11196 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11197 best_mbmode.mode = ZERO_ZEROMV;
11198 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011199#else
11200 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011201 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11202 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011203 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010011204 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011205#endif // CONFIG_EXT_INTER
11206 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011207 }
11208
David Barker9620bcd2017-03-22 14:46:42 +000011209 // Make sure that the ref_mv_idx is only nonzero when we're
11210 // using a mode which can support ref_mv_idx
11211 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010011212#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010011213 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
11214 have_nearmv_in_inter_mode(best_mbmode.mode))) {
David Barker404b2e82017-03-27 13:07:47 +010011215#else
David Barker9620bcd2017-03-22 14:46:42 +000011216 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
David Barker404b2e82017-03-27 13:07:47 +010011217#endif
David Barker9620bcd2017-03-22 14:46:42 +000011218 best_mbmode.ref_mv_idx = 0;
11219 }
11220
David Barkercdcac6d2016-12-01 17:04:16 +000011221 {
Jingning Han731af492016-11-17 11:53:23 -080011222 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11223 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011224 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011225 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011226#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011227 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11228 best_mbmode.ref_frame[1] };
11229 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011230 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011231 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011232 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070011233 zeromv[1].as_int = (refs[1] != NONE_FRAME)
11234 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11235 cm->allow_high_precision_mv,
11236 bsize, mi_col, mi_row, 0)
11237 .as_int
11238 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000011239 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11240 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11241#else
11242 zeromv[0].as_int = zeromv[1].as_int = 0;
11243#endif // CONFIG_GLOBAL_MOTION
11244 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11245 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11246#if CONFIG_EXT_INTER
11247 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11248#else
Emil Keyder01770b32017-01-20 18:03:11 -050011249 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011250 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11251#endif // CONFIG_EXT_INTER
11252 ) {
11253 best_mbmode.mode = ZEROMV;
11254 }
David Barker68e6e862016-11-24 15:10:15 +000011255 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011256 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011257
11258 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11259 rd_cost->rate = INT_MAX;
11260 rd_cost->rdcost = INT64_MAX;
11261 return;
11262 }
11263
Yaowu Xuc27fc142016-08-22 16:08:15 -070011264#if CONFIG_DUAL_FILTER
11265 assert((cm->interp_filter == SWITCHABLE) ||
11266 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11267 !is_inter_block(&best_mbmode));
11268 assert((cm->interp_filter == SWITCHABLE) ||
11269 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11270 !is_inter_block(&best_mbmode));
11271 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11272 assert((cm->interp_filter == SWITCHABLE) ||
11273 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11274 !is_inter_block(&best_mbmode));
11275 assert((cm->interp_filter == SWITCHABLE) ||
11276 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11277 !is_inter_block(&best_mbmode));
11278 }
11279#else
11280 assert((cm->interp_filter == SWITCHABLE) ||
11281 (cm->interp_filter == best_mbmode.interp_filter) ||
11282 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011283#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011284
11285 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011286 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11287 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011288
11289 // macroblock modes
11290 *mbmi = best_mbmode;
11291 x->skip |= best_skip2;
11292
Yue Chen19e7aa82016-11-30 14:05:39 -080011293// Note: this section is needed since the mode may have been forced to
11294// ZEROMV by the all-zero mode handling of ref-mv.
11295#if CONFIG_GLOBAL_MOTION
11296 if (mbmi->mode == ZEROMV
11297#if CONFIG_EXT_INTER
11298 || mbmi->mode == ZERO_ZEROMV
11299#endif // CONFIG_EXT_INTER
11300 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011301#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11302 // Correct the motion mode for ZEROMV
11303 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11304#if SEPARATE_GLOBAL_MOTION
11305 0, xd->global_motion,
11306#endif // SEPARATE_GLOBAL_MOTION
11307 xd->mi[0]);
11308 if (mbmi->motion_mode > last_motion_mode_allowed)
11309 mbmi->motion_mode = last_motion_mode_allowed;
11310#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11311
11312 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011313 if (is_nontrans_global_motion(xd)) {
11314#if CONFIG_DUAL_FILTER
11315 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11316 ? EIGHTTAP_REGULAR
11317 : cm->interp_filter;
11318 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11319 ? EIGHTTAP_REGULAR
11320 : cm->interp_filter;
11321#else
11322 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11323 : cm->interp_filter;
11324#endif // CONFIG_DUAL_FILTER
11325 }
11326 }
11327#endif // CONFIG_GLOBAL_MOTION
11328
Yaowu Xuc27fc142016-08-22 16:08:15 -070011329 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11330 if (mbmi->mode != NEWMV)
11331 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11332 else
11333 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11334 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011335
11336 for (i = 0; i < REFERENCE_MODES; ++i) {
11337 if (best_pred_rd[i] == INT64_MAX)
11338 best_pred_diff[i] = INT_MIN;
11339 else
11340 best_pred_diff[i] = best_rd - best_pred_rd[i];
11341 }
11342
11343 x->skip |= best_mode_skippable;
11344
11345 assert(best_mode_index >= 0);
11346
11347 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11348 best_mode_skippable);
11349
Urvang Joshib100db72016-10-12 16:28:56 -070011350#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011351 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11352 restore_uv_color_map(cpi, x);
11353 }
Urvang Joshib100db72016-10-12 16:28:56 -070011354#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011355}
11356
Urvang Joshi52648442016-10-13 17:27:51 -070011357void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11358 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011359 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011360 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011361 PICK_MODE_CONTEXT *ctx,
11362 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011363 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011364 MACROBLOCKD *const xd = &x->e_mbd;
11365 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11366 unsigned char segment_id = mbmi->segment_id;
11367 const int comp_pred = 0;
11368 int i;
11369 int64_t best_pred_diff[REFERENCE_MODES];
11370 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11371 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011372 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011373 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011374 int64_t this_rd = INT64_MAX;
11375 int rate2 = 0;
11376 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011377 (void)mi_row;
11378 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011379
11380 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11381 &comp_mode_p);
11382
11383 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11384 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11385 x->pred_mv_sad[i] = INT_MAX;
11386
11387 rd_cost->rate = INT_MAX;
11388
11389 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11390
Urvang Joshib100db72016-10-12 16:28:56 -070011391#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011392 mbmi->palette_mode_info.palette_size[0] = 0;
11393 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011394#endif // CONFIG_PALETTE
11395
hui su5db97432016-10-14 16:10:14 -070011396#if CONFIG_FILTER_INTRA
11397 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11398 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11399#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011400 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011401 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011402 mbmi->uv_mode = DC_PRED;
11403 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011404 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011405#if CONFIG_GLOBAL_MOTION
11406 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011407 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011408 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11409 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011410 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011411#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011412 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011413#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011414 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011415 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011416
Yaowu Xuc27fc142016-08-22 16:08:15 -070011417 mbmi->ref_mv_idx = 0;
11418 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011419
Yue Chendead17d2017-04-20 16:19:39 -070011420 mbmi->motion_mode = SIMPLE_TRANSLATION;
11421#if CONFIG_MOTION_VAR
11422 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
11423#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070011424#if CONFIG_WARPED_MOTION
11425 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
11426 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
11427 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
11428 }
11429#endif
Yue Chendead17d2017-04-20 16:19:39 -070011430
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011431 set_default_interp_filters(mbmi, cm->interp_filter);
11432
11433 if (cm->interp_filter != SWITCHABLE) {
11434 best_filter = cm->interp_filter;
11435 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011436 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011437 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011438 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11439 int rs;
11440 int best_rs = INT_MAX;
11441 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11442#if CONFIG_DUAL_FILTER
11443 int k;
11444 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11445#else
11446 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011447#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011448 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011449 if (rs < best_rs) {
11450 best_rs = rs;
11451#if CONFIG_DUAL_FILTER
11452 best_filter = mbmi->interp_filter[0];
11453#else
11454 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011455#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011456 }
11457 }
11458 }
11459 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011460// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070011461#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011462 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011463#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011464 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011465#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011466 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011467
11468 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011469 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011470
11471 // Estimate the reference frame signaling cost and add it
11472 // to the rolling cost variable.
11473 rate2 += ref_costs_single[LAST_FRAME];
11474 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11475
11476 rd_cost->rate = rate2;
11477 rd_cost->dist = distortion2;
11478 rd_cost->rdcost = this_rd;
11479
11480 if (this_rd >= best_rd_so_far) {
11481 rd_cost->rate = INT_MAX;
11482 rd_cost->rdcost = INT64_MAX;
11483 return;
11484 }
11485
11486#if CONFIG_DUAL_FILTER
11487 assert((cm->interp_filter == SWITCHABLE) ||
11488 (cm->interp_filter == mbmi->interp_filter[0]));
11489#else
11490 assert((cm->interp_filter == SWITCHABLE) ||
11491 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011492#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011493
Yaowu Xuf883b422016-08-30 14:01:10 -070011494 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11495 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011496
Yaowu Xuf883b422016-08-30 14:01:10 -070011497 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011498
11499 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11500}
11501
Urvang Joshi52648442016-10-13 17:27:51 -070011502void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11503 TileDataEnc *tile_data, struct macroblock *x,
11504 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011505 struct RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011506#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011507 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011508#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011509 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11510 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011511 const AV1_COMMON *const cm = &cpi->common;
11512 const RD_OPT *const rd_opt = &cpi->rd;
11513 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011514 MACROBLOCKD *const xd = &x->e_mbd;
11515 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11516 const struct segmentation *const seg = &cm->seg;
11517 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11518 unsigned char segment_id = mbmi->segment_id;
11519 int comp_pred, i;
11520 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11521 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11522 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11523 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011524 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011525#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011526 AOM_LAST2_FLAG,
11527 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011528#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011529 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011530#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011531 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011532#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011533 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011534 };
11535 int64_t best_rd = best_rd_so_far;
11536 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11537 int64_t best_pred_diff[REFERENCE_MODES];
11538 int64_t best_pred_rd[REFERENCE_MODES];
11539 MB_MODE_INFO best_mbmode;
11540 int ref_index, best_ref_index = 0;
11541 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11542 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011543 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011544#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011545 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011546#else
James Zern7b9407a2016-05-18 23:48:05 -070011547 InterpFilter tmp_best_filter = SWITCHABLE;
Fergus Simpson4063a682017-02-28 16:52:22 -080011548#endif // CONFIG_DUAL_FILTER
Jingning Han3f167252016-06-07 16:11:42 -070011549 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11550 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011551 int skip_uv;
11552 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011553 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011554 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011555 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011556 b_mode_info best_bmodes[4];
11557 int best_skip2 = 0;
11558 int ref_frame_skip_mask[2] = { 0 };
11559 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011560 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011561#if CONFIG_PVQ
11562 od_rollback_buffer pre_buf;
11563
11564 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011565#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070011566
11567#if CONFIG_SUPERTX
11568 best_rd_so_far = INT64_MAX;
11569 best_rd = best_rd_so_far;
11570 best_yrd = best_rd_so_far;
11571#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011572 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011573
hui su5db97432016-10-14 16:10:14 -070011574#if CONFIG_FILTER_INTRA
11575 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11576 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11577#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011578 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011579#if CONFIG_EXT_INTER
Sarah Parker2d0e9b72017-05-04 01:34:16 +000011580 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011581 mbmi->use_wedge_interintra = 0;
11582#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011583#if CONFIG_WARPED_MOTION
11584 mbmi->num_proj_ref[0] = 0;
11585 mbmi->num_proj_ref[1] = 0;
11586#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011587
11588 for (i = 0; i < 4; i++) {
11589 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011590 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11591 seg_mvs[i][j].as_int = INVALID_MV;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011592 }
11593
11594 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11595 &comp_mode_p);
11596
11597 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11598 rate_uv_intra = INT_MAX;
11599
11600 rd_cost->rate = INT_MAX;
11601#if CONFIG_SUPERTX
11602 *returnrate_nocoef = INT_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -080011603#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011604
11605 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11606 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011607#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011608 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011609#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011610 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11611 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11612 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11613 } else {
11614 ref_frame_skip_mask[0] |= (1 << ref_frame);
11615 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11616 }
11617 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11618#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011619#endif // CONFIG_EXT_INTER
11620 frame_mv[ZEROMV][ref_frame].as_int = 0;
11621 }
11622
Urvang Joshib100db72016-10-12 16:28:56 -070011623#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011624 mbmi->palette_mode_info.palette_size[0] = 0;
11625 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011626#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011627
11628 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11629 int mode_excluded = 0;
11630 int64_t this_rd = INT64_MAX;
11631 int disable_skip = 0;
11632 int compmode_cost = 0;
11633 int rate2 = 0, rate_y = 0, rate_uv = 0;
11634 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11635 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011636 int this_skip2 = 0;
11637 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011638
Yushin Cho77bba8d2016-11-04 16:36:56 -070011639#if CONFIG_PVQ
11640 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011641#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -070011642
Yaowu Xuf883b422016-08-30 14:01:10 -070011643 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11644 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011645
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011646 mbmi->ref_mv_idx = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011647
Yaowu Xuc27fc142016-08-22 16:08:15 -070011648 // Look at the reference frame of the best mode so far and set the
11649 // skip mask to look at a subset of the remaining modes.
11650 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11651 if (ref_index == 3) {
11652 switch (best_mbmode.ref_frame[0]) {
11653 case INTRA_FRAME: break;
11654 case LAST_FRAME:
11655 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11656#if CONFIG_EXT_REFS
11657 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11658 (1 << BWDREF_FRAME) |
11659#endif // CONFIG_EXT_REFS
11660 (1 << ALTREF_FRAME);
11661 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11662 break;
11663#if CONFIG_EXT_REFS
11664 case LAST2_FRAME:
11665 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11666 (1 << GOLDEN_FRAME) |
11667 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11668 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11669 break;
11670 case LAST3_FRAME:
11671 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11672 (1 << GOLDEN_FRAME) |
11673 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11674 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11675 break;
11676#endif // CONFIG_EXT_REFS
11677 case GOLDEN_FRAME:
11678 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11679#if CONFIG_EXT_REFS
11680 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11681 (1 << BWDREF_FRAME) |
11682#endif // CONFIG_EXT_REFS
11683 (1 << ALTREF_FRAME);
11684 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11685 break;
11686#if CONFIG_EXT_REFS
11687 case BWDREF_FRAME:
11688 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11689 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11690 (1 << ALTREF_FRAME);
11691 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11692 break;
11693#endif // CONFIG_EXT_REFS
11694 case ALTREF_FRAME:
11695 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11696#if CONFIG_EXT_REFS
11697 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11698 (1 << BWDREF_FRAME) |
11699#endif // CONFIG_EXT_REFS
11700 (1 << GOLDEN_FRAME);
11701#if CONFIG_EXT_REFS
11702 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11703#endif // CONFIG_EXT_REFS
11704 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011705 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011706 case TOTAL_REFS_PER_FRAME:
11707 assert(0 && "Invalid Reference frame");
11708 break;
11709 }
11710 }
11711 }
11712
11713 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011714 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011715 continue;
11716
11717 // Test best rd so far against threshold for trying this mode.
11718 if (!internal_active_edge &&
11719 rd_less_than_thresh(best_rd,
11720 rd_opt->threshes[segment_id][bsize][ref_index],
11721 tile_data->thresh_freq_fact[bsize][ref_index]))
11722 continue;
11723
Yunqing Wangff4fa062017-04-21 10:56:08 -070011724 // This is only used in motion vector unit test.
11725 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
11726
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020011727#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
11728#if CONFIG_EXT_REFS
11729 if (cpi->oxcf.pass == 0) {
11730 // Complexity-compression trade-offs
11731 // if (ref_frame == ALTREF_FRAME) continue;
11732 // if (ref_frame == BWDREF_FRAME) continue;
11733 if (second_ref_frame == ALTREF_FRAME) continue;
11734 // if (second_ref_frame == BWDREF_FRAME) continue;
11735 }
11736#endif
11737#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011738 comp_pred = second_ref_frame > INTRA_FRAME;
11739 if (comp_pred) {
11740 if (!cpi->allow_comp_inter_inter) continue;
11741 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11742 // Do not allow compound prediction if the segment level reference frame
11743 // feature is in use as in this case there can only be one reference.
11744 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11745
11746 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11747 best_mbmode.ref_frame[0] == INTRA_FRAME)
11748 continue;
11749 }
11750
11751 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11752 // sub8x8 blocks.
11753 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011754 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011755 continue;
11756
11757 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011758 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011759 continue;
11760
11761 if (comp_pred)
11762 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11763 else if (ref_frame != INTRA_FRAME)
11764 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11765
11766 // If the segment reference frame feature is enabled....
11767 // then do nothing if the current ref frame is not allowed..
11768 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11769 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11770 continue;
11771 // Disable this drop out case if the ref frame
11772 // segment level feature is enabled for this segment. This is to
11773 // prevent the possibility that we end up unable to pick any mode.
11774 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11775 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11776 // unless ARNR filtering is enabled in which case we want
11777 // an unfiltered alternative. We allow near/nearest as well
11778 // because they may result in zero-zero MVs but be cheaper.
11779 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11780 continue;
11781 }
11782
11783 mbmi->tx_size = TX_4X4;
11784 mbmi->uv_mode = DC_PRED;
11785 mbmi->ref_frame[0] = ref_frame;
11786 mbmi->ref_frame[1] = second_ref_frame;
11787// Evaluate all sub-pel filters irrespective of whether we can use
11788// them for this frame.
11789#if CONFIG_DUAL_FILTER
11790 for (i = 0; i < 4; ++i)
11791 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11792 ? EIGHTTAP_REGULAR
11793 : cm->interp_filter;
11794#else
11795 mbmi->interp_filter =
11796 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011797#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011798 x->skip = 0;
11799 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11800
11801 // Select prediction reference frames.
11802 for (i = 0; i < MAX_MB_PLANE; i++) {
11803 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11804 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11805 }
11806
11807#if CONFIG_VAR_TX
11808 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011809 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -080011810#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011811
11812 if (ref_frame == INTRA_FRAME) {
11813 int rate;
11814 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011815 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011816 continue;
11817 rate2 += rate;
11818 rate2 += intra_cost_penalty;
11819 distortion2 += distortion_y;
11820
11821 if (rate_uv_intra == INT_MAX) {
11822 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11823 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11824 }
11825 rate2 += rate_uv_intra;
11826 rate_uv = rate_uv_tokenonly;
11827 distortion2 += dist_uv;
11828 distortion_uv = dist_uv;
11829 mbmi->uv_mode = mode_uv;
11830 } else {
11831 int rate;
11832 int64_t distortion;
11833 int64_t this_rd_thresh;
11834 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11835 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11836 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11837 int tmp_best_skippable = 0;
11838 int switchable_filter_index;
11839 int_mv *second_ref =
11840 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11841 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11842 MB_MODE_INFO tmp_best_mbmode;
11843#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011844 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011845#else
11846 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
Fergus Simpson4063a682017-02-28 16:52:22 -080011847#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011848 int pred_exists = 0;
11849 int uv_skippable;
11850#if CONFIG_EXT_INTER
11851 int_mv compound_seg_newmvs[4][2];
11852 for (i = 0; i < 4; i++) {
11853 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11854 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11855 }
11856#endif // CONFIG_EXT_INTER
11857
11858 this_rd_thresh = (ref_frame == LAST_FRAME)
11859 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11860 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11861#if CONFIG_EXT_REFS
11862 this_rd_thresh = (ref_frame == LAST2_FRAME)
11863 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11864 : this_rd_thresh;
11865 this_rd_thresh = (ref_frame == LAST3_FRAME)
11866 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11867 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011868 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11869 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11870 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011871#endif // CONFIG_EXT_REFS
11872 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11873 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11874 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011875
11876 // TODO(any): Add search of the tx_type to improve rd performance at the
11877 // expense of speed.
11878 mbmi->tx_type = DCT_DCT;
11879
11880 if (cm->interp_filter != BILINEAR) {
11881#if CONFIG_DUAL_FILTER
11882 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11883 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11884 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11885 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11886#else
11887 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011888#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011889 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11890#if CONFIG_DUAL_FILTER
11891 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11892#else
11893 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011894#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011895 } else if (sf->adaptive_pred_interp_filter == 1 &&
11896 ctx->pred_interp_filter < SWITCHABLE) {
11897#if CONFIG_DUAL_FILTER
11898 tmp_best_filter[0] = ctx->pred_interp_filter;
11899#else
11900 tmp_best_filter = ctx->pred_interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011901#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011902 } else if (sf->adaptive_pred_interp_filter == 2) {
11903#if CONFIG_DUAL_FILTER
11904 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
11905 ? ctx->pred_interp_filter
11906 : 0;
11907#else
11908 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
11909 ? ctx->pred_interp_filter
11910 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011911#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011912 } else {
11913#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011914 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011915#else
Angie Chiang5678ad92016-11-21 09:38:40 -080011916 const int filter_set_size = SWITCHABLE_FILTERS;
Fergus Simpson4063a682017-02-28 16:52:22 -080011917#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011918 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080011919 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011920 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011921 int newbest, rs;
11922 int64_t rs_rd;
11923 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
11924#if CONFIG_DUAL_FILTER
11925 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
11926 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
11927 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
11928 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
11929#else
11930 mbmi->interp_filter = switchable_filter_index;
Fergus Simpson4063a682017-02-28 16:52:22 -080011931#endif // CONFIG_DUAL_FILTER
Yushin Cho482016d2017-01-06 14:06:13 -080011932 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011933 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11934 &rate, &rate_y, &distortion, &skippable, &total_sse,
11935 (int)this_rd_thresh, seg_mvs,
11936#if CONFIG_EXT_INTER
11937 compound_seg_newmvs,
11938#endif // CONFIG_EXT_INTER
11939 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011940 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070011941 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011942 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
11943 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
11944
11945 newbest = (tmp_rd < tmp_best_rd);
11946 if (newbest) {
11947#if CONFIG_DUAL_FILTER
11948 tmp_best_filter[0] = mbmi->interp_filter[0];
11949 tmp_best_filter[1] = mbmi->interp_filter[1];
11950 tmp_best_filter[2] = mbmi->interp_filter[2];
11951 tmp_best_filter[3] = mbmi->interp_filter[3];
11952#else
11953 tmp_best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011954#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011955 tmp_best_rd = tmp_rd;
11956 }
11957 if ((newbest && cm->interp_filter == SWITCHABLE) ||
11958 (
11959#if CONFIG_DUAL_FILTER
11960 mbmi->interp_filter[0] == cm->interp_filter
11961#else
11962 mbmi->interp_filter == cm->interp_filter
Fergus Simpson4063a682017-02-28 16:52:22 -080011963#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011964 && cm->interp_filter != SWITCHABLE)) {
11965 tmp_best_rdu = tmp_rd;
11966 tmp_best_rate = rate;
11967 tmp_best_ratey = rate_y;
11968 tmp_best_distortion = distortion;
11969 tmp_best_sse = total_sse;
11970 tmp_best_skippable = skippable;
11971 tmp_best_mbmode = *mbmi;
11972 for (i = 0; i < 4; i++) {
11973 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
11974 }
11975 pred_exists = 1;
11976 }
11977 } // switchable_filter_index loop
11978 }
11979 }
11980
11981 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
11982
11983#if CONFIG_DUAL_FILTER
11984 mbmi->interp_filter[0] =
11985 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
11986 : cm->interp_filter);
11987 mbmi->interp_filter[1] =
11988 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
11989 : cm->interp_filter);
11990 mbmi->interp_filter[2] =
11991 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
11992 : cm->interp_filter);
11993 mbmi->interp_filter[3] =
11994 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
11995 : cm->interp_filter);
11996#else
11997 mbmi->interp_filter =
11998 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
11999 : cm->interp_filter);
Fergus Simpson4063a682017-02-28 16:52:22 -080012000#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012001
12002 if (!pred_exists) {
12003 // Handles the special case when a filter that is not in the
12004 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080012005 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070012006 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
12007 &rate, &rate_y, &distortion, &skippable, &total_sse,
12008 (int)this_rd_thresh, seg_mvs,
12009#if CONFIG_EXT_INTER
12010 compound_seg_newmvs,
12011#endif // CONFIG_EXT_INTER
12012 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012013 if (tmp_rd == INT64_MAX) continue;
12014 } else {
12015 total_sse = tmp_best_sse;
12016 rate = tmp_best_rate;
12017 rate_y = tmp_best_ratey;
12018 distortion = tmp_best_distortion;
12019 skippable = tmp_best_skippable;
12020 *mbmi = tmp_best_mbmode;
12021 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
12022 }
12023 // Add in the cost of the transform type
12024 if (!xd->lossless[mbmi->segment_id]) {
12025 int rate_tx_type = 0;
12026#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080012027 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
12028 1) {
12029 const int eset =
12030 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012031 rate_tx_type =
12032 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
12033 }
12034#else
12035 if (mbmi->tx_size < TX_32X32) {
12036 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
12037 }
Fergus Simpson4063a682017-02-28 16:52:22 -080012038#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012039 rate += rate_tx_type;
12040 rate_y += rate_tx_type;
12041 }
12042
12043 rate2 += rate;
12044 distortion2 += distortion;
12045
12046 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070012047 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012048
12049 if (!mode_excluded)
12050 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
12051 : cm->reference_mode == COMPOUND_REFERENCE;
12052
Yaowu Xuf883b422016-08-30 14:01:10 -070012053 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012054
12055 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070012056 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012057 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
12058
12059 if (tmp_best_rdu > 0) {
12060 // If even the 'Y' rd value of split is higher than best so far
12061 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070012062 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070012063 RD_STATS rd_stats_uv;
Jingning Hanc44009c2017-05-06 11:36:49 -070012064 av1_build_inter_predictors_sbuv(cm, &x->e_mbd, mi_row, mi_col, NULL,
David Barkerac37fa32016-12-02 12:30:21 +000012065 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012066#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012067 is_cost_valid_uv =
12068 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080012069#else
12070 is_cost_valid_uv =
12071 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Fergus Simpson4063a682017-02-28 16:52:22 -080012072#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070012073 rate_uv = rd_stats_uv.rate;
12074 distortion_uv = rd_stats_uv.dist;
12075 uv_skippable = rd_stats_uv.skip;
12076 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080012077
Angie Chiangb5dda482016-11-02 16:19:58 -070012078 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012079 rate2 += rate_uv;
12080 distortion2 += distortion_uv;
12081 skippable = skippable && uv_skippable;
12082 total_sse += uv_sse;
12083 } else {
12084 continue;
12085 }
12086 }
12087
12088 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
12089
12090 // Estimate the reference frame signaling cost and add it
12091 // to the rolling cost variable.
12092 if (second_ref_frame > INTRA_FRAME) {
12093 rate2 += ref_costs_comp[ref_frame];
12094#if CONFIG_EXT_REFS
12095 rate2 += ref_costs_comp[second_ref_frame];
12096#endif // CONFIG_EXT_REFS
12097 } else {
12098 rate2 += ref_costs_single[ref_frame];
12099 }
12100
12101 if (!disable_skip) {
12102 // Skip is never coded at the segment level for sub8x8 blocks and instead
12103 // always coded in the bitstream at the mode info level.
12104
12105 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
12106 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
12107 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
12108 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012109 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012110 } else {
12111 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070012112 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012113 distortion2 = total_sse;
12114 assert(total_sse >= 0);
12115 rate2 -= (rate_y + rate_uv);
12116 rate_y = 0;
12117 rate_uv = 0;
12118 this_skip2 = 1;
12119 }
12120 } else {
12121 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012122 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012123 }
12124
12125 // Calculate the final RD estimate for this mode.
12126 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
12127 }
12128
12129 if (!disable_skip && ref_frame == INTRA_FRAME) {
12130 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070012131 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012132 }
12133
12134 // Did this mode help.. i.e. is it the new best mode
12135 if (this_rd < best_rd || x->skip) {
12136 if (!mode_excluded) {
12137 // Note index of best mode so far
12138 best_ref_index = ref_index;
12139
12140 if (ref_frame == INTRA_FRAME) {
12141 /* required for left and above block mv */
12142 mbmi->mv[0].as_int = 0;
12143 }
12144
12145 rd_cost->rate = rate2;
12146#if CONFIG_SUPERTX
12147 *returnrate_nocoef = rate2 - rate_y - rate_uv;
12148 if (!disable_skip)
12149 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070012150 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
12151 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
12152 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012153 assert(*returnrate_nocoef > 0);
12154#endif // CONFIG_SUPERTX
12155 rd_cost->dist = distortion2;
12156 rd_cost->rdcost = this_rd;
12157 best_rd = this_rd;
12158 best_yrd =
12159 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
12160 best_mbmode = *mbmi;
12161 best_skip2 = this_skip2;
12162
12163#if CONFIG_VAR_TX
12164 for (i = 0; i < MAX_MB_PLANE; ++i)
12165 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080012166#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012167
12168 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070012169 }
12170 }
12171
12172 /* keep record of best compound/single-only prediction */
12173 if (!disable_skip && ref_frame != INTRA_FRAME) {
12174 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
12175
12176 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
12177 single_rate = rate2 - compmode_cost;
12178 hybrid_rate = rate2;
12179 } else {
12180 single_rate = rate2;
12181 hybrid_rate = rate2 + compmode_cost;
12182 }
12183
12184 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
12185 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
12186
12187 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
12188 best_pred_rd[SINGLE_REFERENCE] = single_rd;
12189 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
12190 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
12191
12192 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
12193 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
12194 }
12195
Yaowu Xuc27fc142016-08-22 16:08:15 -070012196 if (x->skip && !comp_pred) break;
12197 }
12198
12199 if (best_rd >= best_rd_so_far) {
12200 rd_cost->rate = INT_MAX;
12201 rd_cost->rdcost = INT64_MAX;
12202#if CONFIG_SUPERTX
12203 *returnrate_nocoef = INT_MAX;
12204#endif // CONFIG_SUPERTX
12205 return;
12206 }
12207
Yaowu Xuc27fc142016-08-22 16:08:15 -070012208 if (best_rd == INT64_MAX) {
12209 rd_cost->rate = INT_MAX;
12210 rd_cost->dist = INT64_MAX;
12211 rd_cost->rdcost = INT64_MAX;
12212#if CONFIG_SUPERTX
12213 *returnrate_nocoef = INT_MAX;
12214#endif // CONFIG_SUPERTX
12215 return;
12216 }
12217
12218#if CONFIG_DUAL_FILTER
12219 assert((cm->interp_filter == SWITCHABLE) ||
12220 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12221 !is_inter_block(&best_mbmode));
12222#else
12223 assert((cm->interp_filter == SWITCHABLE) ||
12224 (cm->interp_filter == best_mbmode.interp_filter) ||
12225 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080012226#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012227
Yaowu Xuf883b422016-08-30 14:01:10 -070012228 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12229 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012230
12231 // macroblock modes
12232 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012233#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012234 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080012235#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012236
12237 x->skip |= best_skip2;
12238 if (!is_inter_block(&best_mbmode)) {
12239 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12240 } else {
12241 for (i = 0; i < 4; ++i)
12242 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12243
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012244 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12245 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012246 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12247 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012248 }
12249
Yue Chen19e7aa82016-11-30 14:05:39 -080012250// Note: this section is needed since the mode may have been forced to ZEROMV
12251#if CONFIG_GLOBAL_MOTION
12252 if (mbmi->mode == ZEROMV
12253#if CONFIG_EXT_INTER
12254 || mbmi->mode == ZERO_ZEROMV
12255#endif // CONFIG_EXT_INTER
12256 ) {
12257 if (is_nontrans_global_motion(xd)) {
12258#if CONFIG_DUAL_FILTER
12259 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12260 ? EIGHTTAP_REGULAR
12261 : cm->interp_filter;
12262 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12263 ? EIGHTTAP_REGULAR
12264 : cm->interp_filter;
12265#else
12266 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12267 : cm->interp_filter;
12268#endif // CONFIG_DUAL_FILTER
12269 }
12270 }
12271#endif // CONFIG_GLOBAL_MOTION
12272
Yaowu Xuc27fc142016-08-22 16:08:15 -070012273 for (i = 0; i < REFERENCE_MODES; ++i) {
12274 if (best_pred_rd[i] == INT64_MAX)
12275 best_pred_diff[i] = INT_MIN;
12276 else
12277 best_pred_diff[i] = best_rd - best_pred_rd[i];
12278 }
12279
12280 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12281}
12282
Yue Chencb60b182016-10-13 15:18:22 -070012283#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012284// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012285//
12286// The OBMC predictor is computed as:
12287//
12288// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012289// AOM_BLEND_A64(Mh(x),
12290// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012291// PLeft(x, y))
12292//
Yaowu Xuf883b422016-08-30 14:01:10 -070012293// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012294// rounding, this can be written as:
12295//
Yaowu Xuf883b422016-08-30 14:01:10 -070012296// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012297// Mh(x) * Mv(y) * P(x,y) +
12298// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012299// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012300//
12301// Where :
12302//
Yaowu Xuf883b422016-08-30 14:01:10 -070012303// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12304// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012305//
12306// This function computes 'wsrc' and 'mask' as:
12307//
12308// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012309// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012310// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012311// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012312//
12313// mask(x, y) = Mh(x) * Mv(y)
12314//
12315// These can then be used to efficiently approximate the error for any
12316// predictor P in the context of the provided neighbouring predictors by
12317// computing:
12318//
12319// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012320// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012321//
Yaowu Xuf883b422016-08-30 14:01:10 -070012322static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012323 const MACROBLOCKD *xd, int mi_row,
12324 int mi_col, const uint8_t *above,
12325 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012326 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012327 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12328 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012329 const int bw = xd->n8_w << MI_SIZE_LOG2;
12330 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012331 int32_t *mask_buf = x->mask_buf;
12332 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012333 const int wsrc_stride = bw;
12334 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012335 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012336#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012337 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12338#else
12339 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012340#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012341
12342 // plane 0 should not be subsampled
12343 assert(xd->plane[0].subsampling_x == 0);
12344 assert(xd->plane[0].subsampling_y == 0);
12345
Yaowu Xuf883b422016-08-30 14:01:10 -070012346 av1_zero_array(wsrc_buf, bw * bh);
12347 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012348
12349 // handle above row
12350 if (xd->up_available) {
12351 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012352 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012353 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012354 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012355 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
12356 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012357
12358 assert(miw > 0);
12359
12360 i = 0;
12361 do { // for each mi in the above row
12362 const int mi_col_offset = i;
12363 const MB_MODE_INFO *const above_mbmi =
12364 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012365 const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012366 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012367 const int neighbor_bw = mi_step * MI_SIZE;
12368
12369 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012370 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
12371 neighbor_count += 2;
12372 else
12373 neighbor_count++;
12374 if (neighbor_count > neighbor_limit) break;
12375
Yaowu Xuc27fc142016-08-22 16:08:15 -070012376 const int tmp_stride = above_stride;
12377 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12378 int32_t *mask = mask_buf + (i * MI_SIZE);
12379
12380 if (!is_hbd) {
12381 const uint8_t *tmp = above;
12382
12383 for (row = 0; row < overlap; ++row) {
12384 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012385 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012386 for (col = 0; col < neighbor_bw; ++col) {
12387 wsrc[col] = m1 * tmp[col];
12388 mask[col] = m0;
12389 }
12390 wsrc += wsrc_stride;
12391 mask += mask_stride;
12392 tmp += tmp_stride;
12393 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012394#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012395 } else {
12396 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12397
12398 for (row = 0; row < overlap; ++row) {
12399 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012400 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012401 for (col = 0; col < neighbor_bw; ++col) {
12402 wsrc[col] = m1 * tmp[col];
12403 mask[col] = m0;
12404 }
12405 wsrc += wsrc_stride;
12406 mask += mask_stride;
12407 tmp += tmp_stride;
12408 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012409#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012410 }
12411 }
12412
12413 above += neighbor_bw;
12414 i += mi_step;
12415 } while (i < miw);
12416 }
12417
12418 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012419 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12420 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012421 }
12422
12423 // handle left column
12424 if (xd->left_available) {
12425 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012426 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012427 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012428 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012429 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
12430 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012431
12432 assert(mih > 0);
12433
12434 i = 0;
12435 do { // for each mi in the left column
12436 const int mi_row_offset = i;
12437 const MB_MODE_INFO *const left_mbmi =
12438 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012439 const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012440 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012441 const int neighbor_bh = mi_step * MI_SIZE;
12442
12443 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012444 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
12445 neighbor_count += 2;
12446 else
12447 neighbor_count++;
12448 if (neighbor_count > neighbor_limit) break;
12449
Yaowu Xuc27fc142016-08-22 16:08:15 -070012450 const int tmp_stride = left_stride;
12451 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12452 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12453
12454 if (!is_hbd) {
12455 const uint8_t *tmp = left;
12456
12457 for (row = 0; row < neighbor_bh; ++row) {
12458 for (col = 0; col < overlap; ++col) {
12459 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012460 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12461 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12462 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12463 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012464 }
12465 wsrc += wsrc_stride;
12466 mask += mask_stride;
12467 tmp += tmp_stride;
12468 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012469#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012470 } else {
12471 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
12472
12473 for (row = 0; row < neighbor_bh; ++row) {
12474 for (col = 0; col < overlap; ++col) {
12475 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012476 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12477 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12478 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12479 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012480 }
12481 wsrc += wsrc_stride;
12482 mask += mask_stride;
12483 tmp += tmp_stride;
12484 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012485#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012486 }
12487 }
12488
12489 left += neighbor_bh * left_stride;
12490 i += mi_step;
12491 } while (i < mih);
12492 }
12493
12494 if (!is_hbd) {
12495 const uint8_t *src = x->plane[0].src.buf;
12496
12497 for (row = 0; row < bh; ++row) {
12498 for (col = 0; col < bw; ++col) {
12499 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12500 }
12501 wsrc_buf += wsrc_stride;
12502 src += x->plane[0].src.stride;
12503 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012504#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012505 } else {
12506 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12507
12508 for (row = 0; row < bh; ++row) {
12509 for (col = 0; col < bw; ++col) {
12510 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12511 }
12512 wsrc_buf += wsrc_stride;
12513 src += x->plane[0].src.stride;
12514 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012515#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012516 }
12517}
Yue Chenf27b1602017-01-13 11:11:43 -080012518
12519#if CONFIG_NCOBMC
12520void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12521 int mi_row, int mi_col) {
12522 const AV1_COMMON *const cm = &cpi->common;
12523 MACROBLOCKD *const xd = &x->e_mbd;
12524 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12525 MB_MODE_INFO backup_mbmi;
12526 BLOCK_SIZE bsize = mbmi->sb_type;
12527 int ref, skip_blk, backup_skip = x->skip;
12528 int64_t rd_causal;
12529 RD_STATS rd_stats_y, rd_stats_uv;
12530 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12531 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12532
12533 // Recompute the best causal predictor and rd
12534 mbmi->motion_mode = SIMPLE_TRANSLATION;
12535 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12536 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12537 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12538 assert(cfg != NULL);
12539 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12540 &xd->block_refs[ref]->sf);
12541 }
Jingning Han91d9a792017-04-18 12:01:52 -070012542 av1_setup_dst_planes(x->e_mbd.plane, bsize,
12543 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080012544
Jingning Hanc44009c2017-05-06 11:36:49 -070012545 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chenf27b1602017-01-13 11:11:43 -080012546
12547 av1_subtract_plane(x, bsize, 0);
12548 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12549 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12550 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12551 if (rd_stats_y.skip && rd_stats_uv.skip) {
12552 rd_stats_y.rate = rate_skip1;
12553 rd_stats_uv.rate = 0;
12554 rd_stats_y.dist = rd_stats_y.sse;
12555 rd_stats_uv.dist = rd_stats_uv.sse;
12556 skip_blk = 0;
12557 } else if (RDCOST(x->rdmult, x->rddiv,
12558 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12559 (rd_stats_y.dist + rd_stats_uv.dist)) >
12560 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12561 (rd_stats_y.sse + rd_stats_uv.sse))) {
12562 rd_stats_y.rate = rate_skip1;
12563 rd_stats_uv.rate = 0;
12564 rd_stats_y.dist = rd_stats_y.sse;
12565 rd_stats_uv.dist = rd_stats_uv.sse;
12566 skip_blk = 1;
12567 } else {
12568 rd_stats_y.rate += rate_skip0;
12569 skip_blk = 0;
12570 }
12571 backup_skip = skip_blk;
12572 backup_mbmi = *mbmi;
12573 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12574 (rd_stats_y.dist + rd_stats_uv.dist));
12575 rd_causal += RDCOST(x->rdmult, x->rddiv,
12576 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12577
12578 // Check non-causal mode
12579 mbmi->motion_mode = OBMC_CAUSAL;
12580 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12581
12582 av1_subtract_plane(x, bsize, 0);
12583 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12584 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12585 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12586 if (rd_stats_y.skip && rd_stats_uv.skip) {
12587 rd_stats_y.rate = rate_skip1;
12588 rd_stats_uv.rate = 0;
12589 rd_stats_y.dist = rd_stats_y.sse;
12590 rd_stats_uv.dist = rd_stats_uv.sse;
12591 skip_blk = 0;
12592 } else if (RDCOST(x->rdmult, x->rddiv,
12593 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12594 (rd_stats_y.dist + rd_stats_uv.dist)) >
12595 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12596 (rd_stats_y.sse + rd_stats_uv.sse))) {
12597 rd_stats_y.rate = rate_skip1;
12598 rd_stats_uv.rate = 0;
12599 rd_stats_y.dist = rd_stats_y.sse;
12600 rd_stats_uv.dist = rd_stats_uv.sse;
12601 skip_blk = 1;
12602 } else {
12603 rd_stats_y.rate += rate_skip0;
12604 skip_blk = 0;
12605 }
12606
12607 if (rd_causal >
12608 RDCOST(x->rdmult, x->rddiv,
12609 rd_stats_y.rate + rd_stats_uv.rate +
12610 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12611 (rd_stats_y.dist + rd_stats_uv.dist))) {
12612 x->skip = skip_blk;
12613 } else {
12614 *mbmi = backup_mbmi;
12615 x->skip = backup_skip;
12616 }
12617}
Fergus Simpson4063a682017-02-28 16:52:22 -080012618#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070012619#endif // CONFIG_MOTION_VAR