blob: 55e391c58ad83d8551008c5e9700540f3964fef1 [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
227 { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
228 { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
229 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
230 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
231 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
232 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
233 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
234 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
235 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
236
237#if CONFIG_EXT_REFS
238 { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
239 { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
240 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
241 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
242 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
243 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
244 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
247
248 { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
249 { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
250 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
251 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
252 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
253 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
254 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
257#endif // CONFIG_EXT_REFS
258
259 { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
260 { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
261 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
262 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
263 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
264 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
265 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
268
269#if CONFIG_EXT_REFS
270 { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
271 { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
272 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
273 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
274 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
275 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
276 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
277 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
278 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
279
280 { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
281 { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
282 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
283 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
284 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
285 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
286 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
287 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
288 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
289
290 { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
291 { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
292 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
293 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
294 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
295 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
296 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
297 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
298 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
299
300 { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
301 { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
302 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
303 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
304 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
305 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
306 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
307 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
308 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
309#endif // CONFIG_EXT_REFS
310
311#else // CONFIG_EXT_INTER
312
313 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
314 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
315#if CONFIG_EXT_REFS
316 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
317 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
318 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
319 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
320#endif // CONFIG_EXT_REFS
321 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
322 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
323
324#if CONFIG_EXT_REFS
325 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
326 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
327 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
328 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
329 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
330 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
331 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
332 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
333#endif // CONFIG_EXT_REFS
334
335 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
336#if CONFIG_EXT_REFS
337 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
338 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
339#endif // CONFIG_EXT_REFS
340 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
341
342#if CONFIG_EXT_REFS
343 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
344 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
345 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
346 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
347#endif // CONFIG_EXT_REFS
348
349#endif // CONFIG_EXT_INTER
350
Emil Keyder01770b32017-01-20 18:03:11 -0500351 { H_PRED, { INTRA_FRAME, NONE_FRAME } },
352 { V_PRED, { INTRA_FRAME, NONE_FRAME } },
353 { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
354 { D207_PRED, { INTRA_FRAME, NONE_FRAME } },
355 { D153_PRED, { INTRA_FRAME, NONE_FRAME } },
356 { D63_PRED, { INTRA_FRAME, NONE_FRAME } },
357 { D117_PRED, { INTRA_FRAME, NONE_FRAME } },
358 { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700359
360#if CONFIG_EXT_INTER
361 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
362 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
363 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
364 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
365
366#if CONFIG_EXT_REFS
367 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
368 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
369 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
370 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
371
372 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
373 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
374 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
375 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
376#endif // CONFIG_EXT_REFS
377
378 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
379 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
380 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
381 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
382
383#if CONFIG_EXT_REFS
384 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
385 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
386 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
387 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
388#endif // CONFIG_EXT_REFS
389
390 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
391 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
392 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
393 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
394#endif // CONFIG_EXT_INTER
395};
396
Yaowu Xuf883b422016-08-30 14:01:10 -0700397static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500398 { { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500400 { { LAST2_FRAME, NONE_FRAME } }, { { LAST3_FRAME, NONE_FRAME } },
401 { { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500403 { { GOLDEN_FRAME, NONE_FRAME } }, { { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404
405 { { LAST_FRAME, ALTREF_FRAME } },
406#if CONFIG_EXT_REFS
407 { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
408#endif // CONFIG_EXT_REFS
409 { { GOLDEN_FRAME, ALTREF_FRAME } },
410
411#if CONFIG_EXT_REFS
412 { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
413 { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
414#endif // CONFIG_EXT_REFS
415
Emil Keyder01770b32017-01-20 18:03:11 -0500416 { { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700417};
418
hui su5db97432016-10-14 16:10:14 -0700419#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420static INLINE int write_uniform_cost(int n, int v) {
hui su37499292017-04-26 09:49:53 -0700421 const int l = get_unsigned_bits(n);
422 const int m = (1 << l) - n;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700423 if (l == 0) return 0;
424 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700425 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700426 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700427 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700428}
hui su5db97432016-10-14 16:10:14 -0700429#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700430
431// constants for prune 1 and prune 2 decision boundaries
432#define FAST_EXT_TX_CORR_MID 0.0
433#define FAST_EXT_TX_EDST_MID 0.1
434#define FAST_EXT_TX_CORR_MARGIN 0.5
435#define FAST_EXT_TX_EDST_MARGIN 0.3
436
437static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
438 DCT_1D, ADST_1D, DCT_1D, ADST_1D,
439#if CONFIG_EXT_TX
440 FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
441 DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
442#endif // CONFIG_EXT_TX
443};
444
445static const TX_TYPE_1D htx_tab[TX_TYPES] = {
446 DCT_1D, DCT_1D, ADST_1D, ADST_1D,
447#if CONFIG_EXT_TX
448 DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
449 IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
450#endif // CONFIG_EXT_TX
451};
452
Yushin Cho7a428ba2017-01-12 16:28:49 -0800453#if CONFIG_DAALA_DIST
454static int od_compute_var_4x4(od_coeff *x, int stride) {
455 int sum;
456 int s2;
457 int i;
458 sum = 0;
459 s2 = 0;
460 for (i = 0; i < 4; i++) {
461 int j;
462 for (j = 0; j < 4; j++) {
463 int t;
464
465 t = x[i * stride + j];
466 sum += t;
467 s2 += t * t;
468 }
469 }
470 // TODO(yushin) : Check wheter any changes are required for high bit depth.
471 return (s2 - (sum * sum >> 4)) >> 4;
472}
473
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500474/* OD_DIST_LP_MID controls the frequency weighting filter used for computing
475 the distortion. For a value X, the filter is [1 X 1]/(X + 2) and
476 is applied both horizontally and vertically. For X=5, the filter is
477 a good approximation for the OD_QM8_Q4_HVS quantization matrix. */
478#define OD_DIST_LP_MID (5)
479#define OD_DIST_LP_NORM (OD_DIST_LP_MID + 2)
480
Yushin Cho7a428ba2017-01-12 16:28:49 -0800481static double od_compute_dist_8x8(int qm, int use_activity_masking, od_coeff *x,
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500482 od_coeff *y, od_coeff *e_lp, int stride) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800483 double sum;
484 int min_var;
485 double mean_var;
486 double var_stat;
487 double activity;
488 double calibration;
489 int i;
490 int j;
491 double vardist;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800492
493 vardist = 0;
494 OD_ASSERT(qm != OD_FLAT_QM);
Alex Converse76b89632017-03-20 11:47:12 -0700495 (void)qm;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800496#if 1
497 min_var = INT_MAX;
498 mean_var = 0;
499 for (i = 0; i < 3; i++) {
500 for (j = 0; j < 3; j++) {
501 int varx;
502 int vary;
503 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
504 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
505 min_var = OD_MINI(min_var, varx);
506 mean_var += 1. / (1 + varx);
507 /* The cast to (double) is to avoid an overflow before the sqrt.*/
508 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
509 }
510 }
511 /* We use a different variance statistic depending on whether activity
512 masking is used, since the harmonic mean appeared slghtly worse with
513 masking off. The calibration constant just ensures that we preserve the
514 rate compared to activity=1. */
515 if (use_activity_masking) {
516 calibration = 1.95;
517 var_stat = 9. / mean_var;
518 } else {
519 calibration = 1.62;
520 var_stat = min_var;
521 }
522 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
523 activity masking constant. */
524 activity = calibration * pow(.25 + var_stat, -1. / 6);
525#else
526 activity = 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800527#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800528 sum = 0;
529 for (i = 0; i < 8; i++) {
530 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500531 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800532 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500533 /* Normalize the filter to unit DC response. */
534 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
535 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800536 return activity * activity * (sum + vardist);
537}
538
539// Note : Inputs x and y are in a pixel domain
540static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
541 od_coeff *y, int bsize_w, int bsize_h,
542 int qindex) {
543 int i;
544 double sum;
545 sum = 0;
546
Yushin Cho7a428ba2017-01-12 16:28:49 -0800547 assert(bsize_w >= 8 && bsize_h >= 8);
548
549 if (qm == OD_FLAT_QM) {
550 for (i = 0; i < bsize_w * bsize_h; i++) {
551 double tmp;
552 tmp = x[i] - y[i];
553 sum += tmp * tmp;
554 }
555 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500556 int j;
557 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
558 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
559 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
560 int mid = OD_DIST_LP_MID;
561 for (i = 0; i < bsize_h; i++) {
562 for (j = 0; j < bsize_w; j++) {
563 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
564 }
565 }
566 for (i = 0; i < bsize_h; i++) {
567 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
568 tmp[i * bsize_w + bsize_w - 1] =
569 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
570 for (j = 1; j < bsize_w - 1; j++) {
571 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
572 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
573 }
574 }
575 for (j = 0; j < bsize_w; j++) {
576 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
577 e_lp[(bsize_h - 1) * bsize_w + j] =
578 mid * tmp[(bsize_h - 1) * bsize_w + j] +
579 2 * tmp[(bsize_h - 2) * bsize_w + j];
580 }
581 for (i = 1; i < bsize_h - 1; i++) {
582 for (j = 0; j < bsize_w; j++) {
583 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
584 tmp[(i - 1) * bsize_w + j] +
585 tmp[(i + 1) * bsize_w + j];
586 }
587 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800588 for (i = 0; i < bsize_h; i += 8) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800589 for (j = 0; j < bsize_w; j += 8) {
590 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500591 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
592 bsize_w);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800593 }
594 }
David Michael Barrd091b802017-01-21 16:05:46 +0900595 /* Scale according to linear regression against SSE, for 8x8 blocks. */
596 if (activity_masking) {
597 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
598 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
599 } else {
600 sum *= qindex >= 128
601 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
602 : qindex <= 43
603 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
604 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
605 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800606 }
607 return sum;
608}
609
610static int64_t av1_daala_dist(const uint8_t *src, int src_stride,
Yushin Cho4483e3d2017-04-18 19:41:20 -0700611 const uint8_t *dst, int dst_stride, int bsw,
612 int bsh, int qm, int use_activity_masking,
613 int qindex) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800614 int i, j;
615 int64_t d;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800616 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
617 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
618
619 assert(qm == OD_HVS_QM);
620
621 for (j = 0; j < bsh; j++)
622 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
623
624 for (j = 0; j < bsh; j++)
625 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
626
627 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
628 qindex);
629 return d;
630}
Fergus Simpson4063a682017-02-28 16:52:22 -0800631#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800632
Yaowu Xuf883b422016-08-30 14:01:10 -0700633static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse9f217762017-04-20 15:34:54 -0700634 const uint8_t *src, int src_stride,
635 const uint8_t *dst, int dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636 double *hordist, double *verdist) {
Alex Converse9f217762017-04-20 15:34:54 -0700637 const int bw = block_size_wide[bsize];
638 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 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 -0700640
641 const int f_index = bsize - BLOCK_16X16;
642 if (f_index < 0) {
Alex Converse9f217762017-04-20 15:34:54 -0700643 const int w_shift = bw == 8 ? 1 : 2;
644 const int h_shift = bh == 8 ? 1 : 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200645#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646 if (cpi->common.use_highbitdepth) {
Alex Converse9f217762017-04-20 15:34:54 -0700647 const uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
648 const uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
649 for (int i = 0; i < bh; ++i)
650 for (int j = 0; j < bw; ++j) {
651 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700652 esq[index] +=
653 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
654 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
655 }
656 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200657#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700658
Alex Converse9f217762017-04-20 15:34:54 -0700659 for (int i = 0; i < bh; ++i)
660 for (int j = 0; j < bw; ++j) {
661 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700662 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
663 (src[j + i * src_stride] - dst[j + i * dst_stride]);
664 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200665#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200667#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700668 } else {
Alex Converse9f217762017-04-20 15:34:54 -0700669 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
670 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
671 &esq[1]);
672 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
673 &esq[2]);
674 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
675 dst_stride, &esq[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676 src += bh / 4 * src_stride;
677 dst += bh / 4 * dst_stride;
678
Alex Converse9f217762017-04-20 15:34:54 -0700679 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
680 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
681 &esq[5]);
682 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
683 &esq[6]);
684 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
685 dst_stride, &esq[7]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700686 src += bh / 4 * src_stride;
687 dst += bh / 4 * dst_stride;
688
Alex Converse9f217762017-04-20 15:34:54 -0700689 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
690 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
691 &esq[9]);
692 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
693 &esq[10]);
694 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
695 dst_stride, &esq[11]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696 src += bh / 4 * src_stride;
697 dst += bh / 4 * dst_stride;
698
Alex Converse9f217762017-04-20 15:34:54 -0700699 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
700 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
701 &esq[13]);
702 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
703 &esq[14]);
704 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
705 dst_stride, &esq[15]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700706 }
707
Alex Converse9f217762017-04-20 15:34:54 -0700708 double total = (double)esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] +
709 esq[6] + esq[7] + esq[8] + esq[9] + esq[10] + esq[11] +
710 esq[12] + esq[13] + esq[14] + esq[15];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 if (total > 0) {
712 const double e_recip = 1.0 / total;
Alex Converse9f217762017-04-20 15:34:54 -0700713 hordist[0] = ((double)esq[0] + esq[4] + esq[8] + esq[12]) * e_recip;
714 hordist[1] = ((double)esq[1] + esq[5] + esq[9] + esq[13]) * e_recip;
715 hordist[2] = ((double)esq[2] + esq[6] + esq[10] + esq[14]) * e_recip;
716 verdist[0] = ((double)esq[0] + esq[1] + esq[2] + esq[3]) * e_recip;
717 verdist[1] = ((double)esq[4] + esq[5] + esq[6] + esq[7]) * e_recip;
718 verdist[2] = ((double)esq[8] + esq[9] + esq[10] + esq[11]) * e_recip;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700719 } else {
720 hordist[0] = verdist[0] = 0.25;
721 hordist[1] = verdist[1] = 0.25;
722 hordist[2] = verdist[2] = 0.25;
723 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700724}
725
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700726static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize,
727 const uint8_t *src, int src_stride,
728 const uint8_t *dst, int dst_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700729 int prune_bitmask = 0;
730 double svm_proj_h = 0, svm_proj_v = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700731 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
733 hdist, vdist);
734
735 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
736 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
737 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
738 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
739 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
740 prune_bitmask |= 1 << FLIPADST_1D;
741 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
742 prune_bitmask |= 1 << ADST_1D;
743
744 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
745 prune_bitmask |= 1 << (FLIPADST_1D + 8);
746 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
747 prune_bitmask |= 1 << (ADST_1D + 8);
748
749 return prune_bitmask;
750}
751
752#if CONFIG_EXT_TX
Alex Converse89912f92017-04-21 13:28:50 -0700753static void get_horver_correlation(const int16_t *diff, int stride, int w,
754 int h, double *hcorr, double *vcorr) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700755 // Returns hor/ver correlation coefficient
756 const int num = (h - 1) * (w - 1);
757 double num_r;
758 int i, j;
759 int64_t xy_sum = 0, xz_sum = 0;
760 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
761 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
762 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
763 *hcorr = *vcorr = 1;
764
765 assert(num > 0);
766 num_r = 1.0 / num;
767 for (i = 1; i < h; ++i) {
768 for (j = 1; j < w; ++j) {
769 const int16_t x = diff[i * stride + j];
770 const int16_t y = diff[i * stride + j - 1];
771 const int16_t z = diff[(i - 1) * stride + j];
772 xy_sum += x * y;
773 xz_sum += x * z;
774 x_sum += x;
775 y_sum += y;
776 z_sum += z;
777 x2_sum += x * x;
778 y2_sum += y * y;
779 z2_sum += z * z;
780 }
781 }
782 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
783 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
784 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
785 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
786 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
787 if (x_var_n > 0 && y_var_n > 0) {
788 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
789 *hcorr = *hcorr < 0 ? 0 : *hcorr;
790 }
791 if (x_var_n > 0 && z_var_n > 0) {
792 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
793 *vcorr = *vcorr < 0 ? 0 : *vcorr;
794 }
795}
796
Alex Converse89912f92017-04-21 13:28:50 -0700797int dct_vs_idtx(const int16_t *diff, int stride, int w, int h) {
798 double hcorr, vcorr;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700799 int prune_bitmask = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700800 get_horver_correlation(diff, stride, w, h, &hcorr, &vcorr);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700801
Alex Converse89912f92017-04-21 13:28:50 -0700802 if (vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700803 prune_bitmask |= 1 << IDTX_1D;
Alex Converse89912f92017-04-21 13:28:50 -0700804 else if (vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700805 prune_bitmask |= 1 << DCT_1D;
806
Alex Converse89912f92017-04-21 13:28:50 -0700807 if (hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700808 prune_bitmask |= 1 << (IDTX_1D + 8);
Alex Converse89912f92017-04-21 13:28:50 -0700809 else if (hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700810 prune_bitmask |= 1 << (DCT_1D + 8);
811 return prune_bitmask;
812}
813
814// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700815static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700816 MACROBLOCK *x, const MACROBLOCKD *xd,
817 int adst_flipadst, int dct_idtx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700818 int prune = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700819
Alex Converse89912f92017-04-21 13:28:50 -0700820 if (adst_flipadst) {
821 const struct macroblock_plane *const p = &x->plane[0];
822 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700823 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
Alex Converse89912f92017-04-21 13:28:50 -0700824 pd->dst.buf, pd->dst.stride);
825 }
826 if (dct_idtx) {
827 av1_subtract_plane(x, bsize, 0);
828 const struct macroblock_plane *const p = &x->plane[0];
829 const int bw = 4 << (b_width_log2_lookup[bsize]);
830 const int bh = 4 << (b_height_log2_lookup[bsize]);
831 prune |= dct_vs_idtx(p->src_diff, bw, bw, bh);
832 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833
834 return prune;
835}
836#endif // CONFIG_EXT_TX
837
838// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700839static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700840 const MACROBLOCK *x, const MACROBLOCKD *xd) {
841 const struct macroblock_plane *const p = &x->plane[0];
842 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
Alex Converse89912f92017-04-21 13:28:50 -0700844 pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700845}
846
Yaowu Xuf883b422016-08-30 14:01:10 -0700847static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700848 const MACROBLOCKD *const xd, int tx_set) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700849#if CONFIG_EXT_TX
850 const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
851#else
852 const int tx_set_1D[TX_TYPES_1D] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -0800853#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854
855 switch (cpi->sf.tx_type_search.prune_mode) {
856 case NO_PRUNE: return 0; break;
857 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700858 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700859 return 0;
860 return prune_one_for_sby(cpi, bsize, x, xd);
861 break;
862#if CONFIG_EXT_TX
863 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700864 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
866 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
867 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700868 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700869 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
870 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
871 break;
Fergus Simpson4063a682017-02-28 16:52:22 -0800872#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700873 }
874 assert(0);
875 return 0;
876}
877
878static int do_tx_type_search(TX_TYPE tx_type, int prune) {
879// TODO(sarahparker) implement for non ext tx
880#if CONFIG_EXT_TX
881 return !(((prune >> vtx_tab[tx_type]) & 1) |
882 ((prune >> (htx_tab[tx_type] + 8)) & 1));
883#else
884 // temporary to avoid compiler warnings
885 (void)vtx_tab;
886 (void)htx_tab;
887 (void)tx_type;
888 (void)prune;
889 return 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800890#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700891}
892
Yaowu Xuf883b422016-08-30 14:01:10 -0700893static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
895 int plane, int64_t sse, int *rate,
896 int64_t *dist) {
897 const struct macroblockd_plane *const pd = &xd->plane[plane];
898 const int dequant_shift =
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200899#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200901#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700902 3;
903
904 // Fast approximate the modelling function.
905 if (cpi->sf.simple_model_rd_from_var) {
906 const int64_t square_error = sse;
907 int quantizer = (pd->dequant[1] >> dequant_shift);
908
909 if (quantizer < 120)
910 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700911 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700912 else
913 *rate = 0;
914 *dist = (square_error * quantizer) >> 8;
915 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700916 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
917 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918 }
919
920 *dist <<= 4;
921}
922
Yaowu Xuf883b422016-08-30 14:01:10 -0700923static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
925 int plane_to, int *out_rate_sum,
926 int64_t *out_dist_sum, int *skip_txfm_sb,
927 int64_t *skip_sse_sb) {
928 // Note our transform coeffs are 8 times an orthogonal transform.
929 // Hence quantizer step is also 8 times. To get effective quantizer
930 // we need to divide by 8 before sending to modeling function.
931 int plane;
932 const int ref = xd->mi[0]->mbmi.ref_frame[0];
933
934 int64_t rate_sum = 0;
935 int64_t dist_sum = 0;
936 int64_t total_sse = 0;
937
938 x->pred_sse[ref] = 0;
939
940 for (plane = plane_from; plane <= plane_to; ++plane) {
941 struct macroblock_plane *const p = &x->plane[plane];
942 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han31b6a4f2017-02-23 11:05:53 -0800943#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -0800944 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
945#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Fergus Simpson4063a682017-02-28 16:52:22 -0800947#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948
949 unsigned int sse;
950 int rate;
951 int64_t dist;
952
Jingning Han9ce464c2017-02-20 15:36:30 -0800953#if CONFIG_CB4X4
954 if (x->skip_chroma_rd && plane) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -0800955#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -0800956
Yaowu Xuc27fc142016-08-22 16:08:15 -0700957 // TODO(geza): Write direct sse functions that do not compute
958 // variance as well.
959 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
960 &sse);
961
962 if (plane == 0) x->pred_sse[ref] = sse;
963
964 total_sse += sse;
965
966 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
967
968 rate_sum += rate;
969 dist_sum += dist;
970 }
971
972 *skip_txfm_sb = total_sse == 0;
973 *skip_sse_sb = total_sse << 4;
974 *out_rate_sum = (int)rate_sum;
975 *out_dist_sum = dist_sum;
976}
977
Yaowu Xuf883b422016-08-30 14:01:10 -0700978int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
979 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 int i;
981 int64_t error = 0, sqcoeff = 0;
982
983 for (i = 0; i < block_size; i++) {
984 const int diff = coeff[i] - dqcoeff[i];
985 error += diff * diff;
986 sqcoeff += coeff[i] * coeff[i];
987 }
988
989 *ssz = sqcoeff;
990 return error;
991}
992
Yaowu Xuf883b422016-08-30 14:01:10 -0700993int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
994 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700995 int i;
996 int64_t error = 0;
997
998 for (i = 0; i < block_size; i++) {
999 const int diff = coeff[i] - dqcoeff[i];
1000 error += diff * diff;
1001 }
1002
1003 return error;
1004}
1005
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001006#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001007int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
1008 const tran_low_t *dqcoeff, intptr_t block_size,
1009 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 int i;
1011 int64_t error = 0, sqcoeff = 0;
1012 int shift = 2 * (bd - 8);
1013 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1014
1015 for (i = 0; i < block_size; i++) {
1016 const int64_t diff = coeff[i] - dqcoeff[i];
1017 error += diff * diff;
1018 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
1019 }
1020 assert(error >= 0 && sqcoeff >= 0);
1021 error = (error + rounding) >> shift;
1022 sqcoeff = (sqcoeff + rounding) >> shift;
1023
1024 *ssz = sqcoeff;
1025 return error;
1026}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001027#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001028
Thomas Daede6ff6af62017-02-03 16:29:24 -08001029#if CONFIG_PVQ
1030// Without PVQ, av1_block_error_c() return two kind of errors,
1031// 1) reconstruction (i.e. decoded) error and
1032// 2) Squared sum of transformed residue (i.e. 'coeff')
1033// However, if PVQ is enabled, coeff does not keep the transformed residue
1034// but instead a transformed original is kept.
1035// Hence, new parameter ref vector (i.e. transformed predicted signal)
1036// is required to derive the residue signal,
1037// i.e. coeff - ref = residue (all transformed).
1038
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001039#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001040static int64_t av1_highbd_block_error2_c(const tran_low_t *coeff,
1041 const tran_low_t *dqcoeff,
1042 const tran_low_t *ref,
1043 intptr_t block_size, int64_t *ssz,
1044 int bd) {
1045 int64_t error;
1046 int64_t sqcoeff;
1047 int shift = 2 * (bd - 8);
1048 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1049 // Use the existing sse codes for calculating distortion of decoded signal:
1050 // i.e. (orig - decoded)^2
1051 // For high bit depth, throw away ssz until a 32-bit version of
1052 // av1_block_error_fp is written.
1053 int64_t ssz_trash;
1054 error = av1_block_error(coeff, dqcoeff, block_size, &ssz_trash);
1055 // prediction residue^2 = (orig - ref)^2
1056 sqcoeff = av1_block_error(coeff, ref, block_size, &ssz_trash);
1057 error = (error + rounding) >> shift;
1058 sqcoeff = (sqcoeff + rounding) >> shift;
1059 *ssz = sqcoeff;
1060 return error;
1061}
1062#else
1063// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1064// a separate function that does not do the extra computations for ssz.
1065static int64_t av1_block_error2_c(const tran_low_t *coeff,
1066 const tran_low_t *dqcoeff,
1067 const tran_low_t *ref, intptr_t block_size,
1068 int64_t *ssz) {
1069 int64_t error;
1070 // Use the existing sse codes for calculating distortion of decoded signal:
1071 // i.e. (orig - decoded)^2
1072 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1073 // prediction residue^2 = (orig - ref)^2
1074 *ssz = av1_block_error_fp(coeff, ref, block_size);
1075 return error;
1076}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001077#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001078#endif // CONFIG_PVQ
1079
Jingning Hanab77e732017-02-28 15:20:59 -08001080#if !CONFIG_PVQ || CONFIG_VAR_TX
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001081/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082 * decide whether to include cost of a trailing EOB node or not (i.e. we
1083 * can skip this if the last coefficient in this transform block, e.g. the
1084 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1085 * were non-zero). */
Angie Chiang47e4b362017-03-24 11:25:10 -07001086#if !CONFIG_LV_MAP
1087static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1088 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1089 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1090 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001091 MACROBLOCKD *const xd = &x->e_mbd;
1092 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1093 const struct macroblock_plane *p = &x->plane[plane];
1094 const struct macroblockd_plane *pd = &xd->plane[plane];
1095 const PLANE_TYPE type = pd->plane_type;
1096 const uint16_t *band_count = &band_count_table[tx_size][1];
1097 const int eob = p->eobs[block];
1098 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1099 const int tx_size_ctx = txsize_sqr_map[tx_size];
1100 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1101 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1102 uint8_t token_cache[MAX_TX_SQUARE];
Angie Chiang77368af2017-03-23 16:22:07 -07001103 int pt = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001104 int c, cost;
Angie Chiang77368af2017-03-23 16:22:07 -07001105 const int16_t *scan = scan_order->scan;
1106 const int16_t *nb = scan_order->neighbors;
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001107#if CONFIG_NEW_TOKENSET
1108 const int ref = is_inter_block(mbmi);
1109 aom_prob *blockz_probs =
1110 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
Thomas Davies10525752017-03-06 12:10:46 +00001111
Fergus Simpson4063a682017-02-28 16:52:22 -08001112#endif // CONFIG_NEW_TOKENSET
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001113
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001114#if CONFIG_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001115 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001117 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001118#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119
1120#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1121 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001122 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001124 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125
1126 if (eob == 0) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001127#if CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001129 cost = av1_cost_bit(blockz_probs[pt], 0);
1130#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131 cost = token_costs[0][0][pt][EOB_TOKEN];
Fergus Simpson4063a682017-02-28 16:52:22 -08001132#endif // CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133 } else {
1134 if (use_fast_coef_costing) {
1135 int band_left = *band_count++;
1136
1137 // dc token
1138 int v = qcoeff[0];
1139 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001140 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001141#if CONFIG_NEW_TOKENSET
1142 cost += (*token_costs)[!prev_t][pt][prev_t];
1143#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001144 cost += (*token_costs)[0][pt][prev_t];
Thomas Davies10525752017-03-06 12:10:46 +00001145#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001146
Yaowu Xuf883b422016-08-30 14:01:10 -07001147 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148 ++token_costs;
1149
1150 // ac tokens
1151 for (c = 1; c < eob; c++) {
1152 const int rc = scan[c];
1153 int16_t t;
1154
1155 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001156 cost += av1_get_token_cost(v, &t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001157#if CONFIG_NEW_TOKENSET
1158 cost += (*token_costs)[!t][!prev_t][t];
1159#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 cost += (*token_costs)[!prev_t][!prev_t][t];
Thomas Davies10525752017-03-06 12:10:46 +00001161#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162 prev_t = t;
1163 if (!--band_left) {
1164 band_left = *band_count++;
1165 ++token_costs;
1166 }
1167 }
1168
1169 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001170 if (band_left || CONFIG_NEW_TOKENSET)
1171 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001172
1173 } else { // !use_fast_coef_costing
1174 int band_left = *band_count++;
1175
1176 // dc token
1177 int v = qcoeff[0];
1178 int16_t tok;
Thomas Davies10525752017-03-06 12:10:46 +00001179#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
Thomas Davies10525752017-03-06 12:10:46 +00001181#endif
Alex Converseda3d94f2017-03-15 14:54:29 -07001182 cost = av1_get_token_cost(v, &tok, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001183#if CONFIG_NEW_TOKENSET
1184 cost += (*token_costs)[!tok][pt][tok];
1185#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 cost += (*token_costs)[0][pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001187#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188
Yaowu Xuf883b422016-08-30 14:01:10 -07001189 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001190 ++token_costs;
1191
Thomas Davies10525752017-03-06 12:10:46 +00001192#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001193 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001194#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001195
1196 // ac tokens
1197 for (c = 1; c < eob; c++) {
1198 const int rc = scan[c];
1199
1200 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001201 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001202 pt = get_coef_context(nb, token_cache, c);
Thomas Davies10525752017-03-06 12:10:46 +00001203#if CONFIG_NEW_TOKENSET
1204 cost += (*token_costs)[!tok][pt][tok];
1205#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001206 cost += (*tok_cost_ptr)[pt][tok];
Thomas Davies10525752017-03-06 12:10:46 +00001207#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001208 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001209 if (!--band_left) {
1210 band_left = *band_count++;
1211 ++token_costs;
1212 }
Thomas Davies10525752017-03-06 12:10:46 +00001213#if !CONFIG_NEW_TOKENSET
Yaowu Xuc27fc142016-08-22 16:08:15 -07001214 tok_cost_ptr = &((*token_costs)[!tok]);
Thomas Davies10525752017-03-06 12:10:46 +00001215#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001216 }
1217
1218 // eob token
Thomas Davies10525752017-03-06 12:10:46 +00001219 if (band_left || CONFIG_NEW_TOKENSET) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220 pt = get_coef_context(nb, token_cache, c);
1221 cost += (*token_costs)[0][pt][EOB_TOKEN];
1222 }
1223 }
1224 }
1225
Yaowu Xuc27fc142016-08-22 16:08:15 -07001226 return cost;
1227}
Angie Chiang47e4b362017-03-24 11:25:10 -07001228#endif // !CONFIG_LV_MAP
1229
Angie Chiang05917872017-04-15 12:28:56 -07001230int av1_cost_coeffs(const AV1_COMP *const cpi, MACROBLOCK *x, int plane,
Angie Chiang47e4b362017-03-24 11:25:10 -07001231 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1232 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1233 int use_fast_coef_costing) {
1234#if !CONFIG_LV_MAP
Angie Chiang05917872017-04-15 12:28:56 -07001235 const AV1_COMMON *const cm = &cpi->common;
Angie Chiang47e4b362017-03-24 11:25:10 -07001236 return cost_coeffs(cm, x, plane, block, tx_size, scan_order, a, l,
1237 use_fast_coef_costing);
1238#else // !CONFIG_LV_MAP
1239 (void)scan_order;
1240 (void)use_fast_coef_costing;
1241 const MACROBLOCKD *xd = &x->e_mbd;
1242 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1243 const struct macroblockd_plane *pd = &xd->plane[plane];
1244 const BLOCK_SIZE bsize = mbmi->sb_type;
1245#if CONFIG_CB4X4
1246#if CONFIG_CHROMA_2X2
1247 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
1248#else
1249 const BLOCK_SIZE plane_bsize =
1250 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
1251#endif // CONFIG_CHROMA_2X2
1252#else // CONFIG_CB4X4
1253 const BLOCK_SIZE plane_bsize =
1254 get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
1255#endif // CONFIG_CB4X4
1256
1257 TXB_CTX txb_ctx;
1258 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07001259 return av1_cost_coeffs_txb(cpi, x, plane, block, &txb_ctx);
Angie Chiang47e4b362017-03-24 11:25:10 -07001260#endif // !CONFIG_LV_MAP
1261}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001262#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001263
Alex Converse61f37b82017-03-29 15:26:03 -07001264// Get transform block visible dimensions cropped to the MI units.
1265static void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
1266 BLOCK_SIZE plane_bsize, int blk_row, int blk_col,
1267 BLOCK_SIZE tx_bsize, int *width, int *height,
1268 int *visible_width, int *visible_height) {
1269 assert(tx_bsize <= plane_bsize);
1270 int txb_height = block_size_high[tx_bsize];
1271 int txb_width = block_size_wide[tx_bsize];
1272 const int block_height = block_size_high[plane_bsize];
1273 const int block_width = block_size_wide[plane_bsize];
1274 const struct macroblockd_plane *const pd = &xd->plane[plane];
1275 // TODO(aconverse@google.com): Investigate using crop_width/height here rather
1276 // than the MI size
1277 const int block_rows =
1278 (xd->mb_to_bottom_edge >= 0)
1279 ? block_height
1280 : (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
1281 const int block_cols =
1282 (xd->mb_to_right_edge >= 0)
1283 ? block_width
1284 : (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) + block_width;
1285 const int tx_unit_size = tx_size_wide_log2[0];
1286 if (width) *width = txb_width;
1287 if (height) *height = txb_height;
1288 *visible_width = clamp(block_cols - (blk_col << tx_unit_size), 0, txb_width);
1289 *visible_height =
1290 clamp(block_rows - (blk_row << tx_unit_size), 0, txb_height);
1291}
1292
1293// Compute the pixel domain sum square error on all visible 4x4s in the
1294// transform block.
1295static unsigned pixel_sse(const AV1_COMP *const cpi, const MACROBLOCKD *xd,
1296 int plane, const uint8_t *src, const int src_stride,
1297 const uint8_t *dst, const int dst_stride, int blk_row,
1298 int blk_col, const BLOCK_SIZE plane_bsize,
1299 const BLOCK_SIZE tx_bsize) {
1300 int txb_rows, txb_cols, visible_rows, visible_cols;
1301 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize,
1302 &txb_cols, &txb_rows, &visible_cols, &visible_rows);
1303 assert(visible_rows > 0);
1304 assert(visible_cols > 0);
1305 if (txb_rows == visible_rows && txb_cols == visible_cols) {
1306 unsigned sse;
1307 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse);
1308 return sse;
1309 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001310#if CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001311 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1312 uint64_t sse = aom_highbd_sse_odd_size(src, src_stride, dst, dst_stride,
1313 visible_cols, visible_rows);
1314 return (unsigned int)ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
1315 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001316#endif // CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001317 unsigned sse = aom_sse_odd_size(src, src_stride, dst, dst_stride,
1318 visible_cols, visible_rows);
1319 return sse;
1320}
1321
1322// Compute the squares sum squares on all visible 4x4s in the transform block.
1323static int64_t sum_squares_visible(const MACROBLOCKD *xd, int plane,
1324 const int16_t *diff, const int diff_stride,
1325 int blk_row, int blk_col,
1326 const BLOCK_SIZE plane_bsize,
1327 const BLOCK_SIZE tx_bsize) {
1328 int visible_rows, visible_cols;
1329 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize, NULL,
1330 NULL, &visible_cols, &visible_rows);
1331 return aom_sum_squares_2d_i16(diff, diff_stride, visible_cols, visible_rows);
1332}
1333
Angie Chiang808d8592017-04-06 18:36:55 -07001334void av1_dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
1335 BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col,
1336 TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse,
1337 OUTPUT_STATUS output_status) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001338 MACROBLOCKD *const xd = &x->e_mbd;
1339 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001340#if CONFIG_DAALA_DIST
1341 int qm = OD_HVS_QM;
1342 int use_activity_masking = 0;
1343#if CONFIG_PVQ
1344 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001345#endif // CONFIG_PVQ
Yushin Cho4483e3d2017-04-18 19:41:20 -07001346 struct macroblockd_plane *const pd = &xd->plane[plane];
1347#else // CONFIG_DAALA_DIST
1348 const struct macroblockd_plane *const pd = &xd->plane[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001349#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001350
1351 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
hui sud2f12ba2017-04-12 10:08:43 -07001352 // Transform domain distortion computation is more efficient as it does
Yaowu Xuc27fc142016-08-22 16:08:15 -07001353 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001354 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001355 int64_t this_sse;
Jingning Hanff705452017-04-27 11:32:15 -07001356 int shift = (MAX_TX_SCALE - av1_get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001357 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1358 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001359#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001360 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001361
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001362#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001363 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001364 *out_dist = av1_highbd_block_error2_c(coeff, dqcoeff, ref_coeff,
1365 buffer_length, &this_sse, bd) >>
1366 shift;
1367#else
1368 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1369 &this_sse) >>
1370 shift;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001371#endif // CONFIG_HIGHBITDEPTH
1372#elif CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001373 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Jingning Hanb9c57272016-10-25 10:15:39 -07001374 *out_dist =
1375 av1_highbd_block_error(coeff, dqcoeff, buffer_length, &this_sse, bd) >>
1376 shift;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001377#else
1378 *out_dist =
Jingning Hanb9c57272016-10-25 10:15:39 -07001379 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001380#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 *out_sse = this_sse >> shift;
1382 } else {
1383 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Angie Chiang50910f62017-04-03 12:31:34 -07001384#if !CONFIG_PVQ || CONFIG_DAALA_DIST
Jingning Hanb9c57272016-10-25 10:15:39 -07001385 const int bsw = block_size_wide[tx_bsize];
1386 const int bsh = block_size_high[tx_bsize];
Angie Chiang50910f62017-04-03 12:31:34 -07001387#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 const int src_stride = x->plane[plane].src.stride;
1389 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001390 // Scale the transform block index to pixel unit.
1391 const int src_idx = (blk_row * src_stride + blk_col)
1392 << tx_size_wide_log2[0];
1393 const int dst_idx = (blk_row * dst_stride + blk_col)
1394 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001395 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1396 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1397 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1398 const uint16_t eob = p->eobs[block];
1399
Yaowu Xuc27fc142016-08-22 16:08:15 -07001400 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001401 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402
Yushin Cho7a428ba2017-01-12 16:28:49 -08001403#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001404 if (plane == 0 && bsw >= 8 && bsh >= 8) {
1405 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
1406 const int pred_stride = block_size_wide[plane_bsize];
1407 const int pred_idx = (blk_row * pred_stride + blk_col)
1408 << tx_size_wide_log2[0];
1409 const int16_t *pred = &pd->pred[pred_idx];
1410 int i, j;
1411 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001412
Yushin Cho4483e3d2017-04-18 19:41:20 -07001413 for (j = 0; j < bsh; j++)
1414 for (i = 0; i < bsw; i++)
1415 pred8[j * bsw + i] = pred[j * pred_stride + i];
Alex Conversef323f012017-04-24 09:26:33 -07001416 *out_sse = av1_daala_dist(src, src_stride, pred8, bsw, bsw, bsh, qm,
1417 use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001418 } else {
Alex Conversef323f012017-04-24 09:26:33 -07001419 *out_sse = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1420 qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001421 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001422 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001423#endif // CONFIG_DAALA_DIST
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001424 {
1425 const int diff_stride = block_size_wide[plane_bsize];
1426 const int diff_idx = (blk_row * diff_stride + blk_col)
1427 << tx_size_wide_log2[0];
1428 const int16_t *diff = &p->src_diff[diff_idx];
Alex Conversef323f012017-04-24 09:26:33 -07001429 *out_sse = sum_squares_visible(xd, plane, diff, diff_stride, blk_row,
1430 blk_col, plane_bsize, tx_bsize);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001431#if CONFIG_HIGHBITDEPTH
hui sub1cc1f92017-04-11 17:41:29 -07001432 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Alex Conversef323f012017-04-24 09:26:33 -07001433 *out_sse = ROUND_POWER_OF_TWO(*out_sse, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001434#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001435 }
Alex Conversef323f012017-04-24 09:26:33 -07001436 *out_sse *= 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001437
1438 if (eob) {
Angie Chiang228cc182017-04-07 15:22:16 -07001439 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001440#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001441 if (plane == 0 && bsw >= 8 && bsh >= 8)
Alex Conversef323f012017-04-24 09:26:33 -07001442 *out_dist = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1443 qm, use_activity_masking, x->qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001444 else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001445#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001446 *out_dist =
1447 pixel_sse(cpi, xd, plane, src, src_stride, dst, dst_stride,
1448 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001449 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001450#if CONFIG_HIGHBITDEPTH
Jingning Han6a9dbef2017-04-10 10:25:14 -07001451 uint8_t *recon;
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001452 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
Jingning Han6a9dbef2017-04-10 10:25:14 -07001453
1454 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1455 recon = CONVERT_TO_BYTEPTR(recon16);
1456 else
1457 recon = (uint8_t *)recon16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001458#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001459 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001460#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461
Angie Chiang50910f62017-04-03 12:31:34 -07001462#if !CONFIG_PVQ
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001463#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001464 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1465 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
1466 NULL, 0, bsw, bsh, xd->bd);
1467 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001468#endif // CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001469 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL,
1470 0, bsw, bsh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001471#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001472 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001473#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001474#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001475 (void)dst;
Angie Chiang50910f62017-04-03 12:31:34 -07001476#endif // !CONFIG_PVQ
Angie Chiang41fffae2017-04-03 10:33:18 -07001477
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001478 const PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001479 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang41fffae2017-04-03 10:33:18 -07001480
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001481 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, recon,
1482 MAX_TX_SIZE, eob);
Angie Chiang41fffae2017-04-03 10:33:18 -07001483
Yushin Cho7a428ba2017-01-12 16:28:49 -08001484#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001485 if (plane == 0 && bsw >= 8 && bsh >= 8) {
Alex Conversef323f012017-04-24 09:26:33 -07001486 *out_dist = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, bsw,
1487 bsh, qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001488 } else {
Yushin Cho4483e3d2017-04-18 19:41:20 -07001489 if (plane == 0) {
1490 // Save decoded pixels for inter block in pd->pred to avoid
1491 // block_8x8_rd_txfm_daala_dist() need to produce them
1492 // by calling av1_inverse_transform_block() again.
1493 const int pred_stride = block_size_wide[plane_bsize];
1494 const int pred_idx = (blk_row * pred_stride + blk_col)
1495 << tx_size_wide_log2[0];
1496 int16_t *pred = &pd->pred[pred_idx];
1497 int i, j;
1498
1499 for (j = 0; j < bsh; j++)
1500 for (i = 0; i < bsw; i++)
1501 pred[j * pred_stride + i] = recon[j * MAX_TX_SIZE + i];
1502 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001503#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001504 *out_dist =
1505 pixel_sse(cpi, xd, plane, src, src_stride, recon, MAX_TX_SIZE,
1506 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001507#if CONFIG_DAALA_DIST
1508 }
1509#endif // CONFIG_DAALA_DIST
1510 }
Alex Conversef323f012017-04-24 09:26:33 -07001511 *out_dist *= 16;
1512 } else {
1513 *out_dist = *out_sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001514 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515 }
1516}
1517
Yaowu Xuc27fc142016-08-22 16:08:15 -07001518static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1519 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1520 struct rdcost_block_args *args = arg;
1521 MACROBLOCK *const x = args->x;
1522 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001523 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiange50f3ec2017-04-10 15:50:33 -07001524 const AV1_COMP *cpi = args->cpi;
Angie Chiang65a39bb2017-04-11 16:50:04 -07001525 ENTROPY_CONTEXT *a = args->t_above + blk_col;
1526 ENTROPY_CONTEXT *l = args->t_left + blk_row;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001527#if !CONFIG_TXK_SEL
Angie Chiang18ad8942017-04-11 12:37:07 -07001528 const AV1_COMMON *cm = &cpi->common;
1529#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001530 int64_t rd1, rd2, rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001531 RD_STATS this_rd_stats;
Yushin Cho6341f5c2017-03-24 14:36:28 -07001532
Angie Chiangbc2288c2017-04-09 15:41:17 -07001533 assert(tx_size == get_tx_size(plane, xd));
1534
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001535 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001536
1537 if (args->exit_early) return;
1538
1539 if (!is_inter_block(mbmi)) {
Luc Trudeauf5334002017-04-25 12:21:26 -04001540#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09001541 av1_predict_intra_block_encoder_facade(x, plane, block, blk_col, blk_row,
1542 tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04001543#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001544 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001545#endif
Angie Chiang62e54cd2017-04-06 10:45:56 -07001546 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
1547 }
1548
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001549#if !CONFIG_TXK_SEL
Angie Chiang62e54cd2017-04-06 10:45:56 -07001550 // full forward transform and quantization
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001551 const int coeff_ctx = combine_entropy_contexts(*a, *l);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001552 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1553 coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07001554 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001555
1556 if (!is_inter_block(mbmi)) {
1557 struct macroblock_plane *const p = &x->plane[plane];
Angie Chiangbc2288c2017-04-09 15:41:17 -07001558 av1_inverse_transform_block_facade(xd, plane, block, blk_row, blk_col,
1559 p->eobs[block]);
Angie Chiang808d8592017-04-06 18:36:55 -07001560 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1561 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1562 OUTPUT_HAS_DECODED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001563 } else {
Angie Chiang808d8592017-04-06 18:36:55 -07001564 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1565 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1566 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001567 }
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001568#if CONFIG_CFL
1569 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1570 struct macroblockd_plane *const pd = &xd->plane[plane];
1571 const int dst_stride = pd->dst.stride;
1572 uint8_t *dst =
1573 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1574 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
1575 }
1576#endif
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001577 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001578 if (args->this_rd + rd > args->best_rd) {
1579 args->exit_early = 1;
1580 return;
1581 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001582#if !CONFIG_PVQ
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001583 const PLANE_TYPE plane_type = get_plane_type(plane);
1584 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang18ad8942017-04-11 12:37:07 -07001585 const SCAN_ORDER *scan_order =
1586 get_scan(cm, tx_size, tx_type, is_inter_block(mbmi));
Angie Chiang05917872017-04-15 12:28:56 -07001587 this_rd_stats.rate =
1588 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l,
1589 args->use_fast_coef_costing);
Angie Chiang65a39bb2017-04-11 16:50:04 -07001590#else // !CONFIG_PVQ
1591 this_rd_stats.rate = x->rate;
1592#endif // !CONFIG_PVQ
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001593#else // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001594 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
1595 tx_size, a, l, args->use_fast_coef_costing,
1596 &this_rd_stats);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001597#endif // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001598
1599#if !CONFIG_PVQ
Angie Chiang3963d632016-11-10 18:41:40 -08001600#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001601 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1602 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001603#endif // CONFIG_RD_DEBUG
Yushin Cho6341f5c2017-03-24 14:36:28 -07001604 av1_set_txb_context(x, plane, block, tx_size, a, l);
Fergus Simpson4063a682017-02-28 16:52:22 -08001605#endif // !CONFIG_PVQ
Angie Chiangb3a12b52017-03-23 14:53:10 -07001606
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001607 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1608 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001609
1610 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001611 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001612
Yushin Cho7a428ba2017-01-12 16:28:49 -08001613#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001614 if (plane == 0 &&
1615 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4)) {
1616 this_rd_stats.dist = 0;
1617 this_rd_stats.sse = 0;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001618 rd = 0;
1619 x->rate_4x4[block] = this_rd_stats.rate;
1620 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001621#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001622
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001623#if !CONFIG_PVQ
1624 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1625#else
1626 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001627#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001628 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001629
Yaowu Xuc27fc142016-08-22 16:08:15 -07001630 args->this_rd += rd;
1631
1632 if (args->this_rd > args->best_rd) {
1633 args->exit_early = 1;
1634 return;
1635 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001636}
1637
Yushin Cho7a428ba2017-01-12 16:28:49 -08001638#if CONFIG_DAALA_DIST
1639static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
1640 int blk_col, BLOCK_SIZE plane_bsize,
1641 TX_SIZE tx_size, void *arg) {
1642 struct rdcost_block_args *args = arg;
1643 MACROBLOCK *const x = args->x;
1644 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001645 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1646 int64_t rd, rd1, rd2;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001647 RD_STATS this_rd_stats;
1648 int qm = OD_HVS_QM;
1649 int use_activity_masking = 0;
1650
Yushin Cho4483e3d2017-04-18 19:41:20 -07001651 (void)tx_size;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001652#if CONFIG_PVQ
1653 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001654#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08001655 av1_init_rd_stats(&this_rd_stats);
1656
1657 if (args->exit_early) return;
1658
1659 {
1660 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho4483e3d2017-04-18 19:41:20 -07001661 struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001662
1663 const int src_stride = p->src.stride;
1664 const int dst_stride = pd->dst.stride;
1665 const int diff_stride = block_size_wide[plane_bsize];
1666
1667 const uint8_t *src =
1668 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1669 const uint8_t *dst =
1670 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1671
Yushin Cho4483e3d2017-04-18 19:41:20 -07001672 unsigned int tmp1, tmp2;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001673 int qindex = x->qindex;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001674 const int pred_stride = block_size_wide[plane_bsize];
1675 const int pred_idx = (blk_row * pred_stride + blk_col)
1676 << tx_size_wide_log2[0];
1677 int16_t *pred = &pd->pred[pred_idx];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001678 int i, j;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001679 const int tx_blk_size = 8;
1680
1681 DECLARE_ALIGNED(16, uint8_t, pred8[8 * 8]);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001682
1683 for (j = 0; j < tx_blk_size; j++)
1684 for (i = 0; i < tx_blk_size; i++)
1685 pred8[j * tx_blk_size + i] = pred[j * diff_stride + i];
1686
Yushin Cho4483e3d2017-04-18 19:41:20 -07001687 tmp1 = av1_daala_dist(src, src_stride, pred8, tx_blk_size, 8, 8, qm,
1688 use_activity_masking, qindex);
1689 tmp2 = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8, qm,
1690 use_activity_masking, qindex);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001691
Yushin Cho4483e3d2017-04-18 19:41:20 -07001692 if (!is_inter_block(mbmi)) {
1693 this_rd_stats.sse = (int64_t)tmp1 * 16;
1694 this_rd_stats.dist = (int64_t)tmp2 * 16;
1695 } else {
1696 // For inter mode, the decoded pixels are provided in pd->pred,
1697 // while the predicted pixels are in dst.
1698 this_rd_stats.sse = (int64_t)tmp2 * 16;
1699 this_rd_stats.dist = (int64_t)tmp1 * 16;
1700 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001701 }
1702
1703 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
1704 if (args->this_rd + rd > args->best_rd) {
1705 args->exit_early = 1;
1706 return;
1707 }
1708
1709 {
1710 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
1711 // The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
1712 this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
1713 x->rate_4x4[block - max_blocks_wide] +
1714 x->rate_4x4[block - 1] + x->rate_4x4[block];
1715 }
1716 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1717 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001718 rd = AOMMIN(rd1, rd2);
1719
1720 args->rd_stats.dist += this_rd_stats.dist;
1721 args->rd_stats.sse += this_rd_stats.sse;
1722
1723 args->this_rd += rd;
1724
1725 if (args->this_rd > args->best_rd) {
1726 args->exit_early = 1;
1727 return;
1728 }
1729}
Fergus Simpson4063a682017-02-28 16:52:22 -08001730#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001731
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001732static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1733 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1734 BLOCK_SIZE bsize, TX_SIZE tx_size,
1735 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001736 MACROBLOCKD *const xd = &x->e_mbd;
1737 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001738 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001739 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001740 args.x = x;
1741 args.cpi = cpi;
1742 args.best_rd = ref_best_rd;
1743 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001744 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745
1746 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1747
Yaowu Xuf883b422016-08-30 14:01:10 -07001748 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001749
Yushin Cho7a428ba2017-01-12 16:28:49 -08001750#if CONFIG_DAALA_DIST
1751 if (plane == 0 &&
1752 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
1753 av1_foreach_8x8_transformed_block_in_plane(
1754 xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
1755 else
Fergus Simpson4063a682017-02-28 16:52:22 -08001756#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001757 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1758 &args);
1759
Yaowu Xuc27fc142016-08-22 16:08:15 -07001760 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001761 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001762 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001763 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001764 }
1765}
1766
1767#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001768void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1769 int64_t *distortion, int *skippable,
1770 int64_t *sse, int64_t ref_best_rd, int plane,
1771 BLOCK_SIZE bsize, TX_SIZE tx_size,
1772 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001773 MACROBLOCKD *const xd = &x->e_mbd;
1774 const struct macroblockd_plane *const pd = &xd->plane[plane];
1775 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001776 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001777 args.cpi = cpi;
1778 args.x = x;
1779 args.best_rd = ref_best_rd;
1780 args.use_fast_coef_costing = use_fast_coef_casting;
1781
1782#if CONFIG_EXT_TX
1783 assert(tx_size < TX_SIZES);
1784#endif // CONFIG_EXT_TX
1785
1786 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1787
Yaowu Xuf883b422016-08-30 14:01:10 -07001788 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001789
Yaowu Xuc27fc142016-08-22 16:08:15 -07001790 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1791 &args);
1792
1793 if (args.exit_early) {
1794 *rate = INT_MAX;
1795 *distortion = INT64_MAX;
1796 *sse = INT64_MAX;
1797 *skippable = 0;
1798 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001799 *distortion = args.rd_stats.dist;
1800 *rate = args.rd_stats.rate;
1801 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001802 *skippable = !x->plane[plane].eobs[0];
1803 }
1804}
1805#endif // CONFIG_SUPERTX
1806
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001807static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Urvang Joshifeb925f2016-12-05 10:37:29 -08001808 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1809 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001810 const MACROBLOCKD *const xd = &x->e_mbd;
1811 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001812
1813 const int tx_select =
1814 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1815
1816 if (tx_select) {
1817 const int is_inter = is_inter_block(mbmi);
1818 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1819 : intra_tx_size_cat_lookup[bsize];
1820 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1821 const int depth = tx_size_to_depth(coded_tx_size);
1822 const int tx_size_ctx = get_tx_size_context(xd);
1823 const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1824 return r_tx_size;
1825 } else {
1826 return 0;
1827 }
1828}
1829
Angie Chiang65201562017-04-10 15:23:28 -07001830// #TODO(angiebird): use this function whenever it's possible
Angie Chiang05917872017-04-15 12:28:56 -07001831int av1_tx_type_cost(const AV1_COMP *cpi, const MACROBLOCKD *xd,
1832 BLOCK_SIZE bsize, int plane, TX_SIZE tx_size,
1833 TX_TYPE tx_type) {
1834 if (plane > 0) return 0;
1835
Angie Chiang65201562017-04-10 15:23:28 -07001836 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1837 const int is_inter = is_inter_block(mbmi);
1838#if CONFIG_EXT_TX
1839 const AV1_COMMON *cm = &cpi->common;
1840 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
1841 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1842 const int ext_tx_set =
1843 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
1844 if (is_inter) {
1845 if (ext_tx_set > 0)
1846 return cpi
1847 ->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]][tx_type];
1848 } else {
1849 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1850 return cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]]
1851 [mbmi->mode][tx_type];
1852 }
1853 }
1854#else
1855 (void)bsize;
1856 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1857 !FIXED_TX_TYPE) {
1858 if (is_inter) {
1859 return cpi->inter_tx_type_costs[tx_size][tx_type];
1860 } else {
1861 return cpi->intra_tx_type_costs[tx_size]
1862 [intra_mode_to_tx_type_context[mbmi->mode]]
1863 [tx_type];
1864 }
1865 }
1866#endif // CONFIG_EXT_TX
1867 return 0;
1868}
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001869static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1870 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1871 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001872 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873 MACROBLOCKD *const xd = &x->e_mbd;
1874 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1875 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001876 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877 int s0, s1;
1878 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001879 const int tx_select =
1880 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001881
1882 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883
1884 assert(skip_prob > 0);
1885#if CONFIG_EXT_TX && CONFIG_RECT_TX
1886 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1887#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1888
Yaowu Xuf883b422016-08-30 14:01:10 -07001889 s0 = av1_cost_bit(skip_prob, 0);
1890 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891
1892 mbmi->tx_type = tx_type;
1893 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001894 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001895 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001896 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001897#if !CONFIG_TXK_SEL
Angie Chiang05917872017-04-15 12:28:56 -07001898 int plane = 0;
1899 rd_stats->rate += av1_tx_type_cost(cpi, xd, bs, plane, tx_size, tx_type);
1900#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001901
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001902 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001904 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001906 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1907 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001908 }
1909 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001910 rd = RDCOST(x->rdmult, x->rddiv,
1911 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912 }
1913
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001914 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001915
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001916 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1917 !(rd_stats->skip))
1918 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001919
1920 return rd;
1921}
1922
Angie Chiang2d147c12017-04-05 11:23:59 -07001923static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
1924 TX_TYPE tx_type, TX_SIZE tx_size) {
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001925 const MACROBLOCKD *const xd = &x->e_mbd;
1926 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiang2d147c12017-04-05 11:23:59 -07001927 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1928 const int is_inter = is_inter_block(mbmi);
1929 int prune = 0;
1930 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1931 // passing -1 in for tx_type indicates that all 1D
1932 // transforms should be considered for pruning
1933 prune = prune_tx_types(cpi, bs, x, xd, -1);
1934
Angie Chianga4fa1902017-04-05 15:26:09 -07001935 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
Angie Chiang2d147c12017-04-05 11:23:59 -07001936 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
1937 return 1;
1938 if (!is_inter && x->use_default_intra_tx_type &&
1939 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1940 return 1;
1941 if (is_inter && x->use_default_inter_tx_type &&
1942 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1943 return 1;
1944 if (max_tx_size >= TX_32X32 && tx_size == TX_4X4) return 1;
1945#if CONFIG_EXT_TX
1946 const AV1_COMMON *const cm = &cpi->common;
1947 int ext_tx_set =
1948 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
1949 if (is_inter) {
1950 if (!ext_tx_used_inter[ext_tx_set][tx_type]) return 1;
1951 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1952 if (!do_tx_type_search(tx_type, prune)) return 1;
1953 }
1954 } else {
1955 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1956 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) return 1;
1957 }
1958 if (!ext_tx_used_intra[ext_tx_set][tx_type]) return 1;
1959 }
1960#else // CONFIG_EXT_TX
1961 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) return 1;
1962 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1963 !do_tx_type_search(tx_type, prune))
1964 return 1;
1965#endif // CONFIG_EXT_TX
1966 return 0;
1967}
1968
Yaowu Xuc27fc142016-08-22 16:08:15 -07001969#if CONFIG_EXT_INTER
Urvang Joshi52648442016-10-13 17:27:51 -07001970static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1971 MACROBLOCK *x, int *r, int64_t *d, int *s,
1972 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001973 RD_STATS rd_stats;
1974 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1975 max_txsize_lookup[bs]);
1976 *r = rd_stats.rate;
1977 *d = rd_stats.dist;
1978 *s = rd_stats.skip;
1979 *sse = rd_stats.sse;
1980 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981}
1982#endif // CONFIG_EXT_INTER
1983
Urvang Joshi52648442016-10-13 17:27:51 -07001984static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001985 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001986 BLOCK_SIZE bs) {
1987 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001988 MACROBLOCKD *const xd = &x->e_mbd;
1989 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1990 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001991 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001992 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1993 int s0 = av1_cost_bit(skip_prob, 0);
1994 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001995 const int is_inter = is_inter_block(mbmi);
1996 int prune = 0;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07001997 const int plane = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001998#if CONFIG_EXT_TX
1999 int ext_tx_set;
2000#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002001 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002
2003 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002004#if CONFIG_VAR_TX
2005 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002006#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002007#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002008 ext_tx_set =
2009 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002010#endif // CONFIG_EXT_TX
2011
2012 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2013#if CONFIG_EXT_TX
2014 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2015#else
2016 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08002017#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002018#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002019 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2020 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002021 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002022#if CONFIG_PVQ
2023 od_rollback_buffer pre_buf, post_buf;
2024
2025 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2026 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002027#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002028
2029 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002030 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031 if (is_inter) {
2032 if (x->use_default_inter_tx_type &&
2033 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2034 continue;
2035 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2036 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2037 if (!do_tx_type_search(tx_type, prune)) continue;
2038 }
2039 } else {
2040 if (x->use_default_intra_tx_type &&
2041 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2042 continue;
2043 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2044 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2045 }
2046 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2047 }
2048
2049 mbmi->tx_type = tx_type;
2050
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002051 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002053#if CONFIG_PVQ
2054 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002055#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002056 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002057 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002058
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002059 if (this_rd_stats.skip)
2060 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002062 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2063 this_rd_stats.dist);
2064 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2065 !this_rd_stats.skip)
2066 this_rd =
2067 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002068
2069 if (this_rd < best_rd) {
2070 best_rd = this_rd;
2071 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002072 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002073#if CONFIG_PVQ
2074 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002075#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002076 }
2077 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002078#if CONFIG_PVQ
2079 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002080#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002081 } else {
2082 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002083 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2084 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002085 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086#else // CONFIG_EXT_TX
2087 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2088 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002089 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090 if (!is_inter && x->use_default_intra_tx_type &&
2091 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2092 continue;
2093 if (is_inter && x->use_default_inter_tx_type &&
2094 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2095 continue;
2096 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002097 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002098 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002099 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002100
2101 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002103 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2104 !do_tx_type_search(tx_type, prune))
2105 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002106 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002107 if (this_rd_stats.skip)
2108 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002110 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2111 this_rd_stats.dist);
2112 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2113 this_rd =
2114 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002115
2116 if (this_rd < best_rd) {
2117 best_rd = this_rd;
2118 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002119 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120 }
2121 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002122 } else {
2123 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002124 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2125 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002126 }
2127#endif // CONFIG_EXT_TX
2128 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002129}
2130
Urvang Joshi52648442016-10-13 17:27:51 -07002131static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002132 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133 BLOCK_SIZE bs) {
2134 MACROBLOCKD *const xd = &x->e_mbd;
2135 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2136
2137 mbmi->tx_size = TX_4X4;
2138 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002139#if CONFIG_VAR_TX
2140 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002141#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002142
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002143 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2144 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145}
2146
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002147#if CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002148static INLINE int bsize_to_num_blk(BLOCK_SIZE bsize) {
2149 int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
2150 return num_blk;
2151}
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002152#endif // CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002153
Urvang Joshi52648442016-10-13 17:27:51 -07002154static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002155 MACROBLOCK *x, RD_STATS *rd_stats,
2156 int64_t ref_best_rd, BLOCK_SIZE bs) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002157 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002158 MACROBLOCKD *const xd = &x->e_mbd;
2159 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002160 int64_t rd = INT64_MAX;
Angie Chianga4fa1902017-04-05 15:26:09 -07002161 int n;
2162 int start_tx, end_tx;
2163 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
2164 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2165 TX_SIZE best_tx_size = max_tx_size;
2166 TX_TYPE best_tx_type = DCT_DCT;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002167#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002168 TX_TYPE best_txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
2169 const int num_blk = bsize_to_num_blk(bs);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002170#endif // CONFIG_TXK_SEL
Angie Chianga4fa1902017-04-05 15:26:09 -07002171 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
2172 const int is_inter = is_inter_block(mbmi);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002173#if CONFIG_PVQ
2174 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002175 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002176#endif // CONFIG_PVQ
Angie Chianga4fa1902017-04-05 15:26:09 -07002177
2178 av1_invalid_rd_stats(rd_stats);
2179
2180#if CONFIG_EXT_TX && CONFIG_RECT_TX
2181 int evaluate_rect_tx = 0;
2182 if (tx_select) {
2183 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
2184 } else {
2185 const TX_SIZE chosen_tx_size =
2186 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2187 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
2188 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
2189 }
2190 if (evaluate_rect_tx) {
Angie Chiangf1cb0752017-04-10 16:01:20 -07002191 TX_TYPE tx_start = DCT_DCT;
2192 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002193#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002194 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2195 // performed in av1_search_txk_type()
2196 tx_end = DCT_DCT + 1;
2197#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002198 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002199 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002200 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Angie Chianga4fa1902017-04-05 15:26:09 -07002201 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
2202 RD_STATS this_rd_stats;
2203 int ext_tx_set =
2204 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
2205 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2206 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2207 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
2208 rect_tx_size);
2209 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002210#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002211 memcpy(best_txk_type, mbmi->txk_type,
2212 sizeof(best_txk_type[0]) * num_blk);
2213#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002214 best_tx_type = tx_type;
2215 best_tx_size = rect_tx_size;
2216 best_rd = rd;
2217 *rd_stats = this_rd_stats;
2218 }
2219 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002220#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002221 const int is_inter = is_inter_block(mbmi);
2222 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002223#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002224 }
2225 }
2226#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2227
2228 if (tx_select) {
2229 start_tx = max_tx_size;
2230 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
2231 } else {
2232 const TX_SIZE chosen_tx_size =
2233 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2234 start_tx = chosen_tx_size;
2235 end_tx = chosen_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002236 }
2237
Angie Chianga4fa1902017-04-05 15:26:09 -07002238 last_rd = INT64_MAX;
2239 for (n = start_tx; n >= end_tx; --n) {
Sarah Parker36661922017-04-13 14:26:49 -07002240#if CONFIG_EXT_TX && CONFIG_RECT_TX
2241 if (is_rect_tx(n)) break;
2242#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002243 TX_TYPE tx_start = DCT_DCT;
2244 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002245#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002246 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2247 // performed in av1_search_txk_type()
2248 tx_end = DCT_DCT + 1;
2249#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002250 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002251 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002252 RD_STATS this_rd_stats;
2253 if (skip_txfm_search(cpi, x, bs, tx_type, n)) continue;
2254 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
2255#if CONFIG_PVQ
2256 od_encode_rollback(&x->daala_enc, &buf);
2257#endif // CONFIG_PVQ
2258 // Early termination in transform size search.
2259 if (cpi->sf.tx_size_search_breakout &&
2260 (rd == INT64_MAX ||
2261 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
2262 (n < (int)max_tx_size && rd > last_rd)))
2263 break;
2264
2265 last_rd = rd;
2266 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002267#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002268 memcpy(best_txk_type, mbmi->txk_type,
2269 sizeof(best_txk_type[0]) * num_blk);
2270#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002271 best_tx_type = tx_type;
2272 best_tx_size = n;
2273 best_rd = rd;
2274 *rd_stats = this_rd_stats;
2275 }
2276#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2277 const int is_inter = is_inter_block(mbmi);
2278 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2279#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2280 }
2281 }
2282 mbmi->tx_size = best_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002283 mbmi->tx_type = best_tx_type;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002284#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002285 memcpy(mbmi->txk_type, best_txk_type, sizeof(best_txk_type[0]) * num_blk);
2286#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002287
Jingning Hane67b38a2016-11-04 10:30:00 -07002288#if CONFIG_VAR_TX
2289 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002290#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002291
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292#if !CONFIG_EXT_TX
2293 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002294#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002295#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002296 if (best_rd != INT64_MAX) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002297 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx_size);
Yushin Cho05f540a2016-11-08 22:12:51 -08002298 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002299#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002300}
2301
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002302static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2303 RD_STATS *rd_stats, BLOCK_SIZE bs,
2304 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002305 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002306 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002307
2308 assert(bs == xd->mi[0]->mbmi.sb_type);
2309
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002310 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002311 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002312 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002313 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002314 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002315 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002316 }
2317}
2318
2319static int conditional_skipintra(PREDICTION_MODE mode,
2320 PREDICTION_MODE best_intra_mode) {
2321 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2322 best_intra_mode != D135_PRED)
2323 return 1;
2324 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2325 best_intra_mode != D45_PRED)
2326 return 1;
2327 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2328 best_intra_mode != D45_PRED)
2329 return 1;
2330 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2331 best_intra_mode != D135_PRED)
2332 return 1;
2333 return 0;
2334}
2335
hui su308a6392017-01-12 14:49:57 -08002336// Model based RD estimation for luma intra blocks.
2337static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002338 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002339 MACROBLOCKD *const xd = &x->e_mbd;
2340 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002341 assert(!is_inter_block(mbmi));
hui su308a6392017-01-12 14:49:57 -08002342 RD_STATS this_rd_stats;
2343 int row, col;
2344 int64_t temp_sse, this_rd;
2345 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2346 const int stepr = tx_size_high_unit[tx_size];
2347 const int stepc = tx_size_wide_unit[tx_size];
2348 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2349 const int max_blocks_high = max_block_high(xd, bsize, 0);
2350 mbmi->tx_size = tx_size;
2351 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002352 const int step = stepr * stepc;
2353 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002354 for (row = 0; row < max_blocks_high; row += stepr) {
2355 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002356#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09002357 const struct macroblockd_plane *const pd = &xd->plane[0];
2358 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2359 av1_predict_intra_block_encoder_facade(x, 0, block, col, row, tx_size,
2360 plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04002361#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002362 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002363#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002364 block += step;
hui su308a6392017-01-12 14:49:57 -08002365 }
2366 }
2367 // RD estimation.
2368 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2369 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002370#if CONFIG_EXT_INTRA
2371 if (av1_is_directional_mode(mbmi->mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002372 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2373 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002374 }
2375#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002376#if CONFIG_FILTER_INTRA
2377 if (mbmi->mode == DC_PRED) {
2378 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2379 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2380 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2381 mode_cost += (av1_cost_bit(prob, 1) +
2382 write_uniform_cost(FILTER_INTRA_MODES, mode));
2383 } else {
2384 mode_cost += av1_cost_bit(prob, 0);
2385 }
2386 }
2387#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002388 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2389 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002390 return this_rd;
2391}
2392
Urvang Joshib100db72016-10-12 16:28:56 -07002393#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002394// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2395// new_height'. Extra rows and columns are filled in by copying last valid
2396// row/column.
2397static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2398 int orig_height, int new_width,
2399 int new_height) {
2400 int j;
2401 assert(new_width >= orig_width);
2402 assert(new_height >= orig_height);
2403 if (new_width == orig_width && new_height == orig_height) return;
2404
2405 for (j = orig_height - 1; j >= 0; --j) {
2406 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2407 // Copy last column to extra columns.
2408 memset(color_map + j * new_width + orig_width,
2409 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2410 }
2411 // Copy last row to extra rows.
2412 for (j = orig_height; j < new_height; ++j) {
2413 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2414 new_width);
2415 }
2416}
2417
hui sude0c70a2017-01-09 17:12:17 -08002418static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2419 BLOCK_SIZE bsize, int palette_ctx,
2420 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2421 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002422 int64_t *best_rd, int64_t *best_model_rd,
2423 int *rate, int *rate_tokenonly,
2424 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002425 int rate_overhead = 0;
2426 MACROBLOCKD *const xd = &x->e_mbd;
2427 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002428 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002429 assert(!is_inter_block(mbmi));
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002430 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 const int src_stride = x->plane[0].src.stride;
2432 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002433 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002434 int block_width, block_height, rows, cols;
2435 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2436 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002437
2438 assert(cpi->common.allow_screen_content_tools);
2439
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002440#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002441 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002442 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2443 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002444 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002445#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002446 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002447#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002448 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002449#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450
2451 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002452 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002453 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002454 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002455 float *const data = x->palette_buffer->kmeans_data_buf;
2456 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002458 RD_STATS tokenonly_rd_stats;
2459 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002461#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002462 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2463 if (cpi->common.use_highbitdepth)
2464 lb = ub = src16[0];
2465 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002466#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467 lb = ub = src[0];
2468
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002469#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002470 if (cpi->common.use_highbitdepth) {
2471 for (r = 0; r < rows; ++r) {
2472 for (c = 0; c < cols; ++c) {
2473 val = src16[r * src_stride + c];
2474 data[r * cols + c] = val;
2475 if (val < lb)
2476 lb = val;
2477 else if (val > ub)
2478 ub = val;
2479 }
2480 }
2481 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002482#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002483 for (r = 0; r < rows; ++r) {
2484 for (c = 0; c < cols; ++c) {
2485 val = src[r * src_stride + c];
2486 data[r * cols + c] = val;
2487 if (val < lb)
2488 lb = val;
2489 else if (val > ub)
2490 ub = val;
2491 }
2492 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002493#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002495#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002496
2497 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002498#if CONFIG_FILTER_INTRA
2499 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2500#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501
2502 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2503
2504 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2505 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002506 if (colors == PALETTE_MIN_SIZE) {
2507 // Special case: These colors automatically become the centroids.
2508 assert(colors == n);
2509 assert(colors == 2);
2510 centroids[0] = lb;
2511 centroids[1] = ub;
2512 k = 2;
2513 } else {
2514 for (i = 0; i < n; ++i) {
2515 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2516 }
2517 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
2518 k = av1_remove_duplicates(centroids, n);
2519 if (k < PALETTE_MIN_SIZE) {
2520 // Too few unique colors to create a palette. And DC_PRED will work
2521 // well for that case anyway. So skip.
2522 continue;
2523 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002524 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002525
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002526#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527 if (cpi->common.use_highbitdepth)
2528 for (i = 0; i < k; ++i)
2529 pmi->palette_colors[i] =
2530 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2531 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002532#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002533 for (i = 0; i < k; ++i)
2534 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2535 pmi->palette_size[0] = k;
2536
Yaowu Xuf883b422016-08-30 14:01:10 -07002537 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002538 extend_palette_color_map(color_map, cols, rows, block_width,
2539 block_height);
hui su78c611a2017-01-13 17:06:04 -08002540 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002541 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002542 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002543 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002544 av1_cost_bit(
2545 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 1);
hui sud13c24a2017-04-07 16:13:07 -07002547 palette_mode_cost += av1_palette_color_cost_y(pmi, cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 for (i = 0; i < rows; ++i) {
2549 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002550 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002551 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002552 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002553 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002554 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2555 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556 }
2557 }
hui su78c611a2017-01-13 17:06:04 -08002558 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2559 if (*best_model_rd != INT64_MAX &&
2560 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2561 continue;
2562 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2563 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2564 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2565 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002566 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002567 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002568 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002569 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570 if (this_rd < *best_rd) {
2571 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002572 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002573 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002574 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002575 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002576 if (rate) *rate = this_rate;
2577 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2578 if (distortion) *distortion = tokenonly_rd_stats.dist;
2579 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580 }
2581 }
2582 }
hui sude0c70a2017-01-09 17:12:17 -08002583
2584 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2585 memcpy(color_map, best_palette_color_map,
2586 rows * cols * sizeof(best_palette_color_map[0]));
2587 }
2588 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002589 return rate_overhead;
2590}
Urvang Joshib100db72016-10-12 16:28:56 -07002591#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002592
Urvang Joshifeb925f2016-12-05 10:37:29 -08002593static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002594 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2595 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2596 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002597 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002598 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 PREDICTION_MODE mode;
2600 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi330aec82017-05-08 15:37:42 -07002601 assert(!is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002602 int64_t best_rd = rd_thresh;
2603 struct macroblock_plane *p = &x->plane[0];
2604 struct macroblockd_plane *pd = &xd->plane[0];
2605 const int src_stride = p->src.stride;
2606 const int dst_stride = pd->dst.stride;
2607 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002608 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002609#if CONFIG_CB4X4
2610 // TODO(jingning): This is a temporal change. The whole function should be
2611 // out when cb4x4 is enabled.
2612 ENTROPY_CONTEXT ta[4], tempa[4];
2613 ENTROPY_CONTEXT tl[4], templ[4];
2614#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615 ENTROPY_CONTEXT ta[2], tempa[2];
2616 ENTROPY_CONTEXT tl[2], templ[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08002617#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002618
2619 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2620 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2621 const int tx_width_unit = tx_size_wide_unit[tx_size];
2622 const int tx_height_unit = tx_size_high_unit[tx_size];
2623 const int pred_block_width = block_size_wide[bsize];
2624 const int pred_block_height = block_size_high[bsize];
2625 const int tx_width = tx_size_wide[tx_size];
2626 const int tx_height = tx_size_high[tx_size];
2627 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2628 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002629 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002630 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002631 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002632#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002633 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002634#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002635 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2636#if CONFIG_EXT_TX && CONFIG_RECT_TX
2637 const int sub_bsize = bsize;
2638#else
2639 const int sub_bsize = BLOCK_4X4;
2640#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002641
Yushin Cho77bba8d2016-11-04 16:36:56 -07002642#if CONFIG_PVQ
2643 od_rollback_buffer pre_buf, post_buf;
2644 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2645 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002646#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002647
Urvang Joshifeb925f2016-12-05 10:37:29 -08002648 assert(bsize < BLOCK_8X8);
2649 assert(tx_width < 8 || tx_height < 8);
2650#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002651 if (is_lossless)
2652 assert(tx_width == 4 && tx_height == 4);
2653 else
2654 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002655#else
2656 assert(tx_width == 4 && tx_height == 4);
2657#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2658
2659 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2660 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2661
2662 xd->mi[0]->mbmi.tx_size = tx_size;
2663
Urvang Joshib100db72016-10-12 16:28:56 -07002664#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002665 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002666#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002667
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002668#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002669 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002670#if CONFIG_PVQ
2671 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2672#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002673 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2674 int64_t this_rd;
2675 int ratey = 0;
2676 int64_t distortion = 0;
2677 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002678 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679
Urvang Joshifeb925f2016-12-05 10:37:29 -08002680 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2681 (1 << mode)))
2682 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002683
2684 // Only do the oblique modes if the best so far is
2685 // one of the neighboring directional modes
2686 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2687 if (conditional_skipintra(mode, *best_mode)) continue;
2688 }
2689
Urvang Joshifeb925f2016-12-05 10:37:29 -08002690 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2691 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002692
Urvang Joshifeb925f2016-12-05 10:37:29 -08002693 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2694 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2695 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2696 const int block =
2697 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2699 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08002700#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002701 int16_t *const src_diff = av1_raster_block_offset_int16(
2702 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002703#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002704 int skip;
2705 assert(block < 4);
2706 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2707 idx == 0 && idy == 0));
2708 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2709 block == 0 || block == 2));
2710 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002711 av1_predict_intra_block(
2712 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2713 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002714#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002715 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2716 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002717#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002718 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07002719 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002720 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002721 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002722 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002723#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002724 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002725 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07002726 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002727 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002728 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002729 skip = (p->eobs[block] == 0);
2730 can_skip &= skip;
2731 tempa[idx] = !skip;
2732 templ[idy] = !skip;
2733#if CONFIG_EXT_TX
2734 if (tx_size == TX_8X4) {
2735 tempa[idx + 1] = tempa[idx];
2736 } else if (tx_size == TX_4X8) {
2737 templ[idy + 1] = templ[idy];
2738 }
2739#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002740#else
2741 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002742
Thomas Daede6ff6af62017-02-03 16:29:24 -08002743 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2744 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
2745
2746 ratey += x->rate;
2747 skip = x->pvq_skip[0];
2748 tempa[idx] = !skip;
2749 templ[idy] = !skip;
2750 can_skip &= skip;
2751#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002752 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2753 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08002754#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002755 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002756#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002757 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2758 DCT_DCT, tx_size, dst, dst_stride,
2759 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760 } else {
2761 int64_t dist;
2762 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07002763 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002764 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002765 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002766 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002767#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002768 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002769 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002770 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07002771 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002772 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002773 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002774 skip = (p->eobs[block] == 0);
2775 can_skip &= skip;
2776 tempa[idx] = !skip;
2777 templ[idy] = !skip;
2778#if CONFIG_EXT_TX
2779 if (tx_size == TX_8X4) {
2780 tempa[idx + 1] = tempa[idx];
2781 } else if (tx_size == TX_4X8) {
2782 templ[idy + 1] = templ[idy];
2783 }
2784#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002785#else
2786 (void)scan_order;
2787
2788 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2789 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2790 ratey += x->rate;
2791 skip = x->pvq_skip[0];
2792 tempa[idx] = !skip;
2793 templ[idy] = !skip;
2794 can_skip &= skip;
2795#endif
2796#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002797 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002798#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002799 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2800 tx_type, tx_size, dst, dst_stride,
2801 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002802 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002803 dist = (int64_t)tmp << 4;
2804 distortion += dist;
2805 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2806 goto next_highbd;
2807 }
2808 }
2809 }
2810
2811 rate += ratey;
2812 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2813
2814 if (this_rd < best_rd) {
2815 *bestrate = rate;
2816 *bestratey = ratey;
2817 *bestdistortion = distortion;
2818 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002819 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002820 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002821 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2822 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08002823#if CONFIG_PVQ
2824 od_encode_checkpoint(&x->daala_enc, &post_buf);
2825#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002826 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 memcpy(best_dst16 + idy * 8,
2828 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002829 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002830 }
2831 }
2832 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08002833#if CONFIG_PVQ
2834 od_encode_rollback(&x->daala_enc, &pre_buf);
2835#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002836 }
2837
2838 if (best_rd >= rd_thresh) return best_rd;
2839
Thomas Daede6ff6af62017-02-03 16:29:24 -08002840#if CONFIG_PVQ
2841 od_encode_rollback(&x->daala_enc, &post_buf);
2842#endif
2843
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002844 if (y_skip) *y_skip &= best_can_skip;
2845
Urvang Joshifeb925f2016-12-05 10:37:29 -08002846 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002848 best_dst16 + idy * 8,
2849 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002850 }
2851
2852 return best_rd;
2853 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002854#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855
Yushin Cho77bba8d2016-11-04 16:36:56 -07002856#if CONFIG_PVQ
2857 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002858#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002859
Yaowu Xuc27fc142016-08-22 16:08:15 -07002860 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2861 int64_t this_rd;
2862 int ratey = 0;
2863 int64_t distortion = 0;
2864 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002865 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002866
Urvang Joshifeb925f2016-12-05 10:37:29 -08002867 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2868 (1 << mode))) {
2869 continue;
2870 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871
2872 // Only do the oblique modes if the best so far is
2873 // one of the neighboring directional modes
2874 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2875 if (conditional_skipintra(mode, *best_mode)) continue;
2876 }
2877
Urvang Joshifeb925f2016-12-05 10:37:29 -08002878 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2879 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002880
Urvang Joshifeb925f2016-12-05 10:37:29 -08002881 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2882 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2883 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2884 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002885 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2886 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002887#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002888 int16_t *const src_diff = av1_raster_block_offset_int16(
2889 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08002890#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002891 int skip;
2892 assert(block < 4);
2893 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2894 idx == 0 && idy == 0));
2895 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2896 block == 0 || block == 2));
2897 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002898 av1_predict_intra_block(xd, pd->width, pd->height,
2899 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2900 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002901#if CONFIG_CB4X4
2902 2 * (col + idx), 2 * (row + idy),
2903#else
2904 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002905#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002906 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002907#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002908 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2909 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002910#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002911
Urvang Joshi14731732017-04-27 18:40:49 -07002912 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
2913 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
2914 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002915#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002916 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002917#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002918#if !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002919 const AV1_XFORM_QUANT xform_quant =
2920 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
2921 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08002922#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002923 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08002924#else
Urvang Joshi14731732017-04-27 18:40:49 -07002925 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002926#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002927 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08002928
Angie Chiang7dec6c42017-05-03 17:58:17 -07002929 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Urvang Joshi14731732017-04-27 18:40:49 -07002930
2931 ratey +=
2932 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
2933 templ + idy, cpi->sf.use_fast_coef_costing);
2934 skip = (p->eobs[block] == 0);
2935 can_skip &= skip;
2936 tempa[idx] = !skip;
2937 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002938#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07002939 if (tx_size == TX_8X4) {
2940 tempa[idx + 1] = tempa[idx];
2941 } else if (tx_size == TX_4X8) {
2942 templ[idy + 1] = templ[idy];
2943 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08002944#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002945#else
Urvang Joshi14731732017-04-27 18:40:49 -07002946 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08002947
Urvang Joshi14731732017-04-27 18:40:49 -07002948 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08002949#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002950 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08002951#else
Urvang Joshi14731732017-04-27 18:40:49 -07002952 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002953#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002954 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2955
2956 ratey += x->rate;
2957 skip = x->pvq_skip[0];
2958 tempa[idx] = !skip;
2959 templ[idy] = !skip;
2960 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002961#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002962
2963 if (!is_lossless) { // To use the pixel domain distortion, we need to
2964 // calculate inverse txfm *before* calculating RD
2965 // cost. Compared to calculating the distortion in
2966 // the frequency domain, the overhead of encoding
2967 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08002968#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002969 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08002970#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002971 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2972 tx_type, tx_size, dst, dst_stride,
2973 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07002974 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002975 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07002976 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002977 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07002978 }
2979
2980 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2981 goto next;
2982
2983 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
2984#if CONFIG_PVQ
2985 if (!skip)
2986#endif // CONFIG_PVQ
2987 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2988 DCT_DCT, tx_size, dst, dst_stride,
2989 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002990 }
2991 }
2992 }
2993
2994 rate += ratey;
2995 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2996
2997 if (this_rd < best_rd) {
2998 *bestrate = rate;
2999 *bestratey = ratey;
3000 *bestdistortion = distortion;
3001 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003002 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003003 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003004 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3005 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003006#if CONFIG_PVQ
3007 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003008#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003009 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003010 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003011 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003012 }
3013 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003014#if CONFIG_PVQ
3015 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003016#endif // CONFIG_PVQ
3017 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003018
3019 if (best_rd >= rd_thresh) return best_rd;
3020
Yushin Cho77bba8d2016-11-04 16:36:56 -07003021#if CONFIG_PVQ
3022 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003023#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003024
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003025 if (y_skip) *y_skip &= best_can_skip;
3026
Urvang Joshifeb925f2016-12-05 10:37:29 -08003027 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003028 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003029 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003030
3031 return best_rd;
3032}
3033
Urvang Joshi52648442016-10-13 17:27:51 -07003034static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3035 MACROBLOCK *mb, int *rate,
3036 int *rate_y, int64_t *distortion,
3037 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003038 const MACROBLOCKD *const xd = &mb->e_mbd;
3039 MODE_INFO *const mic = xd->mi[0];
3040 const MODE_INFO *above_mi = xd->above_mi;
3041 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003042 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003043 assert(!is_inter_block(mbmi));
Urvang Joshifeb925f2016-12-05 10:37:29 -08003044 const BLOCK_SIZE bsize = mbmi->sb_type;
3045 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3046 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003047 int idx, idy;
3048 int cost = 0;
3049 int64_t total_distortion = 0;
3050 int tot_rate_y = 0;
3051 int64_t total_rd = 0;
3052 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003053 const int is_lossless = xd->lossless[mbmi->segment_id];
3054#if CONFIG_EXT_TX && CONFIG_RECT_TX
3055 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3056#else
3057 const TX_SIZE tx_size = TX_4X4;
3058#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059
3060#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003061#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003062 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003063#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003064#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003065#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003066 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003067#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003068
3069 // TODO(any): Add search of the tx_type to improve rd performance at the
3070 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003071 mbmi->tx_type = DCT_DCT;
3072 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003074 if (y_skip) *y_skip = 1;
3075
Urvang Joshifeb925f2016-12-05 10:37:29 -08003076 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3077 // 8x8 coding block.
3078 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3079 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003080 PREDICTION_MODE best_mode = DC_PRED;
3081 int r = INT_MAX, ry = INT_MAX;
3082 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003083 int j;
3084 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003085 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003086 const PREDICTION_MODE A =
3087 av1_above_block_mode(mic, above_mi, pred_block_idx);
3088 const PREDICTION_MODE L =
3089 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003090
3091 bmode_costs = cpi->y_mode_costs[A][L];
3092 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003093 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003094 cpi, mb, idy, idx, &best_mode, bmode_costs,
3095 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003096 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003097#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003098 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003099#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003100 total_rd += this_rd;
3101 cost += r;
3102 total_distortion += d;
3103 tot_rate_y += ry;
3104
Urvang Joshifeb925f2016-12-05 10:37:29 -08003105 mic->bmi[pred_block_idx].as_mode = best_mode;
3106 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3107 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3108 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3109 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003110
3111 if (total_rd >= best_rd) return INT64_MAX;
3112 }
3113 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003114 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003115
Yushin Cho7a428ba2017-01-12 16:28:49 -08003116#if CONFIG_DAALA_DIST
3117 {
3118 const struct macroblock_plane *p = &mb->plane[0];
3119 const struct macroblockd_plane *pd = &xd->plane[0];
3120 const int src_stride = p->src.stride;
3121 const int dst_stride = pd->dst.stride;
3122 uint8_t *src = p->src.buf;
3123 uint8_t *dst = pd->dst.buf;
3124 int use_activity_masking = 0;
3125 int qm = OD_HVS_QM;
3126
3127#if CONFIG_PVQ
3128 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003129#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003130 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho4483e3d2017-04-18 19:41:20 -07003131 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8,
Yushin Cho7a428ba2017-01-12 16:28:49 -08003132 qm, use_activity_masking, mb->qindex)
3133 << 4;
3134 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003135#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003136 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003137 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003138 int rate_tx_type = 0;
3139#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003140 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3141 1) {
3142 const int eset =
3143 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003144 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3145 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146 }
3147#else
clang-format67948d32016-09-07 22:40:40 -07003148 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003149 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3150 [intra_mode_to_tx_type_context[mbmi->mode]]
3151 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003152#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003153 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003154 cost += rate_tx_type;
3155 tot_rate_y += rate_tx_type;
3156 }
3157
3158 *rate = cost;
3159 *rate_y = tot_rate_y;
3160 *distortion = total_distortion;
3161
3162 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3163}
3164
hui su5db97432016-10-14 16:10:14 -07003165#if CONFIG_FILTER_INTRA
3166// Return 1 if an filter intra mode is selected; return 0 otherwise.
3167static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3168 int *rate, int *rate_tokenonly,
3169 int64_t *distortion, int *skippable,
3170 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003171 int64_t *best_rd, int64_t *best_model_rd,
3172 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003173 MACROBLOCKD *const xd = &x->e_mbd;
3174 MODE_INFO *const mic = xd->mi[0];
3175 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003176 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003177 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003178 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003179 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 TX_TYPE best_tx_type;
3181
hui su5db97432016-10-14 16:10:14 -07003182 av1_zero(filter_intra_mode_info);
3183 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003184 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003185#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003186 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003187#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003188
3189 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003190 int this_rate;
3191 int64_t this_rd, this_model_rd;
3192 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003193 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003194 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003195 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3196 if (*best_model_rd != INT64_MAX &&
3197 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3198 continue;
3199 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003200 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3201 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003202 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003203 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003204 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003205 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003206
3207 if (this_rd < *best_rd) {
3208 *best_rd = this_rd;
3209 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003210 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003211 best_tx_type = mic->mbmi.tx_type;
3212 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003213 *rate_tokenonly = tokenonly_rd_stats.rate;
3214 *distortion = tokenonly_rd_stats.dist;
3215 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003216 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003217 }
3218 }
3219
hui su5db97432016-10-14 16:10:14 -07003220 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221 mbmi->mode = DC_PRED;
3222 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003223 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3224 filter_intra_mode_info.use_filter_intra_mode[0];
3225 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3226 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003227 mbmi->tx_type = best_tx_type;
3228 return 1;
3229 } else {
3230 return 0;
3231 }
3232}
hui su5db97432016-10-14 16:10:14 -07003233#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003234
hui su5db97432016-10-14 16:10:14 -07003235#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003236// Run RD calculation with given luma intra prediction angle., and return
3237// the RD cost. Update the best mode info. if the RD cost is the best so far.
3238static int64_t calc_rd_given_intra_angle(
3239 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3240 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3241 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3242 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003243#if CONFIG_INTRA_INTERP
3244 INTRA_FILTER *best_filter,
3245#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003246 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003247 int this_rate;
3248 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003249 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003250 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003251 assert(!is_inter_block(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003252
hui su45dc5972016-12-08 17:42:50 -08003253 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003254 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3255 if (*best_model_rd != INT64_MAX &&
3256 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3257 return INT64_MAX;
3258 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003259 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3260 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3261
3262 this_rate = tokenonly_rd_stats.rate + mode_cost +
3263 write_uniform_cost(2 * max_angle_delta + 1,
3264 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003265 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003266
3267 if (this_rd < *best_rd) {
3268 *best_rd = this_rd;
3269 *best_angle_delta = mbmi->angle_delta[0];
3270 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003271#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003272 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003273#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003274 *best_tx_type = mbmi->tx_type;
3275 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003276 rd_stats->rate = tokenonly_rd_stats.rate;
3277 rd_stats->dist = tokenonly_rd_stats.dist;
3278 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003279 }
hui su45dc5972016-12-08 17:42:50 -08003280 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003281}
3282
hui su45dc5972016-12-08 17:42:50 -08003283// With given luma directional intra prediction mode, pick the best angle delta
3284// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003285static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003286 int *rate, RD_STATS *rd_stats,
3287 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003288 int64_t best_rd,
3289 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003290 MACROBLOCKD *const xd = &x->e_mbd;
3291 MODE_INFO *const mic = xd->mi[0];
3292 MB_MODE_INFO *mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003293 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08003294 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003295 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003296#if CONFIG_INTRA_INTERP
3297 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003298 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003299 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003300#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003301 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3303 TX_TYPE best_tx_type = mbmi->tx_type;
3304
hui su0a6731f2017-04-26 15:23:47 -07003305 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003306
hui su0a6731f2017-04-26 15:23:47 -07003307 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003308#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003309 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3310 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3311 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003312#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003313 for (i = 0; i < 2; ++i) {
3314 best_rd_in = (best_rd == INT64_MAX)
3315 ? INT64_MAX
3316 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3317 this_rd = calc_rd_given_intra_angle(
3318 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003319#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003320 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003321#else
hui su45dc5972016-12-08 17:42:50 -08003322 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003323#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003324 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003325 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003326#if CONFIG_INTRA_INTERP
3327 &best_filter,
3328#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003329 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003330 rd_cost[2 * angle_delta + i] = this_rd;
3331 if (first_try && this_rd == INT64_MAX) return best_rd;
3332 first_try = 0;
3333 if (angle_delta == 0) {
3334 rd_cost[1] = this_rd;
3335 break;
3336 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003337 }
hui su45dc5972016-12-08 17:42:50 -08003338#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003339 }
hui su45dc5972016-12-08 17:42:50 -08003340#endif // CONFIG_INTRA_INTERP
3341 }
3342
3343 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003344 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003345 int64_t rd_thresh;
3346#if CONFIG_INTRA_INTERP
3347 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3348 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3349 mic->mbmi.intra_filter = filter;
3350#endif // CONFIG_INTRA_INTERP
3351 for (i = 0; i < 2; ++i) {
3352 int skip_search = 0;
3353 rd_thresh = best_rd + (best_rd >> 5);
3354 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3355 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3356 skip_search = 1;
3357 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003358 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003359 cpi, x, bsize,
3360#if CONFIG_INTRA_INTERP
3361 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3362#else
3363 mode_cost,
3364#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003365 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003366 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3367#if CONFIG_INTRA_INTERP
3368 &best_filter,
3369#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003370 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003371 }
3372 }
3373#if CONFIG_INTRA_INTERP
3374 }
3375#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 }
3377
hui sueda3d762016-12-06 16:58:23 -08003378#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003379 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003380 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003381 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003382 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3383 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003384 this_rd = calc_rd_given_intra_angle(
3385 cpi, x, bsize,
3386 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003387 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003388 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003389 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003390 }
3391 }
3392 }
hui sueda3d762016-12-06 16:58:23 -08003393#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003394
3395 mbmi->tx_size = best_tx_size;
3396 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003397#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003398 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003399#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003400 mbmi->tx_type = best_tx_type;
3401 return best_rd;
3402}
3403
3404// Indices are sign, integer, and fractional part of the gradient value
3405static const uint8_t gradient_to_angle_bin[2][7][16] = {
3406 {
3407 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3408 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3409 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3410 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3411 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3412 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3413 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3414 },
3415 {
3416 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3417 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3418 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3419 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3420 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3421 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3422 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3423 },
3424};
3425
3426static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3427 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003428#if CONFIG_ALT_INTRA
3429 0,
3430#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431};
3432
3433static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003434 int cols, BLOCK_SIZE bsize,
3435 uint8_t *directional_mode_skip_mask) {
3436 memset(directional_mode_skip_mask, 0,
3437 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3438 // Sub-8x8 blocks do not use extra directions.
3439 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003440 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003441 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3442 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003443 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003444 for (r = 1; r < rows; ++r) {
3445 for (c = 1; c < cols; ++c) {
3446 dx = src[c] - src[c - 1];
3447 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003448 int index;
3449 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450 if (dy == 0) {
3451 index = 2;
3452 } else {
hui su9cc10652017-04-27 17:22:07 -07003453 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003454 dx = abs(dx);
3455 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003456 const int remd = (dx % dy) * 16 / dy;
3457 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003458 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003459 }
3460 hist[index] += temp;
3461 }
3462 src += src_stride;
3463 }
3464
hui su9cc10652017-04-27 17:22:07 -07003465 int i;
3466 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003467 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3468 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003469 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003470 const uint8_t angle_bin = mode_to_angle_bin[i];
3471 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003472 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003473 if (angle_bin > 0) {
3474 score += hist[angle_bin - 1];
3475 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003476 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003477 if (angle_bin < DIRECTIONAL_MODES - 1) {
3478 score += hist[angle_bin + 1];
3479 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003480 }
3481 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3482 directional_mode_skip_mask[i] = 1;
3483 }
3484 }
3485}
3486
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003487#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003488static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003489 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003490 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003491 memset(directional_mode_skip_mask, 0,
3492 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3493 // Sub-8x8 blocks do not use extra directions.
3494 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003495 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003496 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003497 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3498 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003499 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003500 for (r = 1; r < rows; ++r) {
3501 for (c = 1; c < cols; ++c) {
3502 dx = src[c] - src[c - 1];
3503 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003504 int index;
3505 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003506 if (dy == 0) {
3507 index = 2;
3508 } else {
hui su9cc10652017-04-27 17:22:07 -07003509 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003510 dx = abs(dx);
3511 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003512 const int remd = (dx % dy) * 16 / dy;
3513 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003514 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515 }
3516 hist[index] += temp;
3517 }
3518 src += src_stride;
3519 }
3520
hui su9cc10652017-04-27 17:22:07 -07003521 int i;
3522 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003523 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3524 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003525 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003526 const uint8_t angle_bin = mode_to_angle_bin[i];
3527 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003528 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003529 if (angle_bin > 0) {
3530 score += hist[angle_bin - 1];
3531 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003533 if (angle_bin < DIRECTIONAL_MODES - 1) {
3534 score += hist[angle_bin + 1];
3535 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003536 }
3537 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3538 directional_mode_skip_mask[i] = 1;
3539 }
3540 }
3541}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003542#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003543#endif // CONFIG_EXT_INTRA
3544
3545// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003546static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3547 int *rate, int *rate_tokenonly,
3548 int64_t *distortion, int *skippable,
3549 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003550 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003551 MACROBLOCKD *const xd = &x->e_mbd;
3552 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003553 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003554 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08003555 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003556 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003557#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003558 const int rows = block_size_high[bsize];
3559 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003560#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003561 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003562#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003563 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003564 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 const int src_stride = x->plane[0].src.stride;
3566 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003567#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003568#if CONFIG_FILTER_INTRA
3569 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003570 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3571#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003572 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003573#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003574 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003575 uint8_t *best_palette_color_map =
3576 cpi->common.allow_screen_content_tools
3577 ? x->palette_buffer->best_palette_color_map
3578 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003579 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003580 const int try_palette =
3581 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003582#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003583 const MODE_INFO *above_mi = xd->above_mi;
3584 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003585 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3586 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003587 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003588#if CONFIG_PVQ
3589 od_rollback_buffer pre_buf, post_buf;
3590
3591 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3592 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003593#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 bmode_costs = cpi->y_mode_costs[A][L];
3595
3596#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003597 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003598#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003599 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003600 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601 directional_mode_skip_mask);
3602 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003603#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003604 angle_estimation(src, src_stride, rows, cols, bsize,
3605 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003606#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003607#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003608 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003609#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003610#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003611 pmi->palette_size[0] = 0;
3612 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003613 palette_y_mode_ctx +=
3614 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003615 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003616 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003617#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618
3619 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3620 x->use_default_intra_tx_type = 1;
3621 else
3622 x->use_default_intra_tx_type = 0;
3623
3624 /* Y Search for intra prediction mode */
3625 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003626 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003627 int this_rate, this_rate_tokenonly, s;
3628 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 if (mode_idx == FINAL_MODE_SEARCH) {
3630 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003631 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632 x->use_default_intra_tx_type = 0;
3633 } else {
hui sude0c70a2017-01-09 17:12:17 -08003634 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003635 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003636#if CONFIG_PVQ
3637 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003638#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003639#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003640 mbmi->angle_delta[0] = 0;
3641#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003642 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003643 if (best_model_rd != INT64_MAX &&
3644 this_model_rd > best_model_rd + (best_model_rd >> 1))
3645 continue;
3646 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3647#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003648 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3649 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003650 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003651 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07003652 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
3653 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003654 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003655 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003656 }
3657#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003658 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003659#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003660 this_rate_tokenonly = this_rd_stats.rate;
3661 this_distortion = this_rd_stats.dist;
3662 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003663
3664 if (this_rate_tokenonly == INT_MAX) continue;
3665
hui sude0c70a2017-01-09 17:12:17 -08003666 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003667
hui sude0c70a2017-01-09 17:12:17 -08003668 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003669 // super_block_yrd above includes the cost of the tx_size in the
3670 // tokenonly rate, but for intra blocks, tx_size is always coded
3671 // (prediction granularity), so we account for it in the full rate,
3672 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003673 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003674 }
Urvang Joshib100db72016-10-12 16:28:56 -07003675#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003676 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003677 this_rate +=
3678 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3679 [palette_y_mode_ctx],
3680 0);
hui su9bc1d8d2017-03-24 12:36:03 -07003681 }
Urvang Joshib100db72016-10-12 16:28:56 -07003682#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003683#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003684 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003685 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3686#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003687#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003688 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08003689#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003690 const int p_angle =
3691 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003692 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003693 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003694 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003695#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003696 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
3697 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003698 }
3699#endif // CONFIG_EXT_INTRA
3700 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003701#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003702 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003703 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003704 }
hui su5db97432016-10-14 16:10:14 -07003705#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706
3707 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003708 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003709 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003710#if CONFIG_FILTER_INTRA
3711 beat_best_rd = 1;
3712#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003713 *rate = this_rate;
3714 *rate_tokenonly = this_rate_tokenonly;
3715 *distortion = this_distortion;
3716 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003717#if CONFIG_PVQ
3718 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003719#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720 }
3721 }
3722
Yushin Cho77bba8d2016-11-04 16:36:56 -07003723#if CONFIG_PVQ
3724 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003725#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003726
Luc Trudeaue3980282017-04-25 23:17:21 -04003727#if CONFIG_CFL
3728 // Perform one extra txfm_rd_in_plane() call, this time with the best value so
3729 // we can store reconstructed luma values
3730 RD_STATS this_rd_stats;
3731 x->cfl_store_y = 1;
3732 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, 0, bsize,
3733 mic->mbmi.tx_size, cpi->sf.use_fast_coef_costing);
3734 x->cfl_store_y = 0;
3735#endif
3736
Urvang Joshib100db72016-10-12 16:28:56 -07003737#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003738 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003739 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3740 bmode_costs[DC_PRED], &best_mbmi,
3741 best_palette_color_map, &best_rd, &best_model_rd,
3742 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003743 }
Urvang Joshib100db72016-10-12 16:28:56 -07003744#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003745
hui su5db97432016-10-14 16:10:14 -07003746#if CONFIG_FILTER_INTRA
3747 if (beat_best_rd) {
3748 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3749 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003750 &best_rd, &best_model_rd,
3751 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003752 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003753 }
3754 }
hui su5db97432016-10-14 16:10:14 -07003755#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003756
hui sude0c70a2017-01-09 17:12:17 -08003757 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003758 return best_rd;
3759}
3760
Yue Chena1e48dc2016-08-29 17:29:33 -07003761// Return value 0: early termination triggered, no valid rd cost available;
3762// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003763static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3764 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3765 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003766 MACROBLOCKD *const xd = &x->e_mbd;
3767 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3768 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3769 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003770 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003771 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003772
3773 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003774
Jingning Han31b6a4f2017-02-23 11:05:53 -08003775#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003776 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07003777
3778 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
3779 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08003780#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003781
Yushin Cho77bba8d2016-11-04 16:36:56 -07003782#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003783 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003784 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3785 av1_subtract_plane(x, bsize, plane);
3786 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003787#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003788
Yushin Cho09de28b2016-06-21 14:51:23 -07003789 if (is_cost_valid) {
3790 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003791 RD_STATS pn_rd_stats;
3792 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3793 uv_tx_size, cpi->sf.use_fast_coef_costing);
3794 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003795 is_cost_valid = 0;
3796 break;
3797 }
Angie Chiang284d7772016-11-08 11:06:45 -08003798 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3799 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003800 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003801 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003802 is_cost_valid = 0;
3803 break;
3804 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003805 }
3806 }
3807
3808 if (!is_cost_valid) {
3809 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003810 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003811 }
3812
3813 return is_cost_valid;
3814}
3815
Yaowu Xuc27fc142016-08-22 16:08:15 -07003816#if CONFIG_VAR_TX
Alex Converse61f37b82017-03-29 15:26:03 -07003817// FIXME crop these calls
3818static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
3819 TX_SIZE tx_size) {
3820 return aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size],
3821 tx_size_high[tx_size]);
3822}
3823
Yaowu Xuf883b422016-08-30 14:01:10 -07003824void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3825 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07003826 int plane_bsize, const ENTROPY_CONTEXT *a,
3827 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003828 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003829 MACROBLOCKD *xd = &x->e_mbd;
3830 const struct macroblock_plane *const p = &x->plane[plane];
3831 struct macroblockd_plane *const pd = &xd->plane[plane];
3832 int64_t tmp;
3833 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003834 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003835 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003836 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003837 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003838 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003839 int bh = block_size_high[txm_bsize];
3840 int bw = block_size_wide[txm_bsize];
3841 int txb_h = tx_size_high_unit[tx_size];
3842 int txb_w = tx_size_wide_unit[tx_size];
3843
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003845 uint8_t *src =
3846 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3847 uint8_t *dst =
3848 &pd->dst
3849 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003850#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003851 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3852 uint8_t *rec_buffer;
3853#else
3854 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003855#endif // CONFIG_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003856 int max_blocks_high = block_size_high[plane_bsize];
3857 int max_blocks_wide = block_size_wide[plane_bsize];
3858 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003859 const int16_t *diff =
3860 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003861 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003862
3863 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003864
3865 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003866 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003867 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003868 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3869
3870 max_blocks_high >>= tx_size_wide_log2[0];
3871 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003872
Angie Chiang77368af2017-03-23 16:22:07 -07003873 int coeff_ctx = get_entropy_context(tx_size, a, l);
3874
Angie Chiangff6d8902016-10-21 11:02:09 -07003875 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003876 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003877
Angie Chiangff6d8902016-10-21 11:02:09 -07003878 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879
Angie Chiang808d8592017-04-06 18:36:55 -07003880// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003881#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003882 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3883 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003884 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003885 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886 } else {
3887 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003888 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003889 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003890 }
3891#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003892 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003893 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003894#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895
Jingning Han9fdc4222016-10-27 21:32:19 -07003896 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003897 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003898 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3899 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003900 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003901 for (idy = 0; idy < blocks_height; ++idy) {
3902 for (idx = 0; idx < blocks_width; ++idx) {
3903 const int16_t *d =
3904 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003905 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003906 }
3907 }
3908 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003909 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910 }
3911
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003912#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003913 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3914 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003915#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003916 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07003917 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918
Angie Chiang41fffae2017-04-03 10:33:18 -07003919 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
3920 MAX_TX_SIZE, eob);
3921 if (eob > 0) {
Jingning Han4b47c932016-11-03 09:20:08 -07003922 if (txb_w + blk_col > max_blocks_wide ||
3923 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003924 int idx, idy;
3925 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003926 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3927 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003928 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003929 for (idy = 0; idy < blocks_height; ++idy) {
3930 for (idx = 0; idx < blocks_width; ++idx) {
3931 uint8_t *const s =
3932 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3933 uint8_t *const r =
3934 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003935 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003936 tmp += this_dist;
3937 }
3938 }
3939 } else {
3940 uint32_t this_dist;
3941 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3942 &this_dist);
3943 tmp = this_dist;
3944 }
3945 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003946 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07003947 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07003948 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003949 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07003950 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003951
Angie Chiangd81fdb42016-11-03 12:20:58 -07003952#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003953 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3954 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08003955#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003956}
3957
Yaowu Xuf883b422016-08-30 14:01:10 -07003958static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003959 int blk_col, int plane, int block, int block32,
3960 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003961 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3962 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003963 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003964 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965 MACROBLOCKD *const xd = &x->e_mbd;
3966 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3967 struct macroblock_plane *const p = &x->plane[plane];
3968 struct macroblockd_plane *const pd = &xd->plane[plane];
3969 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3970 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003971 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003972 [MAX_MIB_SIZE] =
3973 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003974 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3975 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003976 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003977 int64_t this_rd = INT64_MAX;
3978 ENTROPY_CONTEXT *pta = ta + blk_col;
3979 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003980 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003981 int ctx =
3982 txfm_partition_context(tx_above + (blk_col >> 1),
3983 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003984 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003985 int tmp_eob = 0;
3986 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003987 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003988 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989
Jingning Han63cbf342016-11-09 15:37:48 -08003990 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003991
Jingning Hand3fada82016-11-22 10:46:55 -08003992 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993
3994 if (ref_best_rd < 0) {
3995 *is_cost_valid = 0;
3996 return;
3997 }
3998
Jingning Hance059e82016-10-31 16:27:28 -07003999 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004000
Angie Chiangc0feea82016-11-03 15:36:18 -07004001 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004002
4003 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4004
Jingning Han1c019f92016-11-21 12:53:32 -08004005 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4006 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004007
4008 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4009 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004010
4011 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4012 rd_stats_stack[block32].rate != INT_MAX) {
4013 *rd_stats = rd_stats_stack[block32];
4014 p->eobs[block] = !rd_stats->skip;
4015 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4016 } else {
4017 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004018 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004019 if (tx_size == TX_32X32) {
4020 rd_stats_stack[block32] = *rd_stats;
4021 }
4022 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004023
Angie Chiangb5dda482016-11-02 16:19:58 -07004024 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4025 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4026 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004027 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004028#if CONFIG_RD_DEBUG
4029 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4030 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004031#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004032 rd_stats->rate = zero_blk_rate;
4033 rd_stats->dist = rd_stats->sse;
4034 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004035 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4036 p->eobs[block] = 0;
4037 } else {
4038 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004039 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040 }
4041
Jingning Han571189c2016-10-24 10:38:43 -07004042 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004043 rd_stats->rate +=
4044 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4045 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046 tmp_eob = p->eobs[block];
4047 }
4048
Jingning Han571189c2016-10-24 10:38:43 -07004049 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004050 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4051 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004052 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004053 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 int this_cost_valid = 1;
4055 int64_t tmp_rd = 0;
4056
Angie Chiangd7246172016-11-03 11:49:15 -07004057 sum_rd_stats.rate =
4058 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004059
4060 assert(tx_size < TX_SIZES_ALL);
4061
Yaowu Xuc27fc142016-08-22 16:08:15 -07004062 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004063 int offsetr = blk_row + (i >> 1) * bsl;
4064 int offsetc = blk_col + (i & 0x01) * bsl;
4065
4066 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4067
Jingning Han63cbf342016-11-09 15:37:48 -08004068 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004069 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004070 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4071 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004072
Angie Chiangc0feea82016-11-03 15:36:18 -07004073 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004074
Angie Chiangd7246172016-11-03 11:49:15 -07004075 tmp_rd =
4076 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004077 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004078 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004079 }
4080 if (this_cost_valid) sum_rd = tmp_rd;
4081 }
4082
4083 if (this_rd < sum_rd) {
4084 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004085 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4086 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004087 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004088 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004089 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004090 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4091 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092 inter_tx_size[idy][idx] = tx_size;
4093 mbmi->tx_size = tx_size;
4094 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004095 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004096 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004097 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004098 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4099 }
4100}
4101
Angie Chiangb5dda482016-11-02 16:19:58 -07004102static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4103 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004104 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 MACROBLOCKD *const xd = &x->e_mbd;
4106 int is_cost_valid = 1;
4107 int64_t this_rd = 0;
4108
4109 if (ref_best_rd < 0) is_cost_valid = 0;
4110
Angie Chiangc0feea82016-11-03 15:36:18 -07004111 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004112
4113 if (is_cost_valid) {
4114 const struct macroblockd_plane *const pd = &xd->plane[0];
4115 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004116 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4117 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004118 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004119 const int bh = tx_size_high_unit[max_tx_size];
4120 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004121 int idx, idy;
4122 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004123 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004124 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004125 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4126 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4127 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4128 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4129
Angie Chiangb5dda482016-11-02 16:19:58 -07004130 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004131 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004132
Jingning Han9ca05b72017-01-03 14:41:36 -08004133 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004134 memcpy(tx_above, xd->above_txfm_context,
4135 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4136 memcpy(tx_left, xd->left_txfm_context,
4137 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4138
4139 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004140 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004141 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004142 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004143 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004144 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004145 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004146 this_rd += AOMMIN(
4147 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4148 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004149 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004150 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151 }
4152 }
4153 }
4154
Angie Chiangb5dda482016-11-02 16:19:58 -07004155 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4156 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004157 if (this_rd > ref_best_rd) is_cost_valid = 0;
4158
4159 if (!is_cost_valid) {
4160 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004161 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004162 }
4163}
4164
Yaowu Xuf883b422016-08-30 14:01:10 -07004165static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004166 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004167 int64_t ref_best_rd, TX_TYPE tx_type,
4168 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004169 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004170 MACROBLOCKD *const xd = &x->e_mbd;
4171 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004172 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004173 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4174 int s0 = av1_cost_bit(skip_prob, 0);
4175 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004176 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004177 int row, col;
4178 const int max_blocks_high = max_block_high(xd, bsize, 0);
4179 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180
4181 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004182 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004183 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004184
Angie Chiangb5dda482016-11-02 16:19:58 -07004185 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186
Jingning Hane67b38a2016-11-04 10:30:00 -07004187 for (row = 0; row < max_blocks_high / 2; ++row)
4188 for (col = 0; col < max_blocks_wide / 2; ++col)
4189 mbmi->min_tx_size = AOMMIN(
4190 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4191
Yaowu Xuc27fc142016-08-22 16:08:15 -07004192#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004193 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4194 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004195 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004196 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4197 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004198 if (is_inter) {
4199 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004200 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004201 cpi->inter_tx_type_costs[ext_tx_set]
4202 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004203 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204 } else {
4205 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004206 rd_stats->rate +=
4207 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4208 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209 }
4210 }
4211#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004212 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4213 rd_stats->rate +=
4214 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215#endif // CONFIG_EXT_TX
4216
Angie Chiangb5dda482016-11-02 16:19:58 -07004217 if (rd_stats->skip)
4218 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004219 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004220 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004221
Angie Chiangb5dda482016-11-02 16:19:58 -07004222 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4223 !(rd_stats->skip))
4224 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004225
4226 return rd;
4227}
4228
Angie Chiangb5dda482016-11-02 16:19:58 -07004229static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4230 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004232 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004233 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4234 MACROBLOCKD *const xd = &x->e_mbd;
4235 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4236 int64_t rd = INT64_MAX;
4237 int64_t best_rd = INT64_MAX;
4238 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4239 const int is_inter = is_inter_block(mbmi);
4240 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004241 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004242 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004243 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Angie Chiangf1cb0752017-04-10 16:01:20 -07004244 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245 int idx, idy;
4246 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004247 const int count32 =
4248 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004249#if CONFIG_EXT_PARTITION
4250 RD_STATS rd_stats_stack[16];
4251#else
Jingning Han63cbf342016-11-09 15:37:48 -08004252 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004253#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004254#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004255 const int ext_tx_set =
4256 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004257#endif // CONFIG_EXT_TX
4258
4259 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4260#if CONFIG_EXT_TX
4261 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4262#else
4263 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004264#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004265
Angie Chiangc0feea82016-11-03 15:36:18 -07004266 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004267
Jingning Han89d648b2016-11-22 11:22:08 -08004268 for (idx = 0; idx < count32; ++idx)
4269 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004270
Yaowu Xuc27fc142016-08-22 16:08:15 -07004271 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004272 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004273 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004274#if CONFIG_EXT_TX
4275 if (is_inter) {
4276 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4277 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4278 if (!do_tx_type_search(tx_type, prune)) continue;
4279 }
4280 } else {
4281 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4282 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4283 }
4284 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4285 }
4286#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004287 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4288 !do_tx_type_search(tx_type, prune))
4289 continue;
4290#endif // CONFIG_EXT_TX
4291 if (is_inter && x->use_default_inter_tx_type &&
4292 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4293 continue;
4294
Jingning Hane67b38a2016-11-04 10:30:00 -07004295 if (xd->lossless[mbmi->segment_id])
4296 if (tx_type != DCT_DCT) continue;
4297
Angie Chiangb5dda482016-11-02 16:19:58 -07004298 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004299 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004300
4301 if (rd < best_rd) {
4302 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004303 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004304 best_tx_type = mbmi->tx_type;
4305 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004306 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004307 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4308 for (idy = 0; idy < xd->n8_h; ++idy)
4309 for (idx = 0; idx < xd->n8_w; ++idx)
4310 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4311 }
4312 }
4313
4314 mbmi->tx_type = best_tx_type;
4315 for (idy = 0; idy < xd->n8_h; ++idy)
4316 for (idx = 0; idx < xd->n8_w; ++idx)
4317 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4318 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004319 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004320 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4321}
4322
Yaowu Xuf883b422016-08-30 14:01:10 -07004323static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004324 int blk_col, int plane, int block, TX_SIZE tx_size,
4325 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004326 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004327 MACROBLOCKD *const xd = &x->e_mbd;
4328 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4329 struct macroblock_plane *const p = &x->plane[plane];
4330 struct macroblockd_plane *const pd = &xd->plane[plane];
4331 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4332 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4333 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4334 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004335 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4336 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004337
Jingning Hand3fada82016-11-22 10:46:55 -08004338 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004339
Yaowu Xuc27fc142016-08-22 16:08:15 -07004340 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4341
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004342 plane_tx_size =
4343 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4344 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004345
4346 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004347 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4349 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004350 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004351 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004352
Jingning Han58224042016-10-27 16:35:32 -07004353 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004354 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004355 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004356 tl[i] = !(p->eobs[block] == 0);
4357 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004358 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4359 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004360 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004361 int i;
4362
4363 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364
4365 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004366 int offsetr = blk_row + (i >> 1) * bsl;
4367 int offsetc = blk_col + (i & 0x01) * bsl;
4368
4369 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4370
4371 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4372 above_ctx, left_ctx, rd_stats);
4373 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004374 }
4375 }
4376}
4377
4378// Return value 0: early termination triggered, no valid rd cost available;
4379// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004380static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4381 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4382 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004383 MACROBLOCKD *const xd = &x->e_mbd;
4384 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4385 int plane;
4386 int is_cost_valid = 1;
4387 int64_t this_rd;
4388
4389 if (ref_best_rd < 0) is_cost_valid = 0;
4390
Angie Chiangc0feea82016-11-03 15:36:18 -07004391 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004392
Jingning Han31b6a4f2017-02-23 11:05:53 -08004393#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004394 if (x->skip_chroma_rd) return is_cost_valid;
4395 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08004396#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004397
Yue Chena1e48dc2016-08-29 17:29:33 -07004398#if CONFIG_EXT_TX && CONFIG_RECT_TX
4399 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004400 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004401 }
4402#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4403
Yaowu Xuc27fc142016-08-22 16:08:15 -07004404 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004405 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004406 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407 }
4408
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4410 const struct macroblockd_plane *const pd = &xd->plane[plane];
4411 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004412 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4413 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004414 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004415 const int bh = tx_size_high_unit[max_tx_size];
4416 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417 int idx, idy;
4418 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004419 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004420 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4421 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004422 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004423 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424
Jingning Han9ca05b72017-01-03 14:41:36 -08004425 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004426
4427 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004428 for (idx = 0; idx < mi_width; idx += bw) {
4429 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004430 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004431 block += step;
4432 }
4433 }
4434
Angie Chiangb5dda482016-11-02 16:19:58 -07004435 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004436 is_cost_valid = 0;
4437 break;
4438 }
4439
Angie Chiang628d7c92016-11-03 16:24:56 -07004440 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004441
Angie Chiangb5dda482016-11-02 16:19:58 -07004442 this_rd =
4443 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4444 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004445
4446 if (this_rd > ref_best_rd) {
4447 is_cost_valid = 0;
4448 break;
4449 }
4450 }
4451
4452 if (!is_cost_valid) {
4453 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004454 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004455 }
4456
4457 return is_cost_valid;
4458}
4459#endif // CONFIG_VAR_TX
4460
Urvang Joshib100db72016-10-12 16:28:56 -07004461#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004462static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4463 int dc_mode_cost,
4464 uint8_t *best_palette_color_map,
4465 MB_MODE_INFO *const best_mbmi,
4466 int64_t *best_rd, int *rate,
4467 int *rate_tokenonly, int64_t *distortion,
4468 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004469 MACROBLOCKD *const xd = &x->e_mbd;
4470 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004471 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08004472 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004473 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004474 int this_rate;
4475 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004476 int colors_u, colors_v, colors;
4477 const int src_stride = x->plane[1].src.stride;
4478 const uint8_t *const src_u = x->plane[1].src.buf;
4479 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004480 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004481 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004482 int plane_block_width, plane_block_height, rows, cols;
4483 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4484 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004485 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4486
hui su83c26632017-01-24 17:19:06 -08004487 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004488#if CONFIG_FILTER_INTRA
4489 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4490#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004491
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004492#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004493 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004494 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4495 cpi->common.bit_depth);
4496 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4497 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004498 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004499#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004500 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4501 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004502#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004503 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004504#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004505
4506 colors = colors_u > colors_v ? colors_u : colors_v;
4507 if (colors > 1 && colors <= 64) {
4508 int r, c, n, i, j;
4509 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004510 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004511 float lb_u, ub_u, val_u;
4512 float lb_v, ub_v, val_v;
4513 float *const data = x->palette_buffer->kmeans_data_buf;
4514 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004515
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004516#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004517 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4518 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4519 if (cpi->common.use_highbitdepth) {
4520 lb_u = src_u16[0];
4521 ub_u = src_u16[0];
4522 lb_v = src_v16[0];
4523 ub_v = src_v16[0];
4524 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004525#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526 lb_u = src_u[0];
4527 ub_u = src_u[0];
4528 lb_v = src_v[0];
4529 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004530#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004531 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004532#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533
Yaowu Xuc27fc142016-08-22 16:08:15 -07004534 for (r = 0; r < rows; ++r) {
4535 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004536#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004537 if (cpi->common.use_highbitdepth) {
4538 val_u = src_u16[r * src_stride + c];
4539 val_v = src_v16[r * src_stride + c];
4540 data[(r * cols + c) * 2] = val_u;
4541 data[(r * cols + c) * 2 + 1] = val_v;
4542 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004543#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004544 val_u = src_u[r * src_stride + c];
4545 val_v = src_v[r * src_stride + c];
4546 data[(r * cols + c) * 2] = val_u;
4547 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004548#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004549 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004550#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004551 if (val_u < lb_u)
4552 lb_u = val_u;
4553 else if (val_u > ub_u)
4554 ub_u = val_u;
4555 if (val_v < lb_v)
4556 lb_v = val_v;
4557 else if (val_v > ub_v)
4558 ub_v = val_v;
4559 }
4560 }
4561
4562 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4563 --n) {
4564 for (i = 0; i < n; ++i) {
4565 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4566 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4567 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004568 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07004569#if CONFIG_PALETTE_DELTA_ENCODING
4570 // Sort the U channel colors in ascending order.
4571 for (i = 0; i < 2 * (n - 1); i += 2) {
4572 int min_idx = i;
4573 float min_val = centroids[i];
4574 for (j = i + 2; j < 2 * n; j += 2)
4575 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
4576 if (min_idx != i) {
4577 float temp_u = centroids[i], temp_v = centroids[i + 1];
4578 centroids[i] = centroids[min_idx];
4579 centroids[i + 1] = centroids[min_idx + 1];
4580 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
4581 }
4582 }
4583 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
4584#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004585 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4586 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004587 pmi->palette_size[1] = n;
4588 for (i = 1; i < 3; ++i) {
4589 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004590#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004591 if (cpi->common.use_highbitdepth)
4592 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4593 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4594 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004595#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004596 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4597 clip_pixel((int)centroids[j * 2 + i - 1]);
4598 }
4599 }
4600
Angie Chiang284d7772016-11-08 11:06:45 -08004601 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4602 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004603 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004604 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08004605 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004606 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004607 av1_cost_bit(
4608 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui sud13c24a2017-04-07 16:13:07 -07004609 this_rate += av1_palette_color_cost_uv(pmi, cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610 for (i = 0; i < rows; ++i) {
4611 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004612 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004613 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004614 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004615 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004616 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4617 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004618 }
4619 }
4620
Angie Chiang284d7772016-11-08 11:06:45 -08004621 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004622 if (this_rd < *best_rd) {
4623 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004624 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004625 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004626 plane_block_width * plane_block_height *
4627 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004628 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004629 *distortion = tokenonly_rd_stats.dist;
4630 *rate_tokenonly = tokenonly_rd_stats.rate;
4631 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004632 }
4633 }
4634 }
hui su83c26632017-01-24 17:19:06 -08004635 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004636 memcpy(color_map, best_palette_color_map,
4637 rows * cols * sizeof(best_palette_color_map[0]));
4638 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004639}
Urvang Joshib100db72016-10-12 16:28:56 -07004640#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004641
hui su5db97432016-10-14 16:10:14 -07004642#if CONFIG_FILTER_INTRA
4643// Return 1 if an filter intra mode is selected; return 0 otherwise.
4644static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4645 int *rate, int *rate_tokenonly,
4646 int64_t *distortion, int *skippable,
4647 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004648 MACROBLOCKD *const xd = &x->e_mbd;
4649 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004650 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004651 int this_rate;
4652 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004653 FILTER_INTRA_MODE mode;
4654 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004655 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004656
hui su5db97432016-10-14 16:10:14 -07004657 av1_zero(filter_intra_mode_info);
4658 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004659 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004660#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004661 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004662#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663
4664 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004665 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004666 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004667 continue;
4668
Angie Chiang284d7772016-11-08 11:06:45 -08004669 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004670 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004671 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4672 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004673 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004674 if (this_rd < *best_rd) {
4675 *best_rd = this_rd;
4676 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004677 *rate_tokenonly = tokenonly_rd_stats.rate;
4678 *distortion = tokenonly_rd_stats.dist;
4679 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004680 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4681 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004682 }
4683 }
4684
hui su5db97432016-10-14 16:10:14 -07004685 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004686 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004687 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4688 filter_intra_mode_info.use_filter_intra_mode[1];
4689 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4690 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004691 return 1;
4692 } else {
4693 return 0;
4694 }
4695}
hui su5db97432016-10-14 16:10:14 -07004696#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004697
hui su5db97432016-10-14 16:10:14 -07004698#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004699// Run RD calculation with given chroma intra prediction angle., and return
4700// the RD cost. Update the best mode info. if the RD cost is the best so far.
4701static int64_t pick_intra_angle_routine_sbuv(
4702 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4703 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4704 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004705 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004706 assert(!is_inter_block(mbmi));
Angie Chiang284d7772016-11-08 11:06:45 -08004707 int this_rate;
4708 int64_t this_rd;
4709 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710
hui su45dc5972016-12-08 17:42:50 -08004711 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4712 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004713 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4714 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004715 if (this_rd < *best_rd) {
4716 *best_rd = this_rd;
4717 *best_angle_delta = mbmi->angle_delta[1];
4718 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004719 rd_stats->rate = tokenonly_rd_stats.rate;
4720 rd_stats->dist = tokenonly_rd_stats.dist;
4721 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004722 }
hui su45dc5972016-12-08 17:42:50 -08004723 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004724}
4725
hui su45dc5972016-12-08 17:42:50 -08004726// With given chroma directional intra prediction mode, pick the best angle
4727// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004728static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004729 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004730 int64_t best_rd, int *rate,
4731 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732 MACROBLOCKD *const xd = &x->e_mbd;
4733 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004734 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08004735 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07004736 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004737
hui su45dc5972016-12-08 17:42:50 -08004738 rd_stats->rate = INT_MAX;
4739 rd_stats->skip = 0;
4740 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07004741 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004742
hui su0a6731f2017-04-26 15:23:47 -07004743 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004744 for (i = 0; i < 2; ++i) {
4745 best_rd_in = (best_rd == INT64_MAX)
4746 ? INT64_MAX
4747 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4748 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4749 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4750 best_rd_in, rate, rd_stats,
4751 &best_angle_delta, &best_rd);
4752 rd_cost[2 * angle_delta + i] = this_rd;
4753 if (angle_delta == 0) {
4754 if (this_rd == INT64_MAX) return 0;
4755 rd_cost[1] = this_rd;
4756 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004757 }
4758 }
hui su45dc5972016-12-08 17:42:50 -08004759 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004760
hui su45dc5972016-12-08 17:42:50 -08004761 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07004762 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004763 int64_t rd_thresh;
4764 for (i = 0; i < 2; ++i) {
4765 int skip_search = 0;
4766 rd_thresh = best_rd + (best_rd >> 5);
4767 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4768 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4769 skip_search = 1;
4770 if (!skip_search) {
4771 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07004772 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4773 rate, rd_stats, &best_angle_delta,
4774 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004775 }
4776 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004777 }
4778
4779 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004780 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004781}
4782#endif // CONFIG_EXT_INTRA
4783
Urvang Joshi52648442016-10-13 17:27:51 -07004784static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4785 int *rate, int *rate_tokenonly,
4786 int64_t *distortion, int *skippable,
4787 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788 MACROBLOCKD *xd = &x->e_mbd;
4789 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004790 assert(!is_inter_block(mbmi));
hui su83c26632017-01-24 17:19:06 -08004791 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004792 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004793 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004794 int this_rate;
4795 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004796#if CONFIG_PVQ
4797 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004798 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004799#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004800#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004801 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004802 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004803#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004804
hui su83c26632017-01-24 17:19:06 -08004805#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004806 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4807#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004808#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004809 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004810#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004811 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004812#if CONFIG_EXT_INTRA
4813 const int is_directional_mode =
4814 av1_is_directional_mode(mode, mbmi->sb_type);
4815#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004816 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4817 (1 << mode)))
4818 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004819
4820 mbmi->uv_mode = mode;
4821#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004822 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004823 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004824 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4825 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004826 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4827 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004828 continue;
4829 } else {
hui su83c26632017-01-24 17:19:06 -08004830#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004831 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004832#if CONFIG_PVQ
4833 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004834#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004835 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004836 }
hui su83c26632017-01-24 17:19:06 -08004837#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004838 }
hui su83c26632017-01-24 17:19:06 -08004839#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004840 this_rate =
4841 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004842
4843#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004844 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004845 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4846 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08004847 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004848#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004849#if CONFIG_FILTER_INTRA
4850 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4851 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4852#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004853#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004854 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4855 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004856 this_rate += av1_cost_bit(
4857 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004858#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004859
Yushin Cho77bba8d2016-11-04 16:36:56 -07004860#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004861 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004862#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004863 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004864
4865 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004866 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004867 best_rd = this_rd;
4868 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004869 *rate_tokenonly = tokenonly_rd_stats.rate;
4870 *distortion = tokenonly_rd_stats.dist;
4871 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004872 }
4873 }
4874
Urvang Joshib100db72016-10-12 16:28:56 -07004875#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004876 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4877 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004878 rd_pick_palette_intra_sbuv(cpi, x,
4879 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4880 best_palette_color_map, &best_mbmi, &best_rd,
4881 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004882 }
Urvang Joshib100db72016-10-12 16:28:56 -07004883#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004884
hui su5db97432016-10-14 16:10:14 -07004885#if CONFIG_FILTER_INTRA
4886 if (mbmi->sb_type >= BLOCK_8X8) {
4887 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004888 skippable, bsize, &best_rd))
4889 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004890 }
hui su5db97432016-10-14 16:10:14 -07004891#endif // CONFIG_FILTER_INTRA
4892
hui su83c26632017-01-24 17:19:06 -08004893 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004894 // Make sure we actually chose a mode
4895 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004896 return best_rd;
4897}
4898
Urvang Joshi52648442016-10-13 17:27:51 -07004899static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004900 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4901 TX_SIZE max_tx_size, int *rate_uv,
4902 int *rate_uv_tokenonly, int64_t *dist_uv,
4903 int *skip_uv, PREDICTION_MODE *mode_uv) {
4904 // Use an estimated rd for uv_intra based on DC_PRED if the
4905 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004906 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004907#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004908#if CONFIG_CHROMA_2X2
4909 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4910 bsize, max_tx_size);
4911#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004912 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4913 if (x->skip_chroma_rd) {
4914 *rate_uv = 0;
4915 *rate_uv_tokenonly = 0;
4916 *dist_uv = 0;
4917 *skip_uv = 1;
4918 *mode_uv = DC_PRED;
4919 return;
4920 }
Jingning Han65113f32017-04-12 10:06:58 -07004921 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
4922 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07004923 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07004924 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004925#endif // CONFIG_CHROMA_2X2
4926#else
4927 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4928 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4929#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004930 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4931}
4932
Urvang Joshi52648442016-10-13 17:27:51 -07004933static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004934 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004935#if CONFIG_EXT_INTER
4936 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004937 return cpi
4938 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004939 }
David Barkercb03dc32017-04-07 13:05:09 +01004940#endif
4941
David Barkercb03dc32017-04-07 13:05:09 +01004942 int mode_cost = 0;
4943 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4944 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4945
4946 assert(is_inter_mode(mode));
4947
4948 if (mode == NEWMV) {
4949 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4950 return mode_cost;
4951 } else {
4952 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4953 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4954
4955 if (is_all_zero_mv) return mode_cost;
4956
4957 if (mode == ZEROMV) {
4958 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4959 return mode_cost;
4960 } else {
4961 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4962 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4963
4964 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4965 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4966 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4967
4968 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4969 return mode_cost;
4970 }
4971 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004972}
4973
Sarah Parker6fdc8532016-11-16 17:47:13 -08004974#if CONFIG_EXT_INTER
4975static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4976 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004977 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08004978 switch (comp_type) {
4979 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004980#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08004981 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004982#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08004983#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08004984 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08004985#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08004986 default: assert(0); return 0;
4987 }
4988}
4989#endif // CONFIG_EXT_INTER
4990
clang-format55ce9e02017-02-15 22:27:12 -08004991static int set_and_cost_bmi_mvs(
4992 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
4993 PREDICTION_MODE mode, int_mv this_mv[2],
4994 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
4995 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004996#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08004997 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004998#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00004999 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
5000 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005001 MODE_INFO *const mic = xd->mi[0];
5002 const MB_MODE_INFO *const mbmi = &mic->mbmi;
5003 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5004 int thismvcost = 0;
5005 int idx, idy;
5006 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
5007 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
5008 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08005009 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00005010 (void)mi_row;
5011 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005012
5013 switch (mode) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005014 case NEWMV: this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005015#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005016 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005017 lower_mv_precision(&this_mv[0].as_mv, 0);
5018#endif // CONFIG_EXT_INTER
5019
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 for (idx = 0; idx < 1 + is_compound; ++idx) {
5021 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005022 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005023 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005024 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5025 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005026 }
5027 (void)mvjcost;
5028 (void)mvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005029 break;
5030 case NEARMV:
5031 case NEARESTMV:
5032 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5033 if (is_compound)
5034 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5035 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005036 case ZEROMV: {
5037 int ref;
5038 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005039#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005040 this_mv[ref].as_int =
5041 gm_get_motion_vector(
5042 &cpi->common.global_motion[mbmi->ref_frame[ref]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005043 cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005044 mi_row, i)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005045 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005046#else
5047 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005048#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005049 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005050 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005051 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005052#if CONFIG_EXT_INTER
5053 case NEW_NEWMV:
5054 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5055 compound_seg_newmvs[1].as_int == INVALID_MV) {
5056 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5057 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5058 } else {
5059 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5060 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5061 }
Alex Converse6317c882016-09-29 14:21:37 -07005062 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005063 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005064 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005065 lower_mv_precision(&this_mv[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005066 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005067 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5068 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
David Barker404b2e82017-03-27 13:07:47 +01005069 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005070 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5071 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005072 break;
5073 case NEW_NEARMV:
5074 case NEW_NEARESTMV:
5075 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005076 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005077 lower_mv_precision(&this_mv[0].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005078 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005079 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5080 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5082 break;
5083 case NEAR_NEWMV:
5084 case NEAREST_NEWMV:
5085 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5086 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005087 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005088 lower_mv_precision(&this_mv[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005089 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005090 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5091 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005092 break;
5093 case NEAREST_NEARMV:
5094 case NEAR_NEARESTMV:
5095 case NEAREST_NEARESTMV:
5096 case NEAR_NEARMV:
5097 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5098 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5099 break;
5100 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005101#if CONFIG_GLOBAL_MOTION
5102 this_mv[0].as_int =
5103 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005104 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005105 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005106 .as_int;
5107 this_mv[1].as_int =
5108 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005109 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005110 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005111 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005112#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005113 this_mv[0].as_int = 0;
5114 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005115#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116 break;
5117#endif // CONFIG_EXT_INTER
5118 default: break;
5119 }
5120
5121 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5122 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5123
5124 mic->bmi[i].as_mode = mode;
5125
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005127 mic->bmi[i].pred_mv[0].as_int =
5128 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5129 if (is_compound)
5130 mic->bmi[i].pred_mv[1].as_int =
5131 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005132 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005133 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5134 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005135 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136
5137 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5138 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5139 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5140
Yaowu Xuc27fc142016-08-22 16:08:15 -07005141#if CONFIG_EXT_INTER
5142 if (is_compound)
5143 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5144 else
5145#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005146 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5147 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005149}
5150
Yushin Choab44fd12017-01-09 16:06:53 -08005151static int64_t encode_inter_mb_segment_sub8x8(
5152 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5153 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5154 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005155 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005156 MACROBLOCKD *xd = &x->e_mbd;
5157 struct macroblockd_plane *const pd = &xd->plane[0];
5158 struct macroblock_plane *const p = &x->plane[0];
5159 MODE_INFO *const mi = xd->mi[0];
5160 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005161 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5162 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005163 const int width = block_size_wide[plane_bsize];
5164 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005165 int idx, idy;
5166 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005167 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005168 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005169 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005170 int64_t thisdistortion = 0, thissse = 0;
5171 int thisrate = 0;
5172 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005173 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005174 const int num_4x4_w = tx_size_wide_unit[tx_size];
5175 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005176#if !CONFIG_PVQ
5177 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5178#else
5179 (void)cpi;
5180 (void)ta;
5181 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005182 (void)tx_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08005183#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005184
5185#if CONFIG_EXT_TX && CONFIG_RECT_TX
5186 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5187 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5188 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5189#else
5190 assert(tx_size == TX_4X4);
5191#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005192
Yaowu Xuc27fc142016-08-22 16:08:15 -07005193 assert(tx_type == DCT_DCT);
5194
Jingning Hanc44009c2017-05-06 11:36:49 -07005195 av1_build_inter_predictor_sub8x8(cm, xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005196
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005197#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005199 aom_highbd_subtract_block(
5200 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5201 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005202 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005203 aom_subtract_block(height, width,
5204 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 8, src, p->src.stride, dst, pd->dst.stride);
5206 }
5207#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005208 aom_subtract_block(height, width,
5209 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 8, src, p->src.stride, dst, pd->dst.stride);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005211#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212
Jingning Hanbafee8d2016-12-02 10:25:03 -08005213 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5214 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005216 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005217 const int k = i + (idy * 2 + idx);
5218 const int block = av1_raster_order_to_block_index(tx_size, k);
5219 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5220 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005221 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Angie Chiangff6d8902016-10-21 11:02:09 -07005222 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005223 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07005224 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang808d8592017-04-06 18:36:55 -07005225 av1_dist_block(cpi, x, 0, BLOCK_8X8, block, idy + (i >> 1),
5226 idx + (i & 0x1), tx_size, &dist, &ssz,
5227 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005228 thisdistortion += dist;
5229 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005230#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005231 thisrate +=
Angie Chiang05917872017-04-15 12:28:56 -07005232 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, (ta + (k & 1)),
Angie Chiang77368af2017-03-23 16:22:07 -07005233 (tl + (k >> 1)), cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005234 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5235 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005236#else
5237 thisrate += x->rate;
Fergus Simpson4063a682017-02-28 16:52:22 -08005238#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239#if CONFIG_EXT_TX
5240 if (tx_size == TX_8X4) {
5241 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5242 }
5243 if (tx_size == TX_4X8) {
5244 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5245 }
5246#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005247 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5248 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005249 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005250 if (rd >= best_yrd) return INT64_MAX;
5251 }
5252 }
5253
5254 *distortion = thisdistortion;
5255 *labelyrate = thisrate;
5256 *sse = thissse;
5257
5258 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5259}
5260
5261typedef struct {
5262 int eobs;
5263 int brate;
5264 int byrate;
5265 int64_t bdist;
5266 int64_t bsse;
5267 int64_t brdcost;
5268 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005269 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005270#if CONFIG_EXT_INTER
5271 int_mv ref_mv[2];
5272#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005273
5274#if CONFIG_CB4X4
5275 ENTROPY_CONTEXT ta[4];
5276 ENTROPY_CONTEXT tl[4];
5277#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005278 ENTROPY_CONTEXT ta[2];
5279 ENTROPY_CONTEXT tl[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005280#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005281} SEG_RDSTAT;
5282
5283typedef struct {
5284 int_mv *ref_mv[2];
5285 int_mv mvp;
5286
5287 int64_t segment_rd;
5288 int r;
5289 int64_t d;
5290 int64_t sse;
5291 int segment_yrate;
5292 PREDICTION_MODE modes[4];
5293#if CONFIG_EXT_INTER
5294 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5295#else
5296 SEG_RDSTAT rdstat[4][INTER_MODES];
5297#endif // CONFIG_EXT_INTER
5298 int mvthresh;
5299} BEST_SEG_INFO;
5300
Alex Converse0fa0f422017-04-24 12:51:14 -07005301static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5302 return (mv->row >> 3) < mv_limits->row_min ||
5303 (mv->row >> 3) > mv_limits->row_max ||
5304 (mv->col >> 3) < mv_limits->col_min ||
5305 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005306}
5307
5308static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5309 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5310 struct macroblock_plane *const p = &x->plane[0];
5311 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5312
5313 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005314 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005315 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5316 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005317 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005318 if (has_second_ref(mbmi))
5319 pd->pre[1].buf =
5320 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005321 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005322}
5323
5324static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5325 struct buf_2d orig_pre[2]) {
5326 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5327 x->plane[0].src = orig_src;
5328 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5329 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5330}
5331
5332// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5333// TODO(aconverse): Find out if this is still productive then clean up or remove
5334static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005335 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005336#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005337 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005338#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005339 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005340 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5341 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005342 int_mv zeromv[2];
5343 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5344 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005345 (void)mi_row;
5346 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005347 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5348#if CONFIG_GLOBAL_MOTION
5349 if (this_mode == ZEROMV
5350#if CONFIG_EXT_INTER
5351 || this_mode == ZERO_ZEROMV
5352#endif // CONFIG_EXT_INTER
5353 )
5354 zeromv[cur_frm].as_int =
5355 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005356 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005357 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005358 .as_int;
5359 else
5360#endif // CONFIG_GLOBAL_MOTION
5361 zeromv[cur_frm].as_int = 0;
5362 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005363#if !CONFIG_EXT_INTER
5364 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005365#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005366 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005367 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005369 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005370 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005371 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005372 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5373 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5374 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005375
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376 if (this_mode == NEARMV) {
5377 if (c1 > c3) return 0;
5378 } else if (this_mode == NEARESTMV) {
5379 if (c2 > c3) return 0;
5380 } else {
5381 assert(this_mode == ZEROMV);
5382 if (ref_frames[1] <= INTRA_FRAME) {
5383 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5384 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5385 return 0;
5386 } else {
5387 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5388 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5389 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5390 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5391 return 0;
5392 }
5393 }
5394 }
5395#if CONFIG_EXT_INTER
5396 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
5397 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
5398 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005399 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5400 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005401 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005402 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
5403 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5404 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
5405 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
5406 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005407
5408 if (this_mode == NEAREST_NEARMV) {
5409 if (c1 > c3) return 0;
5410 } else if (this_mode == NEAREST_NEARESTMV) {
5411 if (c2 > c3) return 0;
5412 } else if (this_mode == NEAR_NEARESTMV) {
5413 if (c4 > c3) return 0;
5414 } else if (this_mode == NEAR_NEARMV) {
5415 if (c5 > c3) return 0;
5416 } else {
5417 assert(this_mode == ZERO_ZEROMV);
5418 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5419 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
5420 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
5421 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
5422 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
5423 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
5424 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
5425 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
5426 return 0;
5427 }
5428 }
5429#endif // CONFIG_EXT_INTER
5430 return 1;
5431}
5432
Urvang Joshi52648442016-10-13 17:27:51 -07005433static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5434 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5435 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436#if CONFIG_EXT_INTER
5437 int_mv *ref_mv_sub8x8[2],
Fergus Simpson4063a682017-02-28 16:52:22 -08005438#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005439 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005440 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005441 const int pw = block_size_wide[bsize];
5442 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005443 MACROBLOCKD *xd = &x->e_mbd;
5444 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005445 // This function should only ever be called for compound modes
5446 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005447 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005448 int_mv ref_mv[2];
5449 int ite, ref;
5450#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005451 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005452 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5453 mbmi->interp_filter[3],
5454 };
5455#else
James Zern7b9407a2016-05-18 23:48:05 -07005456 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005457#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005459 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005460#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005461 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5462 const int ic = block & 1;
5463 const int ir = (block - ic) >> 1;
5464 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5465 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005466#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005467 int is_global[2];
5468 for (ref = 0; ref < 2; ++ref) {
5469 WarpedMotionParams *const wm =
5470 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5471 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5472 }
5473#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005474#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475
5476 // Do joint motion search in compound mode to get more accurate mv.
5477 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5478 int last_besterr[2] = { INT_MAX, INT_MAX };
5479 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005480 av1_get_scaled_ref_frame(cpi, refs[0]),
5481 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005482 };
5483
5484// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005485#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5487 uint8_t *second_pred;
5488#else
5489 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005490#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005491
Jingning Han61418bb2017-01-23 17:12:48 -08005492#if CONFIG_EXT_INTER && CONFIG_CB4X4
5493 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005494#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005495
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005497#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005498 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5499 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5500 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005501#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005502 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5503
5504 if (scaled_ref_frame[ref]) {
5505 int i;
5506 // Swap out the reference frame for a version that's been scaled to
5507 // match the resolution of the current frame, allowing the existing
5508 // motion search code to be used without additional modifications.
5509 for (i = 0; i < MAX_MB_PLANE; i++)
5510 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005511 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5512 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005514 }
5515
5516// Since we have scaled the reference frames to match the size of the current
5517// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005518#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005519 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5520 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005521#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005522 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5523 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005524#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525
5526 // Allow joint search multiple times iteratively for each reference frame
5527 // and break out of the search loop if it couldn't find a better mv.
5528 for (ite = 0; ite < 4; ite++) {
5529 struct buf_2d ref_yv12[2];
5530 int bestsme = INT_MAX;
5531 int sadpb = x->sadperbit16;
5532 MV *const best_mv = &x->best_mv.as_mv;
5533 int search_range = 3;
5534
Alex Converse0fa0f422017-04-24 12:51:14 -07005535 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005536 int id = ite % 2; // Even iterations search in the first reference frame,
5537 // odd iterations search in the second. The predictor
5538 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005539 const int plane = 0;
5540 ConvolveParams conv_params = get_conv_params(0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005541#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5542 WarpTypesAllowed warp_types;
5543#if CONFIG_GLOBAL_MOTION
5544 warp_types.global_warp_allowed = is_global[!id];
5545#endif // CONFIG_GLOBAL_MOTION
5546#if CONFIG_WARPED_MOTION
5547 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5548#endif // CONFIG_WARPED_MOTION
5549#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550
5551 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005552 ref_yv12[0] = xd->plane[plane].pre[0];
5553 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005554
5555#if CONFIG_DUAL_FILTER
5556 // reload the filter types
5557 interp_filter[0] =
5558 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5559 interp_filter[1] =
5560 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005561#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005562
5563// Get the prediction block from the 'other' reference frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005564#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005565 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5566 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005567 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5569 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005570#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5571 &warp_types, p_col, p_row,
5572#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005573 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 } else {
5575 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005576#endif // CONFIG_HIGHBITDEPTH
Angie Chiang9f45bc42017-01-13 16:27:54 -08005577 av1_build_inter_predictor(
5578 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5579 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005580#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5581 &warp_types, p_col, p_row, plane, !id,
5582#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005583 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005584#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005586#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587
5588 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005589 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005590 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005591
5592 // Use the mv result from the single mode as mv predictor.
5593 *best_mv = frame_mv[refs[id]].as_mv;
5594
5595 best_mv->col >>= 3;
5596 best_mv->row >>= 3;
5597
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005598 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599
5600 // Small-range full-pixel motion search.
5601 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005602 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5603 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005604 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005605 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5606 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005607
Alex Converse0fa0f422017-04-24 12:51:14 -07005608 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609
5610 if (bestsme < INT_MAX) {
5611 int dis; /* TODO: use dis in distortion calculation later. */
5612 unsigned int sse;
5613 if (cpi->sf.use_upsampled_references) {
5614 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005615 struct buf_2d backup_pred = pd->pre[0];
5616 const YV12_BUFFER_CONFIG *upsampled_ref =
5617 get_upsampled_ref(cpi, refs[id]);
5618
5619 // Set pred for Y plane
Jingning Han91d9a792017-04-18 12:01:52 -07005620 setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621 upsampled_ref->y_crop_width,
5622 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5623 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5624 pd->subsampling_y);
5625
Jingning Han271bb2c2016-12-14 12:34:46 -08005626// If bsize < BLOCK_8X8, adjust pred pointer for this block
5627#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005628 if (bsize < BLOCK_8X8)
5629 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005630 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5631 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005632 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005633#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005634
5635 bestsme = cpi->find_fractional_mv_step(
5636 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5637 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5638 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5639 &dis, &sse, second_pred, pw, ph, 1);
5640
5641 // Restore the reference frames.
5642 pd->pre[0] = backup_pred;
5643 } else {
5644 (void)block;
5645 bestsme = cpi->find_fractional_mv_step(
5646 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5647 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5648 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5649 &dis, &sse, second_pred, pw, ph, 0);
5650 }
5651 }
5652
5653 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005654 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655
5656 if (bestsme < last_besterr[id]) {
5657 frame_mv[refs[id]].as_mv = *best_mv;
5658 last_besterr[id] = bestsme;
5659 } else {
5660 break;
5661 }
5662 }
5663
5664 *rate_mv = 0;
5665
5666 for (ref = 0; ref < 2; ++ref) {
5667 if (scaled_ref_frame[ref]) {
5668 // Restore the prediction frame pointers to their unscaled versions.
5669 int i;
5670 for (i = 0; i < MAX_MB_PLANE; i++)
5671 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5672 }
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005673 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Jingning Han61418bb2017-01-23 17:12:48 -08005674#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005676#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005677 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5678 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5679 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005680#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005681 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005682 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5683 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5684 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005685#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005686 }
5687}
5688
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005689#if !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005690static void update_mv_search_and_seg_mvs(
5691 int *const run_mv_search, int_mv *const seg_mvs, int has_second_rf,
5692 const MV_REFERENCE_FRAME *const ref_frame,
5693 const SEG_RDSTAT *const ref_rdstat, int_mv *const bsi_ref_mv[2]) {
5694 if (has_second_rf) {
5695 if (seg_mvs[ref_frame[0]].as_int == ref_rdstat->mvs[0].as_int &&
5696 ref_rdstat->mvs[0].as_int != INVALID_MV)
5697 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5698 --*run_mv_search;
5699
5700 if (seg_mvs[ref_frame[1]].as_int == ref_rdstat->mvs[1].as_int &&
5701 ref_rdstat->mvs[1].as_int != INVALID_MV)
5702 if (bsi_ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5703 --*run_mv_search;
5704 } else {
5705 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5706 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5707 *run_mv_search = 0;
5708 seg_mvs[ref_frame[0]].as_int = ref_rdstat->mvs[0].as_int;
5709 }
5710 }
5711}
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005712#endif // !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005713
Yushin Cho482016d2017-01-06 14:06:13 -08005714static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005715 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005716 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5717 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005718 int mvthresh, int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005719#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005720 int_mv compound_seg_newmvs[4][2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005721#endif // CONFIG_EXT_INTER
5722 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5723 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005724 int_mv tmp_ref_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005725 MACROBLOCKD *xd = &x->e_mbd;
5726 MODE_INFO *mi = xd->mi[0];
5727 MB_MODE_INFO *mbmi = &mi->mbmi;
5728 int mode_idx;
5729 int k, br = 0, idx, idy;
5730 int64_t bd = 0, block_sse = 0;
5731 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005732 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005733 struct macroblock_plane *const p = &x->plane[0];
5734 struct macroblockd_plane *const pd = &xd->plane[0];
5735 const int label_count = 4;
5736 int64_t this_segment_rd = 0;
5737 int label_mv_thresh;
5738 int segmentyrate = 0;
5739 const BLOCK_SIZE bsize = mbmi->sb_type;
5740 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5741 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005742#if CONFIG_CB4X4
5743 ENTROPY_CONTEXT t_above[4], t_left[4];
5744#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005745 ENTROPY_CONTEXT t_above[2], t_left[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005746#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005747 int subpelmv = 1, have_ref = 0;
5748 const int has_second_rf = has_second_ref(mbmi);
5749 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5750 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005751#if CONFIG_PVQ
5752 od_rollback_buffer pre_buf;
5753
5754 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005755#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005756#if CONFIG_EXT_TX && CONFIG_RECT_TX
5757 mbmi->tx_size =
5758 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5759#else
5760 mbmi->tx_size = TX_4X4;
5761#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5762
Yaowu Xuf883b422016-08-30 14:01:10 -07005763 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764
5765 bsi->segment_rd = best_rd;
5766 bsi->ref_mv[0] = best_ref_mv;
5767 bsi->ref_mv[1] = second_best_ref_mv;
5768 bsi->mvp.as_int = best_ref_mv->as_int;
5769 bsi->mvthresh = mvthresh;
5770
5771 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5772
Yaowu Xuc27fc142016-08-22 16:08:15 -07005773 for (idx = 0; idx < 4; ++idx) {
5774 for (k = NEARESTMV; k <= NEWMV; ++k) {
5775 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5776 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5777
5778 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5779 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5780 }
5781 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005782
5783 memcpy(t_above, pd->above_context, sizeof(t_above));
5784 memcpy(t_left, pd->left_context, sizeof(t_left));
5785
5786 // 64 makes this threshold really big effectively
5787 // making it so that we very rarely check mvs on
5788 // segments. setting this to 1 would make mv thresh
5789 // roughly equal to what it is for macroblocks
5790 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5791
5792 // Segmentation method overheads
5793 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5794 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5795 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5796 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5797 int_mv mode_mv[MB_MODE_COUNT][2];
5798 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5799 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005800 int64_t new_best_rd = INT64_MAX;
5801 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005802 int ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5804 uint8_t ref_mv_count[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005805#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005806 int_mv ref_mvs_sub8x8[2][2];
5807#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005808#if CONFIG_PVQ
5809 od_rollback_buffer idx_buf, post_buf;
5810 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5811 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005812#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005813
5814 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5815 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5816#if CONFIG_EXT_INTER
5817 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Yaowu Xu531d6af2017-03-07 17:48:52 -08005818 av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
5819 mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005820#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005821#if CONFIG_GLOBAL_MOTION
5822 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -08005823 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005824 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005825 mi_col, mi_row, index)
David Barkercdcac6d2016-12-01 17:04:16 +00005826 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005827#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005828 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005829#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005830 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005831 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005832#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005833 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005834#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005835 &frame_mv[NEARESTMV][frame],
5836 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005837
Yaowu Xuc27fc142016-08-22 16:08:15 -07005838 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5839 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5840 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5841 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005842
5843#if CONFIG_EXT_INTER
5844 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5845 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005846 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5847 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848
5849 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005850#if CONFIG_GLOBAL_MOTION
5851 frame_mv[ZERO_ZEROMV][frame].as_int =
5852 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005853 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005854 mi_col, mi_row, index)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005855 .as_int;
5856#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005857 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005858#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005859 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5860 frame_mv[NEARESTMV][frame].as_int;
5861
5862 if (ref == 0) {
5863 frame_mv[NEAREST_NEARMV][frame].as_int =
5864 frame_mv[NEARESTMV][frame].as_int;
5865 frame_mv[NEAR_NEARESTMV][frame].as_int =
5866 frame_mv[NEARMV][frame].as_int;
5867 frame_mv[NEAREST_NEWMV][frame].as_int =
5868 frame_mv[NEARESTMV][frame].as_int;
5869 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5870 frame_mv[NEAR_NEARMV][frame].as_int =
5871 frame_mv[NEARMV][frame].as_int;
5872 } else if (ref == 1) {
5873 frame_mv[NEAREST_NEARMV][frame].as_int =
5874 frame_mv[NEARMV][frame].as_int;
5875 frame_mv[NEAR_NEARESTMV][frame].as_int =
5876 frame_mv[NEARESTMV][frame].as_int;
5877 frame_mv[NEW_NEARESTMV][frame].as_int =
5878 frame_mv[NEARESTMV][frame].as_int;
5879 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5880 frame_mv[NEAR_NEARMV][frame].as_int =
5881 frame_mv[NEARMV][frame].as_int;
5882 }
5883 }
5884#endif // CONFIG_EXT_INTER
5885 }
5886
5887// search for the best motion vector on this segment
5888#if CONFIG_EXT_INTER
5889 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005890 this_mode <= (has_second_rf ? NEW_NEWMV : NEWMV); ++this_mode)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005891#else
5892 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5893#endif // CONFIG_EXT_INTER
5894 {
5895 const struct buf_2d orig_src = x->plane[0].src;
5896 struct buf_2d orig_pre[2];
5897 // This flag controls if the motion estimation will kick off. When it
5898 // is set to a non-zero value, the encoder will force motion estimation.
5899 int run_mv_search = 0;
5900
5901 mode_idx = INTER_OFFSET(this_mode);
5902#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005903 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005904 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[0][ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005905#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005906 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907 if (!(inter_mode_mask & (1 << this_mode))) continue;
5908
Yaowu Xuc27fc142016-08-22 16:08:15 -07005909 run_mv_search = 2;
5910#if !CONFIG_EXT_INTER
5911 if (filter_idx > 0 && this_mode == NEWMV) {
Urvang Joshif7751be2017-04-27 12:50:39 -07005912 const BEST_SEG_INFO *ref_bsi = bsi_buf;
5913 const SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005914
Urvang Joshif7751be2017-04-27 12:50:39 -07005915 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5916 has_second_rf, mbmi->ref_frame,
5917 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918
5919 if (run_mv_search != 0 && filter_idx > 1) {
5920 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005921 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005922 run_mv_search = 2;
Urvang Joshif7751be2017-04-27 12:50:39 -07005923 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5924 has_second_rf, mbmi->ref_frame,
5925 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926 }
5927 }
Fergus Simpson4063a682017-02-28 16:52:22 -08005928#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005929
Sarah Parkere5299862016-08-16 14:57:37 -07005930#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005931 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005932 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005933 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005934#endif // CONFIG_GLOBAL_MOTION
5935
5936 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005937#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005938 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005939#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005940 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00005941 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07005942 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005943
5944 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005945 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5946 sizeof(bsi->rdstat[index][mode_idx].ta));
5947 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5948 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005949#if CONFIG_PVQ
5950 od_encode_rollback(&x->daala_enc, &idx_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005951#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005952
5953 // motion search for newmv (single predictor case only)
5954 if (!has_second_rf &&
5955#if CONFIG_EXT_INTER
5956 have_newmv_in_inter_mode(this_mode) &&
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005957 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005958#else
5959 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005960 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005961 run_mv_search)
5962#endif // CONFIG_EXT_INTER
5963 ) {
5964 int step_param = 0;
5965 int bestsme = INT_MAX;
5966 int sadpb = x->sadperbit4;
5967 MV mvp_full;
5968 int max_mv;
5969 int cost_list[5];
Alex Converse0fa0f422017-04-24 12:51:14 -07005970 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971
5972 /* Is the best so far sufficiently good that we cant justify doing
5973 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005974 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005975
Yaowu Xuc27fc142016-08-22 16:08:15 -07005976#if CONFIG_EXT_INTER
Thomas Daede6eca8352017-03-17 14:14:12 -07005977 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978#else
5979// use previous block's result as next block's MV predictor.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005980#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005981 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5982 : AOMMAX(abs(bsi->mvp.as_mv.row),
5983 abs(bsi->mvp.as_mv.col)) >>
5984 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005985
5986 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5987 // Take wtd average of the step_params based on the last frame's
5988 // max mv magnitude and the best ref mvs of the current block for
5989 // the given reference.
5990 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005991 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005992 } else {
5993 step_param = cpi->mv_step_param;
5994 }
5995
Yaowu Xuc27fc142016-08-22 16:08:15 -07005996 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5997 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005998
5999 if (cpi->sf.adaptive_motion_search) {
6000 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
6001 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07006002 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003 }
6004
6005 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07006006 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006007
Alex Converse0fa0f422017-04-24 12:51:14 -07006008 av1_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009
6010 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6011
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006012 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07006013 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006014 cpi, x, bsize, &mvp_full, step_param, sadpb,
6015 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6016 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6017
Alex Converse0fa0f422017-04-24 12:51:14 -07006018 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006019
6020 if (bestsme < INT_MAX) {
6021 int distortion;
6022 if (cpi->sf.use_upsampled_references) {
6023 int best_mv_var;
6024 const int try_second =
6025 x->second_best_mv.as_int != INVALID_MV &&
6026 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006027 const int pw = block_size_wide[bsize];
6028 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006029 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006030 struct buf_2d backup_pred = pd->pre[0];
6031 const YV12_BUFFER_CONFIG *upsampled_ref =
6032 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6033
6034 // Set pred for Y plane
6035 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006036 &pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006037 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6038 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6039 pd->subsampling_x, pd->subsampling_y);
6040
6041 // adjust pred pointer for this block
6042 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006043 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006044 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006045 << 3];
6046
6047 best_mv_var = cpi->find_fractional_mv_step(
6048 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6049 x->errorperbit, &cpi->fn_ptr[bsize],
6050 cpi->sf.mv.subpel_force_stop,
6051 cpi->sf.mv.subpel_iters_per_step,
6052 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6053 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
6054 1);
6055
6056 if (try_second) {
6057 int this_var;
6058 MV best_mv = x->best_mv.as_mv;
6059 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Alex Converse0fa0f422017-04-24 12:51:14 -07006060 const int minc =
6061 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6062 const int maxc =
6063 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6064 const int minr =
6065 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6066 const int maxr =
6067 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006068
6069 x->best_mv = x->second_best_mv;
6070 if (x->best_mv.as_mv.row * 8 <= maxr &&
6071 x->best_mv.as_mv.row * 8 >= minr &&
6072 x->best_mv.as_mv.col * 8 <= maxc &&
6073 x->best_mv.as_mv.col * 8 >= minc) {
6074 this_var = cpi->find_fractional_mv_step(
6075 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6076 x->errorperbit, &cpi->fn_ptr[bsize],
6077 cpi->sf.mv.subpel_force_stop,
6078 cpi->sf.mv.subpel_iters_per_step,
6079 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6080 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
6081 NULL, pw, ph, 1);
6082 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6083 x->best_mv.as_mv = best_mv;
6084 }
6085 }
6086
6087 // Restore the reference frames.
6088 pd->pre[0] = backup_pred;
6089 } else {
6090 cpi->find_fractional_mv_step(
6091 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6092 x->errorperbit, &cpi->fn_ptr[bsize],
6093 cpi->sf.mv.subpel_force_stop,
6094 cpi->sf.mv.subpel_iters_per_step,
6095 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6096 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
6097 }
6098
6099// save motion search result for use in compound prediction
6100#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006101 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006102#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006103 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006104#endif // CONFIG_EXT_INTER
6105 }
6106
6107 if (cpi->sf.adaptive_motion_search)
6108 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6109
6110#if CONFIG_EXT_INTER
6111 mode_mv[this_mode][0] = x->best_mv;
6112#else
6113 mode_mv[NEWMV][0] = x->best_mv;
6114#endif // CONFIG_EXT_INTER
6115
6116 // restore src pointers
6117 mi_buf_restore(x, orig_src, orig_pre);
6118 }
6119
6120 if (has_second_rf) {
6121#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006122 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6123 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006124#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006125 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6126 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006127#endif // CONFIG_EXT_INTER
6128 continue;
6129 }
6130
6131#if CONFIG_DUAL_FILTER
6132 (void)run_mv_search;
Fergus Simpson4063a682017-02-28 16:52:22 -08006133#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006134
6135 if (has_second_rf &&
6136#if CONFIG_EXT_INTER
6137 this_mode == NEW_NEWMV &&
6138#else
6139 this_mode == NEWMV &&
6140#endif // CONFIG_EXT_INTER
6141#if CONFIG_DUAL_FILTER
6142 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6143#else
6144 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
Fergus Simpson4063a682017-02-28 16:52:22 -08006145#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006146 {
6147 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006148 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006149 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6150 int rate_mv;
Zoe Liu122f3942017-04-25 11:18:38 -07006151 frame_mv[this_mode][mbmi->ref_frame[0]].as_int =
6152 seg_mvs[index][mbmi->ref_frame[0]].as_int;
6153 frame_mv[this_mode][mbmi->ref_frame[1]].as_int =
6154 seg_mvs[index][mbmi->ref_frame[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006155 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6156 mi_col,
6157#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006158 bsi->ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159#endif // CONFIG_EXT_INTER
Zoe Liu122f3942017-04-25 11:18:38 -07006160 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006161#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006162 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006163 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006164 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6166#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006167 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006169 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006170 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6171#endif // CONFIG_EXT_INTER
6172 }
6173 // restore src pointers
6174 mi_buf_restore(x, orig_src, orig_pre);
6175 }
6176
Urvang Joshi454280d2016-10-14 16:51:44 -07006177 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6178 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Urvang Joshi454280d2016-10-14 16:51:44 -07006179 seg_mvs[index],
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006180#if CONFIG_EXT_INTER
6181 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006182#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006183 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006184
6185 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006186 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006187 mode_mv[this_mode][ref].as_int;
6188 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006189 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190 mode_mv[this_mode][ref].as_int;
6191 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006192 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193 mode_mv[this_mode][ref].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006194 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6195 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006197 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6198 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006199 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006200 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6201 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006203 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006204 bsi->ref_mv[ref]->as_int;
6205 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006206 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006207 bsi->ref_mv[ref]->as_int;
6208 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006209 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006210 bsi->ref_mv[ref]->as_int;
6211#endif // CONFIG_EXT_INTER
6212 }
6213
6214 // Trap vectors that reach beyond the UMV borders
Alex Converse0fa0f422017-04-24 12:51:14 -07006215 if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) ||
6216 (has_second_rf &&
6217 mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv)))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006218 continue;
6219
6220 if (filter_idx > 0) {
6221 BEST_SEG_INFO *ref_bsi = bsi_buf;
6222 subpelmv = 0;
6223 have_ref = 1;
6224
6225 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6226 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6227#if CONFIG_EXT_INTER
6228 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006229 have_ref &=
6230 ((mode_mv[this_mode][ref].as_int ==
6231 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6232 (bsi->ref_mv[ref]->as_int ==
6233 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006234 else
6235#endif // CONFIG_EXT_INTER
6236 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006237 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006238 }
6239
Urvang Joshi454280d2016-10-14 16:51:44 -07006240 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006241
6242 if (filter_idx > 1 && !subpelmv && !have_ref) {
6243 ref_bsi = bsi_buf + 1;
6244 have_ref = 1;
6245 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6246#if CONFIG_EXT_INTER
6247 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006248 have_ref &=
6249 ((mode_mv[this_mode][ref].as_int ==
6250 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6251 (bsi->ref_mv[ref]->as_int ==
6252 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006253 else
6254#endif // CONFIG_EXT_INTER
6255 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006256 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006257
Urvang Joshi454280d2016-10-14 16:51:44 -07006258 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006259 }
6260
6261 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006262 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006263 bsi->rdstat[index][mode_idx].byrate =
6264 ref_bsi->rdstat[index][mode_idx].byrate;
6265 bsi->rdstat[index][mode_idx].bdist =
6266 ref_bsi->rdstat[index][mode_idx].bdist;
6267 bsi->rdstat[index][mode_idx].bsse =
6268 ref_bsi->rdstat[index][mode_idx].bsse;
6269 bsi->rdstat[index][mode_idx].brate +=
6270 ref_bsi->rdstat[index][mode_idx].byrate;
6271 bsi->rdstat[index][mode_idx].eobs =
6272 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273
Urvang Joshi454280d2016-10-14 16:51:44 -07006274 bsi->rdstat[index][mode_idx].brdcost =
6275 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6276 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006277
Urvang Joshi454280d2016-10-14 16:51:44 -07006278 memcpy(bsi->rdstat[index][mode_idx].ta,
6279 ref_bsi->rdstat[index][mode_idx].ta,
6280 sizeof(bsi->rdstat[index][mode_idx].ta));
6281 memcpy(bsi->rdstat[index][mode_idx].tl,
6282 ref_bsi->rdstat[index][mode_idx].tl,
6283 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006284 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006285 bsi->rdstat[index + 1][mode_idx].eobs =
6286 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006287 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006288 bsi->rdstat[index + 2][mode_idx].eobs =
6289 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006290
Urvang Joshi454280d2016-10-14 16:51:44 -07006291 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006292 // If the NEWMV mode is using the same motion vector as the
6293 // NEARESTMV mode, skip the rest rate-distortion calculations
6294 // and use the inferred motion vector modes.
6295 if (this_mode == NEWMV) {
6296 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006297 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006299 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006300 bsi->ref_mv[1]->as_int)
6301 continue;
6302 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006303 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006304 bsi->ref_mv[0]->as_int)
6305 continue;
6306 }
6307 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006308 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006309 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006310#if CONFIG_PVQ
6311 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006312#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313 }
6314 continue;
6315 }
6316 }
6317
Yushin Choab44fd12017-01-09 16:06:53 -08006318 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006319 cpi, x, bsi->segment_rd - this_segment_rd, index,
6320 &bsi->rdstat[index][mode_idx].byrate,
6321 &bsi->rdstat[index][mode_idx].bdist,
6322 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6323 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324
Urvang Joshi454280d2016-10-14 16:51:44 -07006325 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6326 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6327 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6328 bsi->rdstat[index][mode_idx].brate +=
6329 bsi->rdstat[index][mode_idx].byrate;
6330 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006331 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006332 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006333 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006334 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006335 }
6336
Urvang Joshi454280d2016-10-14 16:51:44 -07006337 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006338 // If the NEWMV mode is using the same motion vector as the
6339 // NEARESTMV mode, skip the rest rate-distortion calculations
6340 // and use the inferred motion vector modes.
6341 if (this_mode == NEWMV) {
6342 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006343 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006344 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006345 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006346 bsi->ref_mv[1]->as_int)
6347 continue;
6348 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006349 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006350 bsi->ref_mv[0]->as_int)
6351 continue;
6352 }
6353 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006355 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006356
6357#if CONFIG_PVQ
6358 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006359#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006360 }
6361 } /*for each 4x4 mode*/
6362
Urvang Joshi454280d2016-10-14 16:51:44 -07006363 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006365 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006366#if CONFIG_EXT_INTER
6367 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6368#else
6369 for (midx = 0; midx < INTER_MODES; ++midx)
6370#endif // CONFIG_EXT_INTER
6371 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6372 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006373#if CONFIG_PVQ
6374 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006375#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006376 return INT64_MAX;
6377 }
6378
6379 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006380 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6381 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006382#if CONFIG_PVQ
6383 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006384#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006385
6386#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006387 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006388 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006389 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006391 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
6392 mode_mv[mode_selected], frame_mv, seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006393#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006394 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006395#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006396 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row,
6397 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006398
Urvang Joshi454280d2016-10-14 16:51:44 -07006399 br += bsi->rdstat[index][mode_idx].brate;
6400 bd += bsi->rdstat[index][mode_idx].bdist;
6401 block_sse += bsi->rdstat[index][mode_idx].bsse;
6402 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6403 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006404
6405 if (this_segment_rd > bsi->segment_rd) {
6406 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006407 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006408#if CONFIG_EXT_INTER
6409 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6410#else
6411 for (midx = 0; midx < INTER_MODES; ++midx)
6412#endif // CONFIG_EXT_INTER
6413 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6414 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006415#if CONFIG_PVQ
6416 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006417#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006418 return INT64_MAX;
6419 }
6420 }
6421 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006422#if CONFIG_PVQ
6423 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006424#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006425
6426 bsi->r = br;
6427 bsi->d = bd;
6428 bsi->segment_yrate = segmentyrate;
6429 bsi->segment_rd = this_segment_rd;
6430 bsi->sse = block_sse;
6431
6432 // update the coding decisions
6433 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6434
Yushin Cho7a428ba2017-01-12 16:28:49 -08006435#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07006436 // Compute prediction (i.e. skip) and decoded distortion by daala-distortion.
Yushin Cho7a428ba2017-01-12 16:28:49 -08006437 {
6438 const int src_stride = p->src.stride;
6439 const int dst_stride = pd->dst.stride;
6440 uint8_t *src = p->src.buf;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006441 uint8_t *dst = pd->dst.buf;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006442 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006443 const int use_activity_masking = 0;
6444 const int qm = OD_HVS_QM;
6445 const int bsw = block_size_wide[plane_bsize];
6446 const int bsh = block_size_high[plane_bsize];
6447 int64_t rd1, rd2;
6448 int64_t daala_sse, daala_dist;
6449 TX_SIZE tx_size = mbmi->tx_size;
6450
6451#if CONFIG_HIGHBITDEPTH
6452 uint8_t *recon_8x8;
6453 DECLARE_ALIGNED(16, uint16_t, recon16[8 * 8]);
6454
6455 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6456 recon_8x8 = CONVERT_TO_BYTEPTR(recon16);
6457 else
6458 recon_8x8 = (uint8_t *)recon16;
6459#else
6460 DECLARE_ALIGNED(16, uint8_t, recon_8x8[8 * 8]);
6461#endif // CONFIG_HIGHBITDEPTH
6462
Yushin Cho7a428ba2017-01-12 16:28:49 -08006463#if CONFIG_PVQ
6464 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08006465#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006466
Yushin Cho4483e3d2017-04-18 19:41:20 -07006467 // For each of sub8x8 prediction block in a 8x8 block
6468 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08006469 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6470 int i = idy * 2 + idx;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006471 const uint8_t *const src_sub8x8 =
6472 src + av1_raster_block_offset(BLOCK_8X8, i, p->src.stride);
6473 uint8_t *const dst_sub8x8 =
6474 dst + av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride);
6475 uint8_t *recon_sub8x8 = recon_8x8 + (idy * 8 + idx) * 4;
6476 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6477 const int txb_height = max_block_high(xd, plane_bsize, 0);
6478 int idx_, idy_;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006479
Jingning Hanc44009c2017-05-06 11:36:49 -07006480 av1_build_inter_predictor_sub8x8(cm, xd, 0, i, idy, idx, mi_row,
6481 mi_col);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006482#if CONFIG_HIGHBITDEPTH
6483 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6484 aom_highbd_subtract_block(
6485 height, width,
6486 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6487 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride, xd->bd);
6488 } else {
6489 aom_subtract_block(
6490 height, width,
6491 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6492 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6493 }
6494#else
6495 aom_subtract_block(
6496 bsh, bsw, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
6497 8, src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6498#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006499
Yushin Cho4483e3d2017-04-18 19:41:20 -07006500#if CONFIG_HIGHBITDEPTH
6501 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6502 aom_highbd_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8,
6503 NULL, 0, NULL, 0, bsw, bsh, xd->bd);
6504 } else {
6505#endif // CONFIG_HIGHBITDEPTH
6506 aom_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8, NULL, 0,
6507 NULL, 0, bsw, bsh);
6508#if CONFIG_HIGHBITDEPTH
6509 }
6510#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006511
Yushin Cho4483e3d2017-04-18 19:41:20 -07006512 // To get decoded pixels, do 4x4 xform and quant for each 4x4 block
6513 // in a sub8x8 prediction block. In case remaining parts of
6514 // sub8x8 inter mode rdo assume pd->dst stores predicted pixels,
6515 // use local buffer to store decoded pixels.
6516 for (idy_ = 0; idy_ < txb_height; idy_++) {
6517 for (idx_ = 0; idx_ < txb_width; idx_++) {
6518 int coeff_ctx = 0;
6519 const tran_low_t *dqcoeff;
6520 uint16_t eob;
6521 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6522 uint8_t *recon_4x4 = recon_sub8x8 + (idy_ * 8 + idx_) * 4;
6523 const int block_raster_idx = (idy + idy_) * 2 + (idx + idx_);
6524 const int block =
6525 av1_raster_order_to_block_index(tx_size, block_raster_idx);
6526 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006527
Yushin Cho4483e3d2017-04-18 19:41:20 -07006528 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6529 av1_xform_quant(cm, x, 0, block, idy + idy_, idx + idx_, BLOCK_8X8,
6530 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07006531 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006532
Yushin Cho4483e3d2017-04-18 19:41:20 -07006533 eob = p->eobs[block];
6534 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size,
6535 recon_4x4, 8, eob);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006536 }
6537 }
6538 }
Yushin Cho4483e3d2017-04-18 19:41:20 -07006539 }
6540 // Compute daala-distortion for a 8x8 block
6541 daala_sse = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, 8, 8,
6542 qm, use_activity_masking, x->qindex)
6543 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006544
Yushin Cho4483e3d2017-04-18 19:41:20 -07006545 daala_dist = av1_daala_dist(src, src_stride, recon_8x8, 8, 8, 8, qm,
6546 use_activity_masking, x->qindex)
6547 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006548
Yushin Cho4483e3d2017-04-18 19:41:20 -07006549 bsi->sse = daala_sse;
6550 bsi->d = daala_dist;
6551
6552 rd1 = RDCOST(x->rdmult, x->rddiv, bsi->r, bsi->d);
6553 rd2 = RDCOST(x->rdmult, x->rddiv, 0, bsi->sse);
6554 bsi->segment_rd = AOMMIN(rd1, rd2);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006555 }
6556#endif // CONFIG_DAALA_DIST
6557
Yaowu Xuc27fc142016-08-22 16:08:15 -07006558 if (bsi->segment_rd > best_rd) return INT64_MAX;
6559 /* set it to the best */
6560 for (idx = 0; idx < 4; idx++) {
6561 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6562 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6563 if (has_second_ref(mbmi))
6564 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006565 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006566 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006567 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006568#if CONFIG_EXT_INTER
6569 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6570 if (has_second_rf)
6571 mi->bmi[idx].ref_mv[1].as_int =
6572 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6573#endif // CONFIG_EXT_INTER
6574 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6575 mi->bmi[idx].as_mode = bsi->modes[idx];
6576 }
6577
6578 /*
6579 * used to set mbmi->mv.as_int
6580 */
6581 *returntotrate = bsi->r;
6582 *returndistortion = bsi->d;
6583 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006584 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006585 *psse = bsi->sse;
6586 mbmi->mode = bsi->modes[3];
6587
6588 return bsi->segment_rd;
6589}
6590
Yaowu Xuf883b422016-08-30 14:01:10 -07006591static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006592 const MACROBLOCKD *xd, int segment_id,
6593 unsigned int *ref_costs_single,
6594 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006595 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006596 int seg_ref_active =
6597 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6598 if (seg_ref_active) {
6599 memset(ref_costs_single, 0,
6600 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6601 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6602 *comp_mode_p = 128;
6603 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006604 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6605 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006606
6607 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006608 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006609 *comp_mode_p = comp_inter_p;
6610 } else {
6611 *comp_mode_p = 128;
6612 }
6613
Yaowu Xuf883b422016-08-30 14:01:10 -07006614 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006615
6616 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006617 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6618 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006619#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006620 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6621 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6622 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006623#endif // CONFIG_EXT_REFS
6624
Yaowu Xuf883b422016-08-30 14:01:10 -07006625 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006626
6627 ref_costs_single[LAST_FRAME] =
6628#if CONFIG_EXT_REFS
6629 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6630 ref_costs_single[BWDREF_FRAME] =
6631#endif // CONFIG_EXT_REFS
6632 ref_costs_single[GOLDEN_FRAME] =
6633 ref_costs_single[ALTREF_FRAME] = base_cost;
6634
6635#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006636 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6637 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6638 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6639 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6640 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6641 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006642
Yaowu Xuf883b422016-08-30 14:01:10 -07006643 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6644 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6645 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6646 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006647
Yaowu Xuf883b422016-08-30 14:01:10 -07006648 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6649 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650
Yaowu Xuf883b422016-08-30 14:01:10 -07006651 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6652 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006653
Yaowu Xuf883b422016-08-30 14:01:10 -07006654 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6655 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006656#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006657 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6658 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6659 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006660
Yaowu Xuf883b422016-08-30 14:01:10 -07006661 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6662 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006663#endif // CONFIG_EXT_REFS
6664 } else {
6665 ref_costs_single[LAST_FRAME] = 512;
6666#if CONFIG_EXT_REFS
6667 ref_costs_single[LAST2_FRAME] = 512;
6668 ref_costs_single[LAST3_FRAME] = 512;
6669 ref_costs_single[BWDREF_FRAME] = 512;
6670#endif // CONFIG_EXT_REFS
6671 ref_costs_single[GOLDEN_FRAME] = 512;
6672 ref_costs_single[ALTREF_FRAME] = 512;
6673 }
6674
6675 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006676 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006677#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006678 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6679 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6680 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006681#endif // CONFIG_EXT_REFS
6682
Yaowu Xuf883b422016-08-30 14:01:10 -07006683 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684
6685 ref_costs_comp[LAST_FRAME] =
6686#if CONFIG_EXT_REFS
6687 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6688#endif // CONFIG_EXT_REFS
6689 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6690
6691#if CONFIG_EXT_REFS
6692 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6693#endif // CONFIG_EXT_REFS
6694
6695#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006696 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6697 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6698 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6699 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006700
Yaowu Xuf883b422016-08-30 14:01:10 -07006701 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6702 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006703
Yaowu Xuf883b422016-08-30 14:01:10 -07006704 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6705 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006706
6707 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6708 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006709 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6710 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006711#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006712 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6713 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006714#endif // CONFIG_EXT_REFS
6715 } else {
6716 ref_costs_comp[LAST_FRAME] = 512;
6717#if CONFIG_EXT_REFS
6718 ref_costs_comp[LAST2_FRAME] = 512;
6719 ref_costs_comp[LAST3_FRAME] = 512;
6720 ref_costs_comp[BWDREF_FRAME] = 512;
6721 ref_costs_comp[ALTREF_FRAME] = 512;
6722#endif // CONFIG_EXT_REFS
6723 ref_costs_comp[GOLDEN_FRAME] = 512;
6724 }
6725 }
6726}
6727
6728static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6729 int mode_index,
6730 int64_t comp_pred_diff[REFERENCE_MODES],
6731 int skippable) {
6732 MACROBLOCKD *const xd = &x->e_mbd;
6733
6734 // Take a snapshot of the coding context so it can be
6735 // restored if we decide to encode this way
6736 ctx->skip = x->skip;
6737 ctx->skippable = skippable;
6738 ctx->best_mode_index = mode_index;
6739 ctx->mic = *xd->mi[0];
6740 ctx->mbmi_ext = *x->mbmi_ext;
6741 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6742 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6743 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6744}
6745
clang-format55ce9e02017-02-15 22:27:12 -08006746static void setup_buffer_inter(
6747 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6748 BLOCK_SIZE block_size, int mi_row, int mi_col,
6749 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6750 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6751 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006752 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6754 MACROBLOCKD *const xd = &x->e_mbd;
6755 MODE_INFO *const mi = xd->mi[0];
6756 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6757 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6758 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6759
6760 assert(yv12 != NULL);
6761
6762 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6763 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006764 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006765
6766 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006767 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
6768 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006769#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006770 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006771#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006772 candidates, mi_row, mi_col, NULL, NULL,
6773 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006774
6775 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006776 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6777 &frame_nearest_mv[ref_frame],
6778 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006779
Jingning Han271bb2c2016-12-14 12:34:46 -08006780// Further refinement that is encode side only to test the top few candidates
6781// in full and choose the best as the centre point for subsequent searches.
6782// The current implementation doesn't support scaling.
6783#if CONFIG_CB4X4
6784 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6785 block_size);
6786#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006787 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6788 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6789 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006790#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006791}
6792
Urvang Joshi52648442016-10-13 17:27:51 -07006793static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6794 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006795#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006796 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006797#endif // CONFIG_EXT_INTER
6798 int *rate_mv) {
6799 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006800 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006801 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6802 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6803 int bestsme = INT_MAX;
6804 int step_param;
6805 int sadpb = x->sadperbit16;
6806 MV mvp_full;
6807#if CONFIG_EXT_INTER
6808 int ref = mbmi->ref_frame[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006809#else
6810 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006811 int ref_idx = 0;
6812#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006813 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006814
Alex Converse0fa0f422017-04-24 12:51:14 -07006815 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006816 int cost_list[5];
6817
6818 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006819 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006820
6821 MV pred_mv[3];
6822 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6823 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6824 pred_mv[2] = x->pred_mv[ref];
6825
Yaowu Xuc27fc142016-08-22 16:08:15 -07006826 if (scaled_ref_frame) {
6827 int i;
6828 // Swap out the reference frame for a version that's been scaled to
6829 // match the resolution of the current frame, allowing the existing
6830 // motion search code to be used without additional modifications.
6831 for (i = 0; i < MAX_MB_PLANE; i++)
6832 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6833
Yaowu Xuf883b422016-08-30 14:01:10 -07006834 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006835 }
6836
Alex Converse0fa0f422017-04-24 12:51:14 -07006837 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006838
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006839 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006840
Yaowu Xuc27fc142016-08-22 16:08:15 -07006841 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006842 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006843 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6844 // Take wtd average of the step_params based on the last frame's
6845 // max mv magnitude and that based on the best ref mvs of the current
6846 // block for the given reference.
6847 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006848 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006849 2;
6850 } else {
6851 step_param = cpi->mv_step_param;
6852 }
6853
6854 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6855 int boffset =
6856 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006857 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6858 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006859 }
6860
6861 if (cpi->sf.adaptive_motion_search) {
6862 int bwl = b_width_log2_lookup[bsize];
6863 int bhl = b_height_log2_lookup[bsize];
6864 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6865
6866 if (tlevel < 5) step_param += 2;
6867
6868 // prev_mv_sad is not setup for dynamically scaled frames.
6869 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6870 int i;
6871 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6872 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6873 x->pred_mv[ref].row = 0;
6874 x->pred_mv[ref].col = 0;
6875 x->best_mv.as_int = INVALID_MV;
6876
6877 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006878 int j;
6879 for (j = 0; j < MAX_MB_PLANE; ++j)
6880 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006881 }
6882 return;
6883 }
6884 }
6885 }
6886 }
6887
Alex Converse0fa0f422017-04-24 12:51:14 -07006888 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006889
Yue Chene9638cc2016-10-10 12:37:54 -07006890#if CONFIG_MOTION_VAR
6891 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6892 mvp_full = mbmi->mv[0].as_mv;
6893 else
6894#endif // CONFIG_MOTION_VAR
6895 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006896
6897 mvp_full.col >>= 3;
6898 mvp_full.row >>= 3;
6899
6900 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6901
Yue Chene9638cc2016-10-10 12:37:54 -07006902#if CONFIG_MOTION_VAR
6903 switch (mbmi->motion_mode) {
6904 case SIMPLE_TRANSLATION:
6905#endif // CONFIG_MOTION_VAR
6906 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6907 sadpb, cond_cost_list(cpi, cost_list),
6908 &ref_mv, INT_MAX, 1);
6909#if CONFIG_MOTION_VAR
6910 break;
6911 case OBMC_CAUSAL:
6912 bestsme = av1_obmc_full_pixel_diamond(
6913 cpi, x, &mvp_full, step_param, sadpb,
6914 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6915 &(x->best_mv.as_mv), 0);
6916 break;
6917 default: assert("Invalid motion mode!\n");
6918 }
6919#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006920
Alex Converse0fa0f422017-04-24 12:51:14 -07006921 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006922
6923 if (bestsme < INT_MAX) {
6924 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006925#if CONFIG_MOTION_VAR
6926 switch (mbmi->motion_mode) {
6927 case SIMPLE_TRANSLATION:
6928#endif // CONFIG_MOTION_VAR
6929 if (cpi->sf.use_upsampled_references) {
6930 int best_mv_var;
6931 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6932 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006933 const int pw = block_size_wide[bsize];
6934 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07006935 // Use up-sampled reference frames.
6936 struct macroblockd_plane *const pd = &xd->plane[0];
6937 struct buf_2d backup_pred = pd->pre[ref_idx];
6938 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006939
Yue Chene9638cc2016-10-10 12:37:54 -07006940 // Set pred for Y plane
6941 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006942 &pd->pre[ref_idx], bsize, upsampled_ref->y_buffer,
Yue Chene9638cc2016-10-10 12:37:54 -07006943 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6944 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6945 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006946
Yue Chene9638cc2016-10-10 12:37:54 -07006947 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006948 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6949 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6950 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6951 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6952 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006953
Yue Chene9638cc2016-10-10 12:37:54 -07006954 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07006955 const int minc =
6956 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6957 const int maxc =
6958 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6959 const int minr =
6960 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6961 const int maxr =
6962 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07006963 int this_var;
6964 MV best_mv = x->best_mv.as_mv;
6965
6966 x->best_mv = x->second_best_mv;
6967 if (x->best_mv.as_mv.row * 8 <= maxr &&
6968 x->best_mv.as_mv.row * 8 >= minr &&
6969 x->best_mv.as_mv.col * 8 <= maxc &&
6970 x->best_mv.as_mv.col * 8 >= minc) {
6971 this_var = cpi->find_fractional_mv_step(
6972 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6973 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6974 cpi->sf.mv.subpel_iters_per_step,
6975 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6976 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6977 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6978 x->best_mv.as_mv = best_mv;
6979 }
6980 }
6981
6982 // Restore the reference frames.
6983 pd->pre[ref_idx] = backup_pred;
6984 } else {
6985 cpi->find_fractional_mv_step(
6986 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6987 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6988 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6989 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6990 0);
6991 }
6992#if CONFIG_MOTION_VAR
6993 break;
6994 case OBMC_CAUSAL:
6995 av1_find_best_obmc_sub_pixel_tree_up(
6996 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6997 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6998 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6999 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
7000 cpi->sf.use_upsampled_references);
7001 break;
7002 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07007003 }
Yue Chene9638cc2016-10-10 12:37:54 -07007004#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007005 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007006 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
7007 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007008
Yue Chene9638cc2016-10-10 12:37:54 -07007009#if CONFIG_MOTION_VAR
7010 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
7011#else
7012 if (cpi->sf.adaptive_motion_search)
7013#endif // CONFIG_MOTION_VAR
7014 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007015
7016 if (scaled_ref_frame) {
7017 int i;
7018 for (i = 0; i < MAX_MB_PLANE; i++)
7019 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7020 }
7021}
7022
David Barkerac37fa32016-12-02 12:30:21 +00007023static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007024 int i;
7025 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007026 xd->plane[i].dst.buf = dst.plane[i];
7027 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007028 }
7029}
7030
Yaowu Xuc27fc142016-08-22 16:08:15 -07007031#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007032#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Urvang Joshi52648442016-10-13 17:27:51 -07007033static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007034 const uint8_t *mask, int mask_stride,
7035 BLOCK_SIZE bsize, int mi_row, int mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007036 int_mv *tmp_mv, int *rate_mv, int ref_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007037 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007038 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007039 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7040 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7041 int bestsme = INT_MAX;
7042 int step_param;
7043 int sadpb = x->sadperbit16;
7044 MV mvp_full;
7045 int ref = mbmi->ref_frame[ref_idx];
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007046 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007047
Alex Converse0fa0f422017-04-24 12:51:14 -07007048 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007049
7050 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007051 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007052 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007053
7054 MV pred_mv[3];
7055 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7056 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7057 pred_mv[2] = x->pred_mv[ref];
7058
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007059 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007060
7061 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007062 // Swap out the reference frame for a version that's been scaled to
7063 // match the resolution of the current frame, allowing the existing
7064 // motion search code to be used without additional modifications.
7065 for (i = 0; i < MAX_MB_PLANE; i++)
7066 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7067
Yaowu Xuf883b422016-08-30 14:01:10 -07007068 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007069 }
7070
Alex Converse0fa0f422017-04-24 12:51:14 -07007071 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007072
7073 // Work out the size of the first step in the mv step search.
7074 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7075 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7076 // Take wtd average of the step_params based on the last frame's
7077 // max mv magnitude and that based on the best ref mvs of the current
7078 // block for the given reference.
7079 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007080 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007081 2;
7082 } else {
7083 step_param = cpi->mv_step_param;
7084 }
7085
7086 // TODO(debargha): is show_frame needed here?
7087 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7088 int boffset =
7089 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007090 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7091 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007092 }
7093
7094 if (cpi->sf.adaptive_motion_search) {
7095 int bwl = b_width_log2_lookup[bsize];
7096 int bhl = b_height_log2_lookup[bsize];
7097 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7098
7099 if (tlevel < 5) step_param += 2;
7100
7101 // prev_mv_sad is not setup for dynamically scaled frames.
7102 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007103 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7104 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7105 x->pred_mv[ref].row = 0;
7106 x->pred_mv[ref].col = 0;
7107 tmp_mv->as_int = INVALID_MV;
7108
7109 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007110 int j;
7111 for (j = 0; j < MAX_MB_PLANE; ++j)
7112 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007113 }
7114 return;
7115 }
7116 }
7117 }
7118 }
7119
7120 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7121
7122 mvp_full.col >>= 3;
7123 mvp_full.row >>= 3;
7124
Yaowu Xuf883b422016-08-30 14:01:10 -07007125 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007126 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7127 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7128 &tmp_mv->as_mv, ref_idx);
7129
Alex Converse0fa0f422017-04-24 12:51:14 -07007130 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007131
7132 if (bestsme < INT_MAX) {
7133 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007134 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007135 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7136 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7137 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7138 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7139 cpi->sf.use_upsampled_references);
7140 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007141 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7142 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007143
7144 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7145 x->pred_mv[ref] = tmp_mv->as_mv;
7146
7147 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007148 for (i = 0; i < MAX_MB_PLANE; i++)
7149 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7150 }
7151}
7152
Sarah Parker6fdc8532016-11-16 17:47:13 -08007153static void do_masked_motion_search_indexed(
7154 const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007155 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007156 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007157 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7158 MACROBLOCKD *xd = &x->e_mbd;
7159 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7160 BLOCK_SIZE sb_type = mbmi->sb_type;
7161 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007162 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007163
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007164 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007165
7166 if (which == 0 || which == 2)
7167 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007168 &tmp_mv[0], &rate_mv[0], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007169
7170 if (which == 1 || which == 2) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007171// get the negative mask
7172#if CONFIG_COMPOUND_SEGMENT
7173 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7174 const int h = block_size_high[bsize];
7175 mask = av1_get_compound_type_mask_inverse(
7176 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7177#else
7178 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
Fergus Simpson4063a682017-02-28 16:52:22 -08007179#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007180 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007181 &tmp_mv[1], &rate_mv[1], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007182 }
7183}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007184#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007185#endif // CONFIG_EXT_INTER
7186
7187// In some situations we want to discount tha pparent cost of a new motion
7188// vector. Where there is a subtle motion field and especially where there is
7189// low spatial complexity then it can be hard to cover the cost of a new motion
7190// vector in a single block, even if that motion vector reduces distortion.
7191// However, once established that vector may be usable through the nearest and
7192// near mv modes to reduce distortion in subsequent blocks and also improve
7193// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007194static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007195 int_mv this_mv,
7196 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7197 int ref_frame) {
7198 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7199 (this_mv.as_int != 0) &&
7200 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7201 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7202 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7203 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7204}
7205
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007206#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7207#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007208
7209// TODO(jingning): this mv clamping function should be block size dependent.
7210static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7211 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7212 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7213 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7214 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7215}
7216
7217#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007218#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007219static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007220 const BLOCK_SIZE bsize, const uint8_t *pred0,
7221 int stride0, const uint8_t *pred1, int stride1) {
7222 const struct macroblock_plane *const p = &x->plane[0];
7223 const uint8_t *src = p->src.buf;
7224 int src_stride = p->src.stride;
7225 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007226 const int bw = block_size_wide[bsize];
7227 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007228 uint32_t esq[2][4], var;
7229 int64_t tl, br;
7230
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007231#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007232 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7233 pred0 = CONVERT_TO_BYTEPTR(pred0);
7234 pred1 = CONVERT_TO_BYTEPTR(pred1);
7235 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007236#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007237
7238 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7239 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7240 stride0, &esq[0][1]);
7241 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7242 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7243 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7244 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7245 &esq[0][3]);
7246 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7247 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7248 stride1, &esq[1][1]);
7249 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7250 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7251 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7252 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7253 &esq[1][3]);
7254 (void)var;
7255
7256 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7257 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7258 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7259 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7260 return (tl + br > 0);
7261}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007262#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007263#endif // CONFIG_EXT_INTER
7264
7265#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007266static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007267 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007268 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007269 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7270 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007271 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007272 const MACROBLOCKD *xd = &x->e_mbd;
7273 int bsl = mi_width_log2_lookup[bsize];
7274 int pred_filter_search =
7275 cpi->sf.cb_pred_filter_search
7276 ? (((mi_row + mi_col) >> bsl) +
7277 get_chessboard_index(cm->current_video_frame)) &
7278 0x1
7279 : 0;
7280 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7281 const int is_comp_pred = has_second_ref(mbmi);
7282 const int this_mode = mbmi->mode;
7283 int refs[2] = { mbmi->ref_frame[0],
7284 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007285 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007286 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007287 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7288 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7289
7290#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007291 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007292#else
7293 if ((this_mode != NEWMV) || (af == lf))
7294#endif // CONFIG_EXT_INTER
7295 best_filter = af;
7296 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007297 if (is_comp_pred) {
7298 if (cpi->sf.adaptive_mode_search) {
7299#if CONFIG_EXT_INTER
7300 switch (this_mode) {
7301 case NEAREST_NEARESTMV:
7302 if (single_filter[NEARESTMV][refs[0]] ==
7303 single_filter[NEARESTMV][refs[1]])
7304 best_filter = single_filter[NEARESTMV][refs[0]];
7305 break;
7306 case NEAREST_NEARMV:
7307 if (single_filter[NEARESTMV][refs[0]] ==
7308 single_filter[NEARMV][refs[1]])
7309 best_filter = single_filter[NEARESTMV][refs[0]];
7310 break;
7311 case NEAR_NEARESTMV:
7312 if (single_filter[NEARMV][refs[0]] ==
7313 single_filter[NEARESTMV][refs[1]])
7314 best_filter = single_filter[NEARMV][refs[0]];
7315 break;
7316 case NEAR_NEARMV:
7317 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7318 best_filter = single_filter[NEARMV][refs[0]];
7319 break;
7320 case ZERO_ZEROMV:
7321 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7322 best_filter = single_filter[ZEROMV][refs[0]];
7323 break;
7324 case NEW_NEWMV:
7325 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7326 best_filter = single_filter[NEWMV][refs[0]];
7327 break;
7328 case NEAREST_NEWMV:
7329 if (single_filter[NEARESTMV][refs[0]] ==
7330 single_filter[NEWMV][refs[1]])
7331 best_filter = single_filter[NEARESTMV][refs[0]];
7332 break;
7333 case NEAR_NEWMV:
7334 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7335 best_filter = single_filter[NEARMV][refs[0]];
7336 break;
7337 case NEW_NEARESTMV:
7338 if (single_filter[NEWMV][refs[0]] ==
7339 single_filter[NEARESTMV][refs[1]])
7340 best_filter = single_filter[NEWMV][refs[0]];
7341 break;
7342 case NEW_NEARMV:
7343 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7344 best_filter = single_filter[NEWMV][refs[0]];
7345 break;
7346 default:
7347 if (single_filter[this_mode][refs[0]] ==
7348 single_filter[this_mode][refs[1]])
7349 best_filter = single_filter[this_mode][refs[0]];
7350 break;
7351 }
7352#else
7353 if (single_filter[this_mode][refs[0]] ==
7354 single_filter[this_mode][refs[1]])
7355 best_filter = single_filter[this_mode][refs[0]];
7356#endif // CONFIG_EXT_INTER
7357 }
7358 }
Angie Chiang75c22092016-10-25 12:19:16 -07007359 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7360 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007361 }
7362 return best_filter;
7363}
Fergus Simpson4063a682017-02-28 16:52:22 -08007364#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007365
7366#if CONFIG_EXT_INTER
7367// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007368#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007369static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007370 const BLOCK_SIZE bsize, const uint8_t *const p0,
7371 const uint8_t *const p1, int *const best_wedge_sign,
7372 int *const best_wedge_index) {
7373 const MACROBLOCKD *const xd = &x->e_mbd;
7374 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007375 const int bw = block_size_wide[bsize];
7376 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007377 const int N = bw * bh;
7378 int rate;
7379 int64_t dist;
7380 int64_t rd, best_rd = INT64_MAX;
7381 int wedge_index;
7382 int wedge_sign;
7383 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7384 const uint8_t *mask;
7385 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007386#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007387 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7388 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7389#else
7390 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007391#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007392
7393 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7394 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7395 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7396 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7397
7398 int64_t sign_limit;
7399
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007400#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007401 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007402 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007403 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007404 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007405 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007406 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007407 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7408 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007409#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007410 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007411 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7412 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7413 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007414 }
7415
Yaowu Xuf883b422016-08-30 14:01:10 -07007416 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7417 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007418 (1 << WEDGE_WEIGHT_BITS) / 2;
7419
Jingning Han61418bb2017-01-23 17:12:48 -08007420 if (N < 64)
7421 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7422 else
7423 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007424
7425 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007426 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007427
7428 // TODO(jingning): Make sse2 functions support N = 16 case
7429 if (N < 64)
7430 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7431 else
7432 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007433
Yaowu Xuf883b422016-08-30 14:01:10 -07007434 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007435 if (N < 64)
7436 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7437 else
7438 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007439 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7440
7441 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7442 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7443
7444 if (rd < best_rd) {
7445 *best_wedge_index = wedge_index;
7446 *best_wedge_sign = wedge_sign;
7447 best_rd = rd;
7448 }
7449 }
7450
7451 return best_rd;
7452}
7453
7454// Choose the best wedge index the specified sign
7455static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007456 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007457 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7458 const int wedge_sign, int *const best_wedge_index) {
7459 const MACROBLOCKD *const xd = &x->e_mbd;
7460 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007461 const int bw = block_size_wide[bsize];
7462 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007463 const int N = bw * bh;
7464 int rate;
7465 int64_t dist;
7466 int64_t rd, best_rd = INT64_MAX;
7467 int wedge_index;
7468 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7469 const uint8_t *mask;
7470 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007471#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007472 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7473 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7474#else
7475 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007476#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007477
7478 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7479 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7480
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007481#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007483 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007484 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007485 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007486 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7487 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007488#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007489 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007490 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7491 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007492 }
7493
7494 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007495 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007496 if (N < 64)
7497 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7498 else
7499 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007500 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7501
7502 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7503 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7504
7505 if (rd < best_rd) {
7506 *best_wedge_index = wedge_index;
7507 best_rd = rd;
7508 }
7509 }
7510
7511 return best_rd;
7512}
7513
Yaowu Xuf883b422016-08-30 14:01:10 -07007514static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007515 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007516 const BLOCK_SIZE bsize,
7517 const uint8_t *const p0,
7518 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007519 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007520 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007521 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007522
7523 int64_t rd;
7524 int wedge_index = -1;
7525 int wedge_sign = 0;
7526
Sarah Parker42d96102017-01-31 21:05:27 -08007527 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007528
7529 if (cpi->sf.fast_wedge_sign_estimate) {
7530 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7531 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7532 } else {
7533 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7534 }
7535
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007536 mbmi->wedge_sign = wedge_sign;
7537 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007538 return rd;
7539}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007540#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007541
Sarah Parker569edda2016-12-14 14:57:38 -08007542#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07007543static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007544 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07007545 const uint8_t *const p0,
7546 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007547 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08007548 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7549 const struct buf_2d *const src = &x->plane[0].src;
7550 const int bw = block_size_wide[bsize];
7551 const int bh = block_size_high[bsize];
7552 const int N = bw * bh;
7553 int rate;
7554 uint64_t sse;
7555 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07007556 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007557 SEG_MASK_TYPE cur_mask_type;
7558 int64_t best_rd = INT64_MAX;
7559 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007560#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007561 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7562 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7563#else
7564 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007565#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007566 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7567 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7568 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7569
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007570#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007571 if (hbd) {
7572 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7573 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7574 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7575 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7576 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7577 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7578 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007579#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007580 {
7581 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7582 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7583 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7584 }
7585
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007586 // try each mask type and its inverse
7587 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007588// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007589#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007590 if (hbd)
7591 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007592 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007593 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7594 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007595#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007596 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
7597 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007598
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007599 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007600 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007601 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007602
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007603 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7604 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007605
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007606 if (rd0 < best_rd) {
7607 best_mask_type = cur_mask_type;
7608 best_rd = rd0;
7609 }
7610 }
Sarah Parker569edda2016-12-14 14:57:38 -08007611
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007612 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007613 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007614#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007615 if (hbd)
7616 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007617 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007618 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7619 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007620#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007621 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
7622 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007623
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007624 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007625}
7626#endif // CONFIG_COMPOUND_SEGMENT
7627
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007628#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07007629static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007630 const MACROBLOCK *const x,
7631 const BLOCK_SIZE bsize,
7632 const uint8_t *const p0,
7633 const uint8_t *const p1) {
7634 const MACROBLOCKD *const xd = &x->e_mbd;
7635 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7636
7637 int64_t rd;
7638 int wedge_index = -1;
7639
7640 assert(is_interintra_wedge_used(bsize));
7641
7642 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7643
7644 mbmi->interintra_wedge_sign = 0;
7645 mbmi->interintra_wedge_index = wedge_index;
7646 return rd;
7647}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007648#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08007649
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007650#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007651static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07007652 const BLOCK_SIZE bsize,
7653 const uint8_t *const p0,
7654 const uint8_t *const p1) {
7655 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007656 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07007657 switch (compound_type) {
7658#if CONFIG_WEDGE
7659 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
7660#endif // CONFIG_WEDGE
7661#if CONFIG_COMPOUND_SEGMENT
7662 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
7663#endif // CONFIG_COMPOUND_SEGMENT
7664 default: assert(0); return 0;
7665 }
7666}
7667
Sarah Parker6fdc8532016-11-16 17:47:13 -08007668static int interinter_compound_motion_search(const AV1_COMP *const cpi,
7669 MACROBLOCK *x,
7670 const BLOCK_SIZE bsize,
7671 const int this_mode, int mi_row,
7672 int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007673 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007674 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7675 int_mv tmp_mv[2];
7676 int rate_mvs[2], tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007677 const INTERINTER_COMPOUND_DATA compound_data = {
7678#if CONFIG_WEDGE
7679 mbmi->wedge_index,
7680 mbmi->wedge_sign,
7681#endif // CONFIG_WEDGE
7682#if CONFIG_COMPOUND_SEGMENT
7683 mbmi->mask_type,
7684 xd->seg_mask,
7685#endif // CONFIG_COMPOUND_SEGMENT
7686 mbmi->interinter_compound_type
7687 };
Sarah Parker6fdc8532016-11-16 17:47:13 -08007688 if (this_mode == NEW_NEWMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007689 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7690 mi_col, tmp_mv, rate_mvs, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007691 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7692 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7693 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7694 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007695 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7696 mi_col, tmp_mv, rate_mvs, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007697 tmp_rate_mv = rate_mvs[0];
7698 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7699 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007700 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7701 mi_col, tmp_mv, rate_mvs, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007702 tmp_rate_mv = rate_mvs[1];
7703 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7704 }
7705 return tmp_rate_mv;
7706}
7707
Sarah Parkerddcea392017-04-25 15:57:22 -07007708static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007709 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7710 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7711 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7712 int *strides, int mi_row, int mi_col) {
7713 MACROBLOCKD *xd = &x->e_mbd;
7714 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7715 int rate_sum;
7716 int64_t dist_sum;
7717 int64_t best_rd_cur = INT64_MAX;
7718 int64_t rd = INT64_MAX;
7719 int tmp_skip_txfm_sb;
7720 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007721 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08007722
Sarah Parkerddcea392017-04-25 15:57:22 -07007723 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Sarah Parker569edda2016-12-14 14:57:38 -08007724 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7725
Sarah Parker2e604882017-01-17 17:31:25 -08007726 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07007727 use_masked_motion_search(compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007728 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7729 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00007730 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007731 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7732 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7733 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007734 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007735 mbmi->mv[0].as_int = cur_mv[0].as_int;
7736 mbmi->mv[1].as_int = cur_mv[1].as_int;
7737 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007738 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7739#if CONFIG_SUPERTX
7740 0, 0,
7741#endif // CONFIG_SUPERTX
7742 preds0, strides, preds1,
7743 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007744 }
7745 av1_subtract_plane(x, bsize, 0);
7746 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7747 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7748 if (rd != INT64_MAX)
7749 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7750 best_rd_cur = rd;
7751
7752 } else {
David Barker426a9972017-01-27 11:03:11 +00007753 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7754#if CONFIG_SUPERTX
7755 0, 0,
7756#endif // CONFIG_SUPERTX
7757 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007758 av1_subtract_plane(x, bsize, 0);
7759 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7760 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7761 if (rd != INT64_MAX)
7762 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7763 best_rd_cur = rd;
7764 }
7765 return best_rd_cur;
7766}
Sarah Parkerddcea392017-04-25 15:57:22 -07007767#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007768#endif // CONFIG_EXT_INTER
7769
Fergus Simpson073c6f32017-02-17 12:13:48 -08007770typedef struct {
7771#if CONFIG_MOTION_VAR
7772 // Inter prediction buffers and respective strides
7773 uint8_t *above_pred_buf[MAX_MB_PLANE];
7774 int above_pred_stride[MAX_MB_PLANE];
7775 uint8_t *left_pred_buf[MAX_MB_PLANE];
7776 int left_pred_stride[MAX_MB_PLANE];
7777#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007778 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007779#if CONFIG_EXT_INTER
7780 // Pointer to array of motion vectors to use for each ref and their rates
7781 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007782 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007783 // Pointers costs of compound inter-intra and inter-inter predictions
7784 int *compmode_interintra_cost;
7785 int *compmode_interinter_cost;
7786 // Pointer to array of predicted rate-distortion
7787 // Should point to first of 2 arrays in 2D array
7788 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007789#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007790 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007791} HandleInterModeArgs;
7792
Fergus Simpson45509632017-02-22 15:30:50 -08007793static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7794 const BLOCK_SIZE bsize,
7795 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
7796 const int mi_row, const int mi_col,
7797 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007798 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007799 const MACROBLOCKD *const xd = &x->e_mbd;
7800 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7801 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7802 const int is_comp_pred = has_second_ref(mbmi);
7803 const PREDICTION_MODE this_mode = mbmi->mode;
7804#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007805 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7806#endif // CONFIG_EXT_INTER
7807 int_mv *const frame_mv = mode_mv[this_mode];
7808 const int refs[2] = { mbmi->ref_frame[0],
7809 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7810 int i;
7811
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007812 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007813
7814 if (is_comp_pred) {
7815#if CONFIG_EXT_INTER
7816 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007817 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007818 }
7819
7820 if (this_mode == NEW_NEWMV) {
7821 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7822 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7823
7824 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7825 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
Zoe Liu122f3942017-04-25 11:18:38 -07007826 rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007827 } else {
7828 *rate_mv = 0;
7829 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007830 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007831 *rate_mv += av1_mv_bit_cost(
7832 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7833 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7834 }
7835 }
7836 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7837 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007838 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007839 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
7840 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
7841 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7842 } else {
David Barkercb03dc32017-04-07 13:05:09 +01007843 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08007844 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007845 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007846 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7847 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7848 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7849 }
7850#else
7851 // Initialize mv using single prediction mode result.
7852 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7853 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7854
7855 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07007856 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007857 } else {
7858 *rate_mv = 0;
7859 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007860 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007861 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
7862 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7863 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7864 }
7865 }
7866#endif // CONFIG_EXT_INTER
7867 } else {
7868#if CONFIG_EXT_INTER
7869 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007870 x->best_mv = args->single_newmv[refs[0]];
7871 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08007872 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007873 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
7874 args->single_newmv[refs[0]] = x->best_mv;
7875 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08007876 }
7877#else
7878 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
7879 single_newmv[refs[0]] = x->best_mv;
7880#endif // CONFIG_EXT_INTER
7881
7882 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7883
7884 frame_mv[refs[0]] = x->best_mv;
7885 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7886
7887 // Estimate the rate implications of a new mv but discount this
7888 // under certain circumstances where we want to help initiate a weak
7889 // motion field, where the distortion gain for a single block may not
7890 // be enough to overcome the cost of a new mv.
7891 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
7892 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
7893 }
7894 }
7895
7896 return 0;
7897}
7898
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007899int64_t interpolation_filter_search(
7900 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
7901 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
7902 BUFFER_SET *const orig_dst,
7903 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
7904 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
7905 int64_t *const skip_sse_sb) {
7906 const AV1_COMMON *cm = &cpi->common;
7907 MACROBLOCKD *const xd = &x->e_mbd;
7908 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7909 int i;
7910 int tmp_rate;
7911 int64_t tmp_dist;
7912
7913 (void)single_filter;
7914
7915 InterpFilter assign_filter = SWITCHABLE;
7916
7917 if (cm->interp_filter == SWITCHABLE) {
7918#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007919 assign_filter = av1_is_interp_needed(xd)
7920 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
7921 single_filter)
7922 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007923#endif // !CONFIG_DUAL_FILTER
7924 } else {
7925 assign_filter = cm->interp_filter;
7926 }
7927
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007928 set_default_interp_filters(mbmi, assign_filter);
7929
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007930 *switchable_rate = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007931 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007932 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
7933 skip_txfm_sb, skip_sse_sb);
7934 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
7935
7936 if (assign_filter == SWITCHABLE) {
7937 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007938 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007939#if CONFIG_DUAL_FILTER
7940 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7941#else
7942 const int filter_set_size = SWITCHABLE_FILTERS;
7943#endif // CONFIG_DUAL_FILTER
7944 int best_in_temp = 0;
7945#if CONFIG_DUAL_FILTER
7946 InterpFilter best_filter[4];
7947 av1_copy(best_filter, mbmi->interp_filter);
7948#else
7949 InterpFilter best_filter = mbmi->interp_filter;
7950#endif // CONFIG_DUAL_FILTER
7951 restore_dst_buf(xd, *tmp_dst);
7952 // EIGHTTAP_REGULAR mode is calculated beforehand
7953 for (i = 1; i < filter_set_size; ++i) {
7954 int tmp_skip_sb = 0;
7955 int64_t tmp_skip_sse = INT64_MAX;
7956 int tmp_rs;
7957 int64_t tmp_rd;
7958#if CONFIG_DUAL_FILTER
7959 mbmi->interp_filter[0] = filter_sets[i][0];
7960 mbmi->interp_filter[1] = filter_sets[i][1];
7961 mbmi->interp_filter[2] = filter_sets[i][0];
7962 mbmi->interp_filter[3] = filter_sets[i][1];
7963#else
7964 mbmi->interp_filter = (InterpFilter)i;
7965#endif // CONFIG_DUAL_FILTER
7966 tmp_rs = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007967 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007968 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7969 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7970 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
7971
7972 if (tmp_rd < *rd) {
7973 *rd = tmp_rd;
7974 *switchable_rate = av1_get_switchable_rate(cpi, xd);
7975#if CONFIG_DUAL_FILTER
7976 av1_copy(best_filter, mbmi->interp_filter);
7977#else
7978 best_filter = mbmi->interp_filter;
7979#endif // CONFIG_DUAL_FILTER
7980 *skip_txfm_sb = tmp_skip_sb;
7981 *skip_sse_sb = tmp_skip_sse;
7982 best_in_temp = !best_in_temp;
7983 if (best_in_temp) {
7984 restore_dst_buf(xd, *orig_dst);
7985 } else {
7986 restore_dst_buf(xd, *tmp_dst);
7987 }
7988 }
7989 }
7990 if (best_in_temp) {
7991 restore_dst_buf(xd, *tmp_dst);
7992 } else {
7993 restore_dst_buf(xd, *orig_dst);
7994 }
7995#if CONFIG_DUAL_FILTER
7996 av1_copy(mbmi->interp_filter, best_filter);
7997#else
7998 mbmi->interp_filter = best_filter;
7999#endif // CONFIG_DUAL_FILTER
8000 } else {
8001#if CONFIG_DUAL_FILTER
8002 for (i = 0; i < 4; ++i)
8003 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
8004#else
8005 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
8006#endif // CONFIG_DUAL_FILTER
8007 }
8008 }
8009
8010 return 0;
8011}
8012
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008013// TODO(afergs): Refactor the MBMI references in here - there's four
8014// TODO(afergs): Refactor optional args - add them to a struct or remove
8015static int64_t motion_mode_rd(
8016 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
8017 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8018 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
8019 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
8020 const int *refs, int rate_mv,
8021#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8022#if CONFIG_EXT_INTER
8023 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
8024#if CONFIG_MOTION_VAR
8025 int rate_mv_bmc,
8026#endif // CONFIG_MOTION_VAR
8027#endif // CONFIG_EXT_INTER
8028#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8029 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
8030 const AV1_COMMON *const cm = &cpi->common;
8031 MACROBLOCKD *xd = &x->e_mbd;
8032 MODE_INFO *mi = xd->mi[0];
8033 MB_MODE_INFO *mbmi = &mi->mbmi;
8034 const int is_comp_pred = has_second_ref(mbmi);
8035 const PREDICTION_MODE this_mode = mbmi->mode;
8036
8037 (void)mode_mv;
8038 (void)mi_row;
8039 (void)mi_col;
8040 (void)args;
8041 (void)refs;
8042 (void)rate_mv;
8043 (void)is_comp_pred;
8044 (void)this_mode;
8045
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008046#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8047 MOTION_MODE motion_mode, last_motion_mode_allowed;
8048 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
8049 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
8050 MB_MODE_INFO base_mbmi, best_mbmi;
8051#if CONFIG_VAR_TX
8052 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
8053#endif // CONFIG_VAR_TX
8054#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8055
8056#if CONFIG_WARPED_MOTION
8057 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
8058#endif // CONFIG_WARPED_MOTION
8059
8060#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8061 av1_invalid_rd_stats(&best_rd_stats);
8062#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8063
8064 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
8065#if CONFIG_WARPED_MOTION
8066 aom_clear_system_state();
8067 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
8068#if CONFIG_EXT_INTER
8069 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
8070#endif // CONFIG_EXT_INTER
8071#endif // CONFIG_WARPED_MOTION
8072#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8073 rate2_nocoeff = rd_stats->rate;
8074 last_motion_mode_allowed = motion_mode_allowed(
8075#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8076 0, xd->global_motion,
8077#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8078 mi);
8079 base_mbmi = *mbmi;
8080#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8081
8082#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8083 int64_t best_rd = INT64_MAX;
8084 for (motion_mode = SIMPLE_TRANSLATION;
8085 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8086 int64_t tmp_rd = INT64_MAX;
8087 int tmp_rate;
8088 int64_t tmp_dist;
8089#if CONFIG_EXT_INTER
8090 int tmp_rate2 =
8091 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
8092#else
8093 int tmp_rate2 = rate2_nocoeff;
8094#endif // CONFIG_EXT_INTER
8095
8096 *mbmi = base_mbmi;
8097 mbmi->motion_mode = motion_mode;
8098#if CONFIG_MOTION_VAR
8099 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008100#if CONFIG_EXT_INTER
8101 *mbmi = *best_bmc_mbmi;
8102 mbmi->motion_mode = OBMC_CAUSAL;
8103#endif // CONFIG_EXT_INTER
8104 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
8105 int tmp_rate_mv = 0;
8106
8107 single_motion_search(cpi, x, bsize, mi_row, mi_col,
8108#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07008109 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008110#endif // CONFIG_EXT_INTER
8111 &tmp_rate_mv);
8112 mbmi->mv[0].as_int = x->best_mv.as_int;
8113 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8114 refs[0])) {
8115 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
8116 }
8117#if CONFIG_EXT_INTER
8118 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8119#else
8120 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8121#endif // CONFIG_EXT_INTER
8122#if CONFIG_DUAL_FILTER
8123 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
8124 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
8125 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
8126 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
8127#endif // CONFIG_DUAL_FILTER
Jingning Hanc44009c2017-05-06 11:36:49 -07008128 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008129#if CONFIG_EXT_INTER
8130 } else {
Jingning Hanc44009c2017-05-06 11:36:49 -07008131 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008132#endif // CONFIG_EXT_INTER
8133 }
8134 av1_build_obmc_inter_prediction(
8135 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
8136 args->left_pred_buf, args->left_pred_stride);
8137 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8138 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8139 }
8140#endif // CONFIG_MOTION_VAR
8141
8142#if CONFIG_WARPED_MOTION
8143 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008144#if CONFIG_EXT_INTER
8145 *mbmi = *best_bmc_mbmi;
8146 mbmi->motion_mode = WARPED_CAUSAL;
8147#endif // CONFIG_EXT_INTER
8148 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8149#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07008150 for (int dir = 0; dir < 4; ++dir)
8151 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
8152 ? EIGHTTAP_REGULAR
8153 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008154#else
8155 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8156 : cm->interp_filter;
8157#endif // CONFIG_DUAL_FILTER
8158
Debargha Mukherjeee8e6cad2017-03-22 17:38:38 -07008159 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
8160 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008161 &mbmi->wm_params[0], mi_row, mi_col) == 0) {
Jingning Hanc44009c2017-05-06 11:36:49 -07008162 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008163 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8164 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8165 } else {
8166 continue;
8167 }
8168 }
8169#endif // CONFIG_WARPED_MOTION
8170 x->skip = 0;
8171
8172 rd_stats->dist = 0;
8173 rd_stats->sse = 0;
8174 rd_stats->skip = 1;
8175 rd_stats->rate = tmp_rate2;
8176 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8177#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8178 if (last_motion_mode_allowed == WARPED_CAUSAL)
8179#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8180 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8181#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8182 else
8183 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8184#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8185 }
8186#if CONFIG_WARPED_MOTION
8187 if (mbmi->motion_mode == WARPED_CAUSAL) {
8188 rd_stats->rate -= rs;
8189 }
8190#endif // CONFIG_WARPED_MOTION
8191#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8192 if (!*skip_txfm_sb) {
8193 int64_t rdcosty = INT64_MAX;
8194 int is_cost_valid_uv = 0;
8195
8196 // cost and distortion
8197 av1_subtract_plane(x, bsize, 0);
8198#if CONFIG_VAR_TX
8199 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8200 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8201 } else {
8202 int idx, idy;
8203 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8204 for (idy = 0; idy < xd->n8_h; ++idy)
8205 for (idx = 0; idx < xd->n8_w; ++idx)
8206 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8207 memset(x->blk_skip[0], rd_stats_y->skip,
8208 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8209 }
8210#else
8211 /* clang-format off */
8212 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8213/* clang-format on */
8214#endif // CONFIG_VAR_TX
8215
8216 if (rd_stats_y->rate == INT_MAX) {
8217 av1_invalid_rd_stats(rd_stats);
8218#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8219 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8220 continue;
8221 } else {
8222#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8223 restore_dst_buf(xd, *orig_dst);
8224 return INT64_MAX;
8225#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8226 }
8227#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8228 }
8229
8230 av1_merge_rd_stats(rd_stats, rd_stats_y);
8231
8232 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8233 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
8234/* clang-format off */
8235#if CONFIG_VAR_TX
8236 is_cost_valid_uv =
8237 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8238#else
8239 is_cost_valid_uv =
8240 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8241#endif // CONFIG_VAR_TX
8242 if (!is_cost_valid_uv) {
8243#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8244 continue;
8245#else
8246 restore_dst_buf(xd, *orig_dst);
8247 return INT64_MAX;
8248#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8249 }
8250 /* clang-format on */
8251 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8252#if CONFIG_RD_DEBUG
8253 // record transform block coefficient cost
8254 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8255 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8256 // here because we already collect the coefficient cost. Move this part to
8257 // other place when we need to compare non-coefficient cost.
8258 mbmi->rd_stats = *rd_stats;
8259#endif // CONFIG_RD_DEBUG
8260#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8261 if (rd_stats->skip) {
8262 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8263 rd_stats_y->rate = 0;
8264 rd_stats_uv->rate = 0;
8265 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8266 mbmi->skip = 0;
8267 // here mbmi->skip temporarily plays a role as what this_skip2 does
8268 } else if (!xd->lossless[mbmi->segment_id] &&
8269 (RDCOST(x->rdmult, x->rddiv,
8270 rd_stats_y->rate + rd_stats_uv->rate +
8271 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8272 rd_stats->dist) >=
8273 RDCOST(x->rdmult, x->rddiv,
8274 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8275 rd_stats->sse))) {
8276 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8277 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8278 rd_stats->dist = rd_stats->sse;
8279 rd_stats_y->rate = 0;
8280 rd_stats_uv->rate = 0;
8281 mbmi->skip = 1;
8282 } else {
8283 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8284 mbmi->skip = 0;
8285 }
8286 *disable_skip = 0;
8287#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8288 } else {
8289 x->skip = 1;
8290 *disable_skip = 1;
8291 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8292
8293// The cost of skip bit needs to be added.
8294#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8295 mbmi->skip = 0;
8296#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8297 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8298
8299 rd_stats->dist = *skip_sse_sb;
8300 rd_stats->sse = *skip_sse_sb;
8301 rd_stats_y->rate = 0;
8302 rd_stats_uv->rate = 0;
8303 rd_stats->skip = 1;
8304 }
8305
8306#if CONFIG_GLOBAL_MOTION
8307 if (this_mode == ZEROMV
8308#if CONFIG_EXT_INTER
8309 || this_mode == ZERO_ZEROMV
8310#endif // CONFIG_EXT_INTER
8311 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008312 if (is_nontrans_global_motion(xd)) {
8313 rd_stats->rate -= rs;
8314#if CONFIG_DUAL_FILTER
8315 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8316 ? EIGHTTAP_REGULAR
8317 : cm->interp_filter;
8318 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8319 ? EIGHTTAP_REGULAR
8320 : cm->interp_filter;
8321#else
8322 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8323 ? EIGHTTAP_REGULAR
8324 : cm->interp_filter;
8325#endif // CONFIG_DUAL_FILTER
8326 }
8327 }
8328#endif // CONFIG_GLOBAL_MOTION
8329
8330#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8331 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8332 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8333 best_mbmi = *mbmi;
8334 best_rd = tmp_rd;
8335 best_rd_stats = *rd_stats;
8336 best_rd_stats_y = *rd_stats_y;
8337 best_rd_stats_uv = *rd_stats_uv;
8338#if CONFIG_VAR_TX
8339 for (int i = 0; i < MAX_MB_PLANE; ++i)
8340 memcpy(best_blk_skip[i], x->blk_skip[i],
8341 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8342#endif // CONFIG_VAR_TX
8343 best_xskip = x->skip;
8344 best_disable_skip = *disable_skip;
8345 }
8346 }
8347
8348 if (best_rd == INT64_MAX) {
8349 av1_invalid_rd_stats(rd_stats);
8350 restore_dst_buf(xd, *orig_dst);
8351 return INT64_MAX;
8352 }
8353 *mbmi = best_mbmi;
8354 *rd_stats = best_rd_stats;
8355 *rd_stats_y = best_rd_stats_y;
8356 *rd_stats_uv = best_rd_stats_uv;
8357#if CONFIG_VAR_TX
8358 for (int i = 0; i < MAX_MB_PLANE; ++i)
8359 memcpy(x->blk_skip[i], best_blk_skip[i],
8360 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8361#endif // CONFIG_VAR_TX
8362 x->skip = best_xskip;
8363 *disable_skip = best_disable_skip;
8364#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8365
8366 restore_dst_buf(xd, *orig_dst);
8367 return 0;
8368}
8369
Yaowu Xuc27fc142016-08-22 16:08:15 -07008370static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08008371 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
8372 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008373 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008374 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008375 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008376 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008377 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008378 MODE_INFO *mi = xd->mi[0];
8379 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8381 const int is_comp_pred = has_second_ref(mbmi);
8382 const int this_mode = mbmi->mode;
8383 int_mv *frame_mv = mode_mv[this_mode];
8384 int i;
8385 int refs[2] = { mbmi->ref_frame[0],
8386 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8387 int_mv cur_mv[2];
8388 int rate_mv = 0;
8389#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008390 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008391 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008392 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008393#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008394 const unsigned int *const interintra_mode_cost =
8395 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008396#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008397 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07008398 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008399#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008400 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008401#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008402#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008403 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8404#else
8405 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008406#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008407 uint8_t *tmp_buf;
8408
Yue Chencb60b182016-10-13 15:18:22 -07008409#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008410#if CONFIG_EXT_INTER
8411 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008412 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008413#if CONFIG_MOTION_VAR
8414 int rate_mv_bmc;
8415#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008416#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008417#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008418 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008419 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008420 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008421
8422 int skip_txfm_sb = 0;
8423 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008424 int16_t mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008425
8426#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008427 *args->compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008428 mbmi->use_wedge_interintra = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008429 *args->compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008430 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008431
8432 // is_comp_interintra_pred implies !is_comp_pred
8433 assert(!is_comp_interintra_pred || (!is_comp_pred));
8434 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8435 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8436#endif // CONFIG_EXT_INTER
8437
Yaowu Xuc27fc142016-08-22 16:08:15 -07008438#if CONFIG_EXT_INTER
8439 if (is_comp_pred)
8440 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8441 else
8442#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008443 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8444 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008445
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008446#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008447 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8448 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8449 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008450#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008451 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008452 // Make sure that we didn't leave the plane destination buffers set
8453 // to tmp_buf at the end of the last iteration
8454 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008455
Yue Chen69f18e12016-09-08 14:48:15 -07008456#if CONFIG_WARPED_MOTION
8457 mbmi->num_proj_ref[0] = 0;
8458 mbmi->num_proj_ref[1] = 0;
8459#endif // CONFIG_WARPED_MOTION
8460
Yaowu Xuc27fc142016-08-22 16:08:15 -07008461 if (is_comp_pred) {
8462 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8463 frame_mv[refs[1]].as_int == INVALID_MV)
8464 return INT64_MAX;
8465 }
8466
Yue Chene9638cc2016-10-10 12:37:54 -07008467 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008468 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08008469 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008470 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008471 if (ret_val != 0)
8472 return ret_val;
8473 else
8474 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008475 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476 for (i = 0; i < is_comp_pred + 1; ++i) {
8477 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07008478 // Clip "next_nearest" so that it does not extend to far out of image
8479 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008480 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008481 mbmi->mv[i].as_int = cur_mv[i].as_int;
8482 }
8483
Yaowu Xuc27fc142016-08-22 16:08:15 -07008484#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008485 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008486#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008487 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008488#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008489 {
8490#if !CONFIG_EXT_INTER
8491 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008492#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008493 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8494 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8495 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8496
8497 for (i = 0; i < 2; ++i) {
8498 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008499 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008500 mbmi->mv[i].as_int = cur_mv[i].as_int;
8501 }
8502 }
8503 }
8504
8505#if CONFIG_EXT_INTER
8506 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8507 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
8508 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8509
8510 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8511 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008512 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008513 mbmi->mv[0].as_int = cur_mv[0].as_int;
8514 }
8515
8516 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
8517 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8518
8519 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8520 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008521 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008522 mbmi->mv[1].as_int = cur_mv[1].as_int;
8523 }
8524 }
8525
8526 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01008527 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008528 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
8529 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008530 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008531
8532 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8533 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008534 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008535 mbmi->mv[0].as_int = cur_mv[0].as_int;
8536 }
8537
8538 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
8539 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008540 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008541
8542 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8543 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008544 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008545 mbmi->mv[1].as_int = cur_mv[1].as_int;
8546 }
8547 }
8548#else
8549 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008550 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008551 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8552 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8553 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8554 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8555
8556 for (i = 0; i < 2; ++i) {
8557 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008558 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008559 mbmi->mv[i].as_int = cur_mv[i].as_int;
8560 }
8561 }
8562 }
8563#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008564
8565 // do first prediction into the destination buffer. Do the next
8566 // prediction into a temporary buffer. Then keep track of which one
8567 // of these currently holds the best predictor, and use the other
8568 // one for future predictions. In the end, copy from tmp_buf to
8569 // dst if necessary.
8570 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008571 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8572 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008573 }
8574 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008575 orig_dst.plane[i] = xd->plane[i].dst.buf;
8576 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008577 }
8578
8579 // We don't include the cost of the second reference here, because there
8580 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8581 // words if you present them in that order, the second one is always known
8582 // if the first is known.
8583 //
8584 // Under some circumstances we discount the cost of new mv mode to encourage
8585 // initiation of a motion field.
8586 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8587 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01008588#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008589 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01008590 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8591 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
8592 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008593#else
Angie Chiang76159122016-11-09 12:13:22 -08008594 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8595 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008596#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008597 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008598 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008599 }
8600
Angie Chiang76159122016-11-09 12:13:22 -08008601 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008602#if CONFIG_EXT_INTER
8603 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8604#else
8605 mbmi->mode != NEARESTMV
8606#endif // CONFIG_EXT_INTER
8607 )
8608 return INT64_MAX;
8609
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008610 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008611 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8612 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008613 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008614
Yaowu Xuc27fc142016-08-22 16:08:15 -07008615#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008616#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008617 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008618 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008619 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008620#if CONFIG_MOTION_VAR
8621 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008622#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008623#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008624
Sarah Parker6fdc8532016-11-16 17:47:13 -08008625 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008626 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008627 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008628 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8629 INTERINTER_COMPOUND_DATA best_compound_data;
8630 int_mv best_mv[2];
8631 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008632 int tmp_skip_txfm_sb;
8633 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07008634 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008635 uint8_t pred0[2 * MAX_SB_SQUARE];
8636 uint8_t pred1[2 * MAX_SB_SQUARE];
8637 uint8_t *preds0[1] = { pred0 };
8638 uint8_t *preds1[1] = { pred1 };
8639 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008640 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008641 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008642 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008643
Sarah Parker6fdc8532016-11-16 17:47:13 -08008644 best_mv[0].as_int = cur_mv[0].as_int;
8645 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008646 memset(&best_compound_data, 0, sizeof(best_compound_data));
8647#if CONFIG_COMPOUND_SEGMENT
8648 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
8649 best_compound_data.seg_mask = tmp_mask_buf;
8650#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008651
Sarah Parker42d96102017-01-31 21:05:27 -08008652 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07008653 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8654 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008655 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008656 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008657 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008658 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008659 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008660 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008661
Sarah Parker6fdc8532016-11-16 17:47:13 -08008662 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008663 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008664 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008665 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008666 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008667 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008668 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008669 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008670 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08008671 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008672
Sarah Parker6fdc8532016-11-16 17:47:13 -08008673 switch (cur_type) {
8674 case COMPOUND_AVERAGE:
Jingning Hanc44009c2017-05-06 11:36:49 -07008675 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8676 bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008677 av1_subtract_plane(x, bsize, 0);
8678 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8679 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8680 INT64_MAX);
8681 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008682 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008683 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008684 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008685 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008686#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008687 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008688 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8689 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008690 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00008691 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8692 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008693 }
8694 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008695#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08008696#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008697 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008698 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8699 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008700 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08008701 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8702 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008703 }
8704 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008705#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008706 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008707 }
Sarah Parker2e604882017-01-17 17:31:25 -08008708
8709 if (best_rd_cur < best_rd_compound) {
8710 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008711#if CONFIG_WEDGE
8712 best_compound_data.wedge_index = mbmi->wedge_index;
8713 best_compound_data.wedge_sign = mbmi->wedge_sign;
8714#endif // CONFIG_WEDGE
8715#if CONFIG_COMPOUND_SEGMENT
8716 best_compound_data.mask_type = mbmi->mask_type;
8717 memcpy(best_compound_data.seg_mask, xd->seg_mask,
8718 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8719#endif // CONFIG_COMPOUND_SEGMENT
8720 best_compound_data.interinter_compound_type =
8721 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08008722 if (have_newmv_in_inter_mode(this_mode)) {
8723 if (use_masked_motion_search(cur_type)) {
8724 best_tmp_rate_mv = tmp_rate_mv;
8725 best_mv[0].as_int = mbmi->mv[0].as_int;
8726 best_mv[1].as_int = mbmi->mv[1].as_int;
8727 } else {
8728 best_mv[0].as_int = cur_mv[0].as_int;
8729 best_mv[1].as_int = cur_mv[1].as_int;
8730 }
8731 }
8732 }
8733 // reset to original mvs for next iteration
8734 mbmi->mv[0].as_int = cur_mv[0].as_int;
8735 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008736 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008737#if CONFIG_WEDGE
8738 mbmi->wedge_index = best_compound_data.wedge_index;
8739 mbmi->wedge_sign = best_compound_data.wedge_sign;
8740#endif // CONFIG_WEDGE
8741#if CONFIG_COMPOUND_SEGMENT
8742 mbmi->mask_type = best_compound_data.mask_type;
8743 memcpy(xd->seg_mask, best_compound_data.seg_mask,
8744 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8745#endif // CONFIG_COMPOUND_SEGMENT
8746 mbmi->interinter_compound_type =
8747 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008748 if (have_newmv_in_inter_mode(this_mode)) {
8749 mbmi->mv[0].as_int = best_mv[0].as_int;
8750 mbmi->mv[1].as_int = best_mv[1].as_int;
8751 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8752 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008753 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008754 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8755 rate_mv = best_tmp_rate_mv;
8756 }
8757 }
8758
8759 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008760 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008761 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008762 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008763
8764 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008765
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008766 *args->compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008767 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008768 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01008769 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008770 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01008771 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008772 }
8773
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008774#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008775 if (is_comp_interintra_pred) {
8776 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8777 int64_t best_interintra_rd = INT64_MAX;
8778 int rmode, rate_sum;
8779 int64_t dist_sum;
8780 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 int tmp_rate_mv = 0;
8782 int tmp_skip_txfm_sb;
8783 int64_t tmp_skip_sse_sb;
8784 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8785 uint8_t *intrapred;
8786
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008787#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008788 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8789 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8790 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008791#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008792 intrapred = intrapred_;
8793
Emil Keyder01770b32017-01-20 18:03:11 -05008794 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008795 for (j = 0; j < MAX_MB_PLANE; j++) {
8796 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8797 xd->plane[j].dst.stride = bw;
8798 }
David Barkerac37fa32016-12-02 12:30:21 +00008799 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
8800 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008801 mbmi->ref_frame[1] = INTRA_FRAME;
8802 mbmi->use_wedge_interintra = 0;
8803
8804 for (j = 0; j < INTERINTRA_MODES; ++j) {
8805 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8806 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008807 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8808 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008809 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008810 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8811 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8812 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
8813 if (rd < best_interintra_rd) {
8814 best_interintra_rd = rd;
8815 best_interintra_mode = mbmi->interintra_mode;
8816 }
8817 }
8818 mbmi->interintra_mode = best_interintra_mode;
8819 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008820 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8821 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008822 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8823 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8825 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8826 if (rd != INT64_MAX)
8827 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
8828 best_interintra_rd = rd;
8829
8830 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008831 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008832 return INT64_MAX;
8833 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008834#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008835 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008836 int64_t best_interintra_rd_nowedge = INT64_MAX;
8837 int64_t best_interintra_rd_wedge = INT64_MAX;
8838 int_mv tmp_mv;
8839 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840 if (rd != INT64_MAX)
8841 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
8842 dist_sum);
8843 best_interintra_rd_nowedge = rd;
8844
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008845 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07008846 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8847 mbmi->use_wedge_interintra = 1;
8848
Yaowu Xuf883b422016-08-30 14:01:10 -07008849 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8850 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008851
8852 best_interintra_rd_wedge =
8853 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8854
8855 best_interintra_rd_wedge +=
8856 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
8857 // Refine motion vector.
8858 if (have_newmv_in_inter_mode(this_mode)) {
8859 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008860 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008861 mbmi->interintra_wedge_index, 1, bsize);
8862 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07008863 &tmp_mv, &tmp_rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008864 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00008865 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008866 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8867 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8868 rd = RDCOST(x->rdmult, x->rddiv,
8869 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8870 if (rd < best_interintra_rd_wedge) {
8871 best_interintra_rd_wedge = rd;
8872 } else {
8873 tmp_mv.as_int = cur_mv[0].as_int;
8874 tmp_rate_mv = rate_mv;
8875 }
8876 } else {
8877 tmp_mv.as_int = cur_mv[0].as_int;
8878 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008879 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008880 }
8881 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008882 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008883 rd =
8884 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8885 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8886 if (rd != INT64_MAX)
8887 rd = RDCOST(x->rdmult, x->rddiv,
8888 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8889 best_interintra_rd_wedge = rd;
8890 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8891 mbmi->use_wedge_interintra = 1;
8892 best_interintra_rd = best_interintra_rd_wedge;
8893 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008894 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008895 rate_mv = tmp_rate_mv;
8896 } else {
8897 mbmi->use_wedge_interintra = 0;
8898 best_interintra_rd = best_interintra_rd_nowedge;
8899 mbmi->mv[0].as_int = cur_mv[0].as_int;
8900 }
8901 } else {
8902 mbmi->use_wedge_interintra = 0;
8903 best_interintra_rd = best_interintra_rd_nowedge;
8904 }
8905 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008906#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008907
8908 pred_exists = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008909 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008910 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008911 *args->compmode_interintra_cost +=
Fergus Simpson073c6f32017-02-17 12:13:48 -08008912 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008913 if (is_interintra_wedge_used(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008914 *args->compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008915 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8916 if (mbmi->use_wedge_interintra) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008917 *args->compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008918 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008919 }
8920 }
8921 } else if (is_interintra_allowed(mbmi)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008922 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008923 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008924 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008925#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008926
Angie Chiang75c22092016-10-25 12:19:16 -07008927 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008928 int tmp_rate;
8929 int64_t tmp_dist;
Jingning Hanc44009c2017-05-06 11:36:49 -07008930 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008931 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8932 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8933 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
8934 }
Angie Chiang75c22092016-10-25 12:19:16 -07008935#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008936
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008937 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008938#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008939 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008940#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008941 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008942#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008943
8944#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008945 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008946 if (is_comp_pred) {
8947 const int mode0 = compound_ref0_mode(this_mode);
8948 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008949 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8950 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008951 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008952 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008953 return INT64_MAX;
8954 }
8955 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008956 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008957 }
8958 }
8959#endif // CONFIG_EXT_INTER
8960
8961 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8962 // if current pred_error modeled rd is substantially more than the best
8963 // so far, do not bother doing full rd
8964 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008965 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008966 return INT64_MAX;
8967 }
8968 }
8969
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008970 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
8971 disable_skip, mode_mv, mi_row, mi_col, args,
8972 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07008973#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008974#if CONFIG_EXT_INTER
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008975 rate2_bmc_nocoeff, &best_bmc_mbmi,
Yue Chencb60b182016-10-13 15:18:22 -07008976#if CONFIG_MOTION_VAR
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008977 rate_mv_bmc,
Yue Chencb60b182016-10-13 15:18:22 -07008978#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008979#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008980#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008981 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
8982 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08008983
Yaowu Xuc27fc142016-08-22 16:08:15 -07008984 return 0; // The rate-distortion cost will be re-calculated by caller.
8985}
8986
Alex Converse28744302017-04-13 14:46:22 -07008987#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07008988static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008989 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07008990 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07008991 const AV1_COMMON *const cm = &cpi->common;
8992 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
8993
Alex Converse28744302017-04-13 14:46:22 -07008994 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07008995 const TileInfo *tile = &xd->tile;
8996 MODE_INFO *const mi = xd->mi[0];
8997 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
8998 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
8999 const int w = block_size_wide[bsize];
9000 const int h = block_size_high[bsize];
9001 const int sb_row = mi_row / MAX_MIB_SIZE;
9002
9003 int_mv dv_ref;
9004 av1_find_ref_dv(&dv_ref, mi_row, mi_col);
9005
9006 const MvLimits tmp_mv_limits = x->mv_limits;
9007
9008 // TODO(aconverse@google.com): Handle same row DV.
9009 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
9010 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
9011 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
9012 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
9013 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
9014 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
9015 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
9016 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
9017 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
9018
9019 if (x->mv_limits.col_max < x->mv_limits.col_min ||
9020 x->mv_limits.row_max < x->mv_limits.row_min) {
9021 x->mv_limits = tmp_mv_limits;
9022 return INT64_MAX;
Alex Converse28744302017-04-13 14:46:22 -07009023 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009024
9025 struct buf_2d yv12_mb[MAX_MB_PLANE];
9026 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
9027 for (int i = 0; i < MAX_MB_PLANE; ++i) {
9028 xd->plane[i].pre[0] = yv12_mb[i];
9029 }
9030
9031 int step_param = cpi->mv_step_param;
9032 MV mvp_full = dv_ref.as_mv;
9033 mvp_full.col >>= 3;
9034 mvp_full.row >>= 3;
9035 int sadpb = x->sadperbit16;
9036 int cost_list[5];
9037 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
9038 sadpb, cond_cost_list(cpi, cost_list),
9039 &dv_ref.as_mv, INT_MAX, 1);
9040
9041 x->mv_limits = tmp_mv_limits;
9042 if (bestsme == INT_MAX) return INT64_MAX;
9043 mvp_full = x->best_mv.as_mv;
9044 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
9045 if (mv_check_bounds(&x->mv_limits, &dv)) return INT64_MAX;
9046 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) return INT64_MAX;
9047 MB_MODE_INFO *mbmi = &mi->mbmi;
9048 MB_MODE_INFO best_mbmi = *mbmi;
9049 RD_STATS best_rdcost = *rd_cost;
9050 int best_skip = x->skip;
9051#if CONFIG_PALETTE
9052 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
9053#endif
9054 mbmi->use_intrabc = 1;
9055 mbmi->mode = DC_PRED;
9056 mbmi->uv_mode = DC_PRED;
9057 mbmi->mv[0].as_mv = dv;
9058#if CONFIG_DUAL_FILTER
9059 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
9060#else
9061 mbmi->interp_filter = BILINEAR;
9062#endif
9063 mbmi->skip = 0;
9064 x->skip = 0;
Jingning Hanc44009c2017-05-06 11:36:49 -07009065 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Alex Converse3d8adf32017-04-24 12:35:42 -07009066
9067 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost, x->mvcost,
9068 MV_COST_WEIGHT);
9069 const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
9070 const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
9071 const int rate_mode =
9072 cpi->y_mode_costs[A][L][DC_PRED] + av1_cost_bit(INTRABC_PROB, 1);
9073
9074 RD_STATS rd_stats, rd_stats_uv;
9075 av1_subtract_plane(x, bsize, 0);
9076 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
9077 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
9078 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
9079#if CONFIG_RD_DEBUG
9080 mbmi->rd_stats = rd_stats;
9081#endif
9082
9083 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
9084
9085 RD_STATS rdc_noskip;
9086 av1_init_rd_stats(&rdc_noskip);
9087 rdc_noskip.rate =
9088 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
9089 rdc_noskip.dist = rd_stats.dist;
9090 rdc_noskip.rdcost =
9091 RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
9092 if (rdc_noskip.rdcost < best_rd) {
9093 best_rd = rdc_noskip.rdcost;
9094 best_mbmi = *mbmi;
9095 best_skip = x->skip;
9096 best_rdcost = rdc_noskip;
9097 }
9098
9099 x->skip = 1;
9100 mbmi->skip = 1;
9101 RD_STATS rdc_skip;
9102 av1_init_rd_stats(&rdc_skip);
9103 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
9104 rdc_skip.dist = rd_stats.sse;
9105 rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
9106 if (rdc_skip.rdcost < best_rd) {
9107 best_rd = rdc_skip.rdcost;
9108 best_mbmi = *mbmi;
9109 best_skip = x->skip;
9110 best_rdcost = rdc_skip;
9111 }
9112 *mbmi = best_mbmi;
9113 *rd_cost = best_rdcost;
9114 x->skip = best_skip;
9115 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07009116}
9117#endif // CONFIG_INTRABC
9118
Urvang Joshi52648442016-10-13 17:27:51 -07009119void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009120 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07009121 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9122 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009123 MACROBLOCKD *const xd = &x->e_mbd;
9124 struct macroblockd_plane *const pd = xd->plane;
9125 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9126 int y_skip = 0, uv_skip = 0;
9127 int64_t dist_y = 0, dist_uv = 0;
9128 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009129 const int unify_bsize = CONFIG_CB4X4;
9130
Yaowu Xuc27fc142016-08-22 16:08:15 -07009131 ctx->skip = 0;
9132 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009133 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07009134#if CONFIG_INTRABC
9135 xd->mi[0]->mbmi.use_intrabc = 0;
9136#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07009137
Alex Conversed1b6fad2017-04-26 15:39:37 -07009138 const int64_t intra_yrd =
9139 (bsize >= BLOCK_8X8 || unify_bsize)
9140 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9141 &y_skip, bsize, best_rd)
9142 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
9143 &dist_y, &y_skip, best_rd);
9144
9145 if (intra_yrd < best_rd) {
9146 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9147 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009148
9149#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009150#if !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009151 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08009152#endif // !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009153 if (!x->skip_chroma_rd)
9154 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9155 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009156#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07009157 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9158 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009159#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009160
Alex Conversed1b6fad2017-04-26 15:39:37 -07009161 if (y_skip && uv_skip) {
9162 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
9163 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9164 rd_cost->dist = dist_y + dist_uv;
9165 } else {
9166 rd_cost->rate =
9167 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9168 rd_cost->dist = dist_y + dist_uv;
9169 }
9170 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009171 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07009172 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009173 }
9174
Alex Converse28744302017-04-13 14:46:22 -07009175#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07009176 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
9177 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07009178 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
9179 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07009180 assert(rd_cost->rate != INT_MAX);
9181 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07009182 }
9183#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07009184 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07009185
Yaowu Xuc27fc142016-08-22 16:08:15 -07009186 ctx->mic = *xd->mi[0];
9187 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009188}
9189
Yaowu Xuc27fc142016-08-22 16:08:15 -07009190// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009191int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009192 return (cpi->oxcf.pass == 2) &&
9193 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9194 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9195}
9196
9197// Checks to see if a super block is on a horizontal image edge.
9198// In most cases this is the "real" edge unless there are formatting
9199// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009200int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009201 int top_edge = 0;
9202 int bottom_edge = cpi->common.mi_rows;
9203 int is_active_h_edge = 0;
9204
9205 // For two pass account for any formatting bars detected.
9206 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009207 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009208
9209 // The inactive region is specified in MBs not mi units.
9210 // The image edge is in the following MB row.
9211 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9212
9213 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009214 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009215 }
9216
9217 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9218 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9219 is_active_h_edge = 1;
9220 }
9221 return is_active_h_edge;
9222}
9223
9224// Checks to see if a super block is on a vertical image edge.
9225// In most cases this is the "real" edge unless there are formatting
9226// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009227int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009228 int left_edge = 0;
9229 int right_edge = cpi->common.mi_cols;
9230 int is_active_v_edge = 0;
9231
9232 // For two pass account for any formatting bars detected.
9233 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009234 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009235
9236 // The inactive region is specified in MBs not mi units.
9237 // The image edge is in the following MB row.
9238 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9239
9240 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009241 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009242 }
9243
9244 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9245 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9246 is_active_v_edge = 1;
9247 }
9248 return is_active_v_edge;
9249}
9250
9251// Checks to see if a super block is at the edge of the active image.
9252// In most cases this is the "real" edge unless there are formatting
9253// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009254int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009255 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9256 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009257}
9258
Urvang Joshib100db72016-10-12 16:28:56 -07009259#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009260static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009261 MACROBLOCKD *const xd = &x->e_mbd;
9262 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9263 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9264 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009265 int src_stride = x->plane[1].src.stride;
9266 const uint8_t *const src_u = x->plane[1].src.buf;
9267 const uint8_t *const src_v = x->plane[2].src.buf;
9268 float *const data = x->palette_buffer->kmeans_data_buf;
9269 float centroids[2 * PALETTE_MAX_SIZE];
9270 uint8_t *const color_map = xd->plane[1].color_index_map;
9271 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009272#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009273 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9274 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009275#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009276 int plane_block_width, plane_block_height, rows, cols;
9277 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9278 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009279 (void)cpi;
9280
9281 for (r = 0; r < rows; ++r) {
9282 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009283#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009284 if (cpi->common.use_highbitdepth) {
9285 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9286 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9287 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009288#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009289 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9290 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009291#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009292 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009293#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009294 }
9295 }
9296
9297 for (r = 1; r < 3; ++r) {
9298 for (c = 0; c < pmi->palette_size[1]; ++c) {
9299 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9300 }
9301 }
9302
Yaowu Xuf883b422016-08-30 14:01:10 -07009303 av1_calc_indices(data, centroids, color_map, rows * cols,
9304 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009305 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9306 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009307}
Urvang Joshib100db72016-10-12 16:28:56 -07009308#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009309
hui su5db97432016-10-14 16:10:14 -07009310#if CONFIG_FILTER_INTRA
9311static void pick_filter_intra_interframe(
9312 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009313 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9314 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9315 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009316#if CONFIG_EXT_INTRA
9317 int8_t *uv_angle_delta,
9318#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009319#if CONFIG_PALETTE
9320 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9321#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009322 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9323 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9324 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9325#if CONFIG_SUPERTX
9326 int *returnrate_nocoef,
9327#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009328 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009329 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009330 MACROBLOCKD *const xd = &x->e_mbd;
9331 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009332#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009333 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009334#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009335 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9336 int dc_mode_index;
9337 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009338 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9339 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009340 TX_SIZE uv_tx;
9341
9342 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009343 if (av1_mode_order[i].mode == DC_PRED &&
9344 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009345 break;
9346 dc_mode_index = i;
9347 assert(i < MAX_MODES);
9348
9349 // TODO(huisu): use skip_mask for further speedup.
9350 (void)skip_mask;
9351 mbmi->mode = DC_PRED;
9352 mbmi->uv_mode = DC_PRED;
9353 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009354 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009355 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9356 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009357 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009358 return;
hui su5db97432016-10-14 16:10:14 -07009359 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009360 if (rate_y == INT_MAX) return;
9361
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009362 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9363 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009364 if (rate_uv_intra[uv_tx] == INT_MAX) {
9365 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9366 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9367 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009368#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009369 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009370#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009371 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9372#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009373 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009374#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009375 }
9376
9377 rate_uv = rate_uv_tokenonly[uv_tx];
9378 distortion_uv = dist_uv[uv_tx];
9379 skippable = skippable && skip_uv[uv_tx];
9380 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009381#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009382 if (cm->allow_screen_content_tools) {
9383 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9384 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9385 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9386 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9387 }
Urvang Joshib100db72016-10-12 16:28:56 -07009388#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009389#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009390 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009391#endif // CONFIG_EXT_INTRA
9392 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9393 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9394 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9395 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9396 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009397 }
9398
9399 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9400 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009401#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07009402 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
9403 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07009404 rate2 += av1_cost_bit(
9405 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009406#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009407
9408 if (!xd->lossless[mbmi->segment_id]) {
9409 // super_block_yrd above includes the cost of the tx_size in the
9410 // tokenonly rate, but for intra blocks, tx_size is always coded
9411 // (prediction granularity), so we account for it in the full rate,
9412 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009413 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414 }
9415
hui su5db97432016-10-14 16:10:14 -07009416 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9417 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9418 rate2 += write_uniform_cost(
9419 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9420#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009421 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07009422 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9423 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009424 }
hui su5db97432016-10-14 16:10:14 -07009425#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009426 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009427 rate2 +=
9428 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9429 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9430 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9431 rate2 +=
9432 write_uniform_cost(FILTER_INTRA_MODES,
9433 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009434 }
9435 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009436 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9437 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009438
9439 rate2 += ref_costs_single[INTRA_FRAME];
9440
9441 if (skippable) {
9442 rate2 -= (rate_y + rate_uv);
9443 rate_y = 0;
9444 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009445 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009446 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009447 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009448 }
9449 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009450
9451 if (this_rd < *best_intra_rd) {
9452 *best_intra_rd = this_rd;
9453 *best_intra_mode = mbmi->mode;
9454 }
9455 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009456 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009457
9458 if (this_rd < *best_rd) {
9459 *best_mode_index = dc_mode_index;
9460 mbmi->mv[0].as_int = 0;
9461 rd_cost->rate = rate2;
9462#if CONFIG_SUPERTX
9463 if (x->skip)
9464 *returnrate_nocoef = rate2;
9465 else
9466 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009467 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9468 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9469 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009470#endif // CONFIG_SUPERTX
9471 rd_cost->dist = distortion2;
9472 rd_cost->rdcost = this_rd;
9473 *best_rd = this_rd;
9474 *best_mbmode = *mbmi;
9475 *best_skip2 = 0;
9476 *best_mode_skippable = skippable;
9477 }
9478}
hui su5db97432016-10-14 16:10:14 -07009479#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009480
Yue Chencb60b182016-10-13 15:18:22 -07009481#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009482static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9483 const MACROBLOCKD *xd, int mi_row,
9484 int mi_col, const uint8_t *above,
9485 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009486 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009487#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009488
Urvang Joshi52648442016-10-13 17:27:51 -07009489void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009490 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009491 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009492#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009493 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009494#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009495 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9496 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009497 const AV1_COMMON *const cm = &cpi->common;
9498 const RD_OPT *const rd_opt = &cpi->rd;
9499 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009500 MACROBLOCKD *const xd = &x->e_mbd;
9501 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009502#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009503 const int try_palette =
9504 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009505 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009506#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009507 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9508 const struct segmentation *const seg = &cm->seg;
9509 PREDICTION_MODE this_mode;
9510 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9511 unsigned char segment_id = mbmi->segment_id;
9512 int comp_pred, i, k;
9513 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9514 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009515 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009516#if CONFIG_EXT_INTER
9517 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
9518 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009519#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009520 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9521 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009522 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009523#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009524 AOM_LAST2_FLAG,
9525 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009526#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009527 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009528#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009529 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009530#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009531 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009532 };
9533 int64_t best_rd = best_rd_so_far;
9534 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9535 int64_t best_pred_diff[REFERENCE_MODES];
9536 int64_t best_pred_rd[REFERENCE_MODES];
9537 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009538 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9539 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009540 int best_mode_skippable = 0;
9541 int midx, best_mode_index = -1;
9542 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9543 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009544 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009545 int64_t best_intra_rd = INT64_MAX;
9546 unsigned int best_pred_sse = UINT_MAX;
9547 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009548 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9549 int64_t dist_uvs[TX_SIZES_ALL];
9550 int skip_uvs[TX_SIZES_ALL];
9551 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009552#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009553 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009554#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009555#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009556 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009557 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009558 uint8_t directional_mode_skip_mask[INTRA_MODES];
9559#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009560#if CONFIG_FILTER_INTRA
9561 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009562 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009563#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009564 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009565 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9566 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9567 int best_skip2 = 0;
9568 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009569 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Urvang Joshie6ca8e82017-03-15 14:57:41 -07009570#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009571 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9572 int64_t best_single_inter_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009573#endif // CONFIG_EXT_INTER
9574 int mode_skip_start = sf->mode_skip_start + 1;
9575 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9576 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9577 int64_t mode_threshold[MAX_MODES];
9578 int *mode_map = tile_data->mode_map[bsize];
9579 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009580#if CONFIG_PVQ
9581 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009582#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009583
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009584 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009585#if CONFIG_MOTION_VAR
9586 { NULL },
9587 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9588 { NULL },
9589 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9590#endif // CONFIG_MOTION_VAR
9591#if CONFIG_EXT_INTER
9592 NULL,
9593 NULL,
9594 NULL,
9595 NULL,
9596 NULL,
9597#else // CONFIG_EXT_INTER
9598 NULL,
9599#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009600 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009601 };
9602
Urvang Joshib100db72016-10-12 16:28:56 -07009603#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009604 const int rows = block_size_high[bsize];
9605 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009606#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9607#if CONFIG_PALETTE
9608 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009609 const MODE_INFO *above_mi = xd->above_mi;
9610 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009611#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009612#if CONFIG_MOTION_VAR
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009613#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009614 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9615 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9616#else
9617 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9618 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009619#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009620 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9621 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009622 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9623 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9624 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9625 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009626
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009627#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009628 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9629 int len = sizeof(uint16_t);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009630 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9631 args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9632 args.above_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009633 CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009634 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9635 args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9636 args.left_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009637 CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009638 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009639#endif // CONFIG_HIGHBITDEPTH
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009640 args.above_pred_buf[0] = tmp_buf1;
9641 args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
9642 args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9643 args.left_pred_buf[0] = tmp_buf2;
9644 args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
9645 args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009646#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009647 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009648#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009649#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009650
Yaowu Xuf883b422016-08-30 14:01:10 -07009651 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009652
Urvang Joshib100db72016-10-12 16:28:56 -07009653#if CONFIG_PALETTE
9654 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07009655 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009656 if (above_mi)
9657 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9658 if (left_mi)
9659 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9660 }
Urvang Joshib100db72016-10-12 16:28:56 -07009661#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009662
Yaowu Xuc27fc142016-08-22 16:08:15 -07009663 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9664 &comp_mode_p);
9665
9666 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009667 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009668 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9669 for (i = 0; i < MB_MODE_COUNT; ++i) {
9670 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009671 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009672 }
9673 }
9674
9675 rd_cost->rate = INT_MAX;
9676#if CONFIG_SUPERTX
9677 *returnrate_nocoef = INT_MAX;
9678#endif // CONFIG_SUPERTX
9679
9680 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9681 x->pred_mv_sad[ref_frame] = INT_MAX;
9682 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009683#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009684 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009685#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009686 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9687 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9688 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9689 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9690 }
9691 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009692#if CONFIG_GLOBAL_MOTION
9693 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009694 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009695 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9696 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009697 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009698#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009699 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009700#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009701#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009702 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009703#if CONFIG_GLOBAL_MOTION
9704 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009705 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009706 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9707 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009708 .as_int;
9709#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009710 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009711#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009712#endif // CONFIG_EXT_INTER
9713 }
9714
Yaowu Xuc27fc142016-08-22 16:08:15 -07009715 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9716 MODE_INFO *const mi = xd->mi[0];
9717 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9718 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009719 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9720 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009721#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009722 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009723#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009724 candidates, mi_row, mi_col, NULL, NULL,
9725 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009726 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9727 MV_REFERENCE_FRAME rf[2];
9728 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009729 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9730 frame_mv[ZEROMV][rf[0]].as_int ||
9731 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9732 frame_mv[ZEROMV][rf[0]].as_int ||
9733 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9734 frame_mv[ZEROMV][rf[1]].as_int ||
9735 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009736 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9737 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009738 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009739
Yue Chencb60b182016-10-13 15:18:22 -07009740#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009741 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Yue Chenf7ba6472017-04-19 11:08:58 -07009742 if (check_num_overlappable_neighbors(mbmi) &&
9743 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009744 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9745 args.above_pred_buf, dst_width1,
9746 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009747 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009748 args.left_pred_buf, dst_width2,
9749 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07009750 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
9751 mi_col);
Yue Chen5329a2b2017-02-28 17:33:00 +08009752 x->mask_buf = mask2d_buf;
9753 x->wsrc_buf = weighted_src_buf;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009754 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9755 args.above_pred_stride[0], args.left_pred_buf[0],
9756 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009757 }
Yue Chencb60b182016-10-13 15:18:22 -07009758#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009759
9760 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9761 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9762// Skip checking missing references in both single and compound reference
9763// modes. Note that a mode will be skipped iff both reference frames
9764// are masked out.
9765#if CONFIG_EXT_REFS
9766 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9767 ref_frame_skip_mask[0] |= (1 << ref_frame);
9768 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9769 } else {
9770#endif // CONFIG_EXT_REFS
9771 ref_frame_skip_mask[0] |= (1 << ref_frame);
9772 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9773#if CONFIG_EXT_REFS
9774 }
9775#endif // CONFIG_EXT_REFS
9776 } else {
9777 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9778 // Skip fixed mv modes for poor references
9779 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9780 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9781 break;
9782 }
9783 }
9784 }
9785 // If the segment reference frame feature is enabled....
9786 // then do nothing if the current ref frame is not allowed..
9787 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9788 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9789 ref_frame_skip_mask[0] |= (1 << ref_frame);
9790 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9791 }
9792 }
9793
9794 // Disable this drop out case if the ref frame
9795 // segment level feature is enabled for this segment. This is to
9796 // prevent the possibility that we end up unable to pick any mode.
9797 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9798 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9799 // unless ARNR filtering is enabled in which case we want
9800 // an unfiltered alternative. We allow near/nearest as well
9801 // because they may result in zero-zero MVs but be cheaper.
9802 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009803 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009804 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9805#if CONFIG_EXT_REFS
9806 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9807 (1 << BWDREF_FRAME) |
9808#endif // CONFIG_EXT_REFS
9809 (1 << GOLDEN_FRAME);
9810 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9811 // TODO(zoeliu): To further explore whether following needs to be done for
9812 // BWDREF_FRAME as well.
9813 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009814#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009815 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009816 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009817 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009818 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009819#else
9820 zeromv.as_int = 0;
9821#endif // CONFIG_GLOBAL_MOTION
9822 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009823 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009824 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009825 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9826#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009827 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009828 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009829 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009830 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009831 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009832 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009833 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009834 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9835#endif // CONFIG_EXT_INTER
9836 }
9837 }
9838
9839 if (cpi->rc.is_src_frame_alt_ref) {
9840 if (sf->alt_ref_search_fp) {
9841 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9842 mode_skip_mask[ALTREF_FRAME] = 0;
9843 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9844 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9845 }
9846 }
9847
9848 if (sf->alt_ref_search_fp)
9849 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9850 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9851 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9852
9853 if (sf->adaptive_mode_search) {
9854 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9855 cpi->rc.frames_since_golden >= 3)
9856 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
9857 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9858 }
9859
9860 if (bsize > sf->max_intra_bsize) {
9861 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9862 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9863 }
9864
9865 mode_skip_mask[INTRA_FRAME] |=
9866 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9867
9868 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9869 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9870 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9871
9872 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9873 while (midx > 4) {
9874 uint8_t end_pos = 0;
9875 for (i = 5; i < midx; ++i) {
9876 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9877 uint8_t tmp = mode_map[i];
9878 mode_map[i] = mode_map[i - 1];
9879 mode_map[i - 1] = tmp;
9880 end_pos = i;
9881 }
9882 }
9883 midx = end_pos;
9884 }
9885
9886 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9887 x->use_default_intra_tx_type = 1;
9888 else
9889 x->use_default_intra_tx_type = 0;
9890
9891 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9892 x->use_default_inter_tx_type = 1;
9893 else
9894 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009895#if CONFIG_PVQ
9896 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009897#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009898#if CONFIG_EXT_INTER
9899 for (i = 0; i < MB_MODE_COUNT; ++i)
9900 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9901 modelled_rd[i][ref_frame] = INT64_MAX;
9902#endif // CONFIG_EXT_INTER
9903
9904 for (midx = 0; midx < MAX_MODES; ++midx) {
9905 int mode_index;
9906 int mode_excluded = 0;
9907 int64_t this_rd = INT64_MAX;
9908 int disable_skip = 0;
9909 int compmode_cost = 0;
9910#if CONFIG_EXT_INTER
9911 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009912 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009913#endif // CONFIG_EXT_INTER
9914 int rate2 = 0, rate_y = 0, rate_uv = 0;
9915 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9916 int skippable = 0;
9917 int this_skip2 = 0;
9918 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009919 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009920#if CONFIG_PVQ
9921 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009922#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009923 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009924 this_mode = av1_mode_order[mode_index].mode;
9925 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9926 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009927 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009928
9929#if CONFIG_EXT_INTER
9930 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9931 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -08009932 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009933 if (!is_interintra_allowed_bsize(bsize)) continue;
9934 }
9935
9936 if (is_inter_compound_mode(this_mode)) {
9937 frame_mv[this_mode][ref_frame].as_int =
9938 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9939 frame_mv[this_mode][second_ref_frame].as_int =
9940 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
9941 }
9942#endif // CONFIG_EXT_INTER
9943
9944 // Look at the reference frame of the best mode so far and set the
9945 // skip mask to look at a subset of the remaining modes.
9946 if (midx == mode_skip_start && best_mode_index >= 0) {
9947 switch (best_mbmode.ref_frame[0]) {
9948 case INTRA_FRAME: break;
9949 case LAST_FRAME:
9950 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9951 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9952 break;
9953#if CONFIG_EXT_REFS
9954 case LAST2_FRAME:
9955 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9956 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9957 break;
9958 case LAST3_FRAME:
9959 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9960 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9961 break;
9962#endif // CONFIG_EXT_REFS
9963 case GOLDEN_FRAME:
9964 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9965 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9966 break;
9967#if CONFIG_EXT_REFS
9968 case BWDREF_FRAME:
9969 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9970 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9971 break;
9972#endif // CONFIG_EXT_REFS
9973 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9974#if CONFIG_EXT_REFS
9975 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9976#endif // CONFIG_EXT_REFS
9977 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009978 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009979 case TOTAL_REFS_PER_FRAME:
9980 assert(0 && "Invalid Reference frame");
9981 break;
9982 }
9983 }
9984
9985 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009986 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009987 continue;
9988
9989 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
9990
9991 // Test best rd so far against threshold for trying this mode.
9992 if (best_mode_skippable && sf->schedule_mode_search)
9993 mode_threshold[mode_index] <<= 1;
9994
9995 if (best_rd < mode_threshold[mode_index]) continue;
9996
Yunqing Wangff4fa062017-04-21 10:56:08 -07009997 // This is only used in motion vector unit test.
9998 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
9999
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020010000#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
10001#if CONFIG_EXT_REFS
10002 if (cpi->oxcf.pass == 0) {
10003 // Complexity-compression trade-offs
10004 // if (ref_frame == ALTREF_FRAME) continue;
10005 // if (ref_frame == BWDREF_FRAME) continue;
10006 if (second_ref_frame == ALTREF_FRAME) continue;
10007 // if (second_ref_frame == BWDREF_FRAME) continue;
10008 }
10009#endif
10010#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010011 comp_pred = second_ref_frame > INTRA_FRAME;
10012 if (comp_pred) {
10013 if (!cpi->allow_comp_inter_inter) continue;
10014
10015 // Skip compound inter modes if ARF is not available.
10016 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10017
10018 // Do not allow compound prediction if the segment level reference frame
10019 // feature is in use as in this case there can only be one reference.
10020 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10021
10022 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10023 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10024 continue;
10025
10026 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10027 } else {
10028 if (ref_frame != INTRA_FRAME)
10029 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10030 }
10031
10032 if (ref_frame == INTRA_FRAME) {
10033 if (sf->adaptive_mode_search)
10034 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10035 continue;
10036
10037 if (this_mode != DC_PRED) {
10038 // Disable intra modes other than DC_PRED for blocks with low variance
10039 // Threshold for intra skipping based on source variance
10040 // TODO(debargha): Specialize the threshold for super block sizes
10041 const unsigned int skip_intra_var_thresh = 64;
10042 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10043 x->source_variance < skip_intra_var_thresh)
10044 continue;
10045 // Only search the oblique modes if the best so far is
10046 // one of the neighboring directional modes
10047 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10048 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10049 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10050 continue;
10051 }
10052 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10053 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10054 }
10055 }
Sarah Parkere5299862016-08-16 14:57:37 -070010056#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010057 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010058 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010059 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010060#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010061 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010062#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010063 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10064 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010065#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010066 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010067#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010068 frame_mv, this_mode, ref_frames, bsize, -1,
10069 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010070 continue;
10071 }
10072
10073 mbmi->mode = this_mode;
10074 mbmi->uv_mode = DC_PRED;
10075 mbmi->ref_frame[0] = ref_frame;
10076 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010077#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010078 pmi->palette_size[0] = 0;
10079 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010080#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010081#if CONFIG_FILTER_INTRA
10082 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10083 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10084#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010085 // Evaluate all sub-pel filters irrespective of whether we can use
10086 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010087
10088 set_default_interp_filters(mbmi, cm->interp_filter);
10089
Yaowu Xuc27fc142016-08-22 16:08:15 -070010090 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010091 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010092
10093 x->skip = 0;
10094 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10095
10096 // Select prediction reference frames.
10097 for (i = 0; i < MAX_MB_PLANE; i++) {
10098 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10099 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10100 }
10101
10102#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010103 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010104#endif // CONFIG_EXT_INTER
10105
10106 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010107 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010108 TX_SIZE uv_tx;
10109 struct macroblockd_plane *const pd = &xd->plane[1];
10110#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010111 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010112 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010113 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010114 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010115 if (!angle_stats_ready) {
10116 const int src_stride = x->plane[0].src.stride;
10117 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010118#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010119 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -070010120 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010121 directional_mode_skip_mask);
10122 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010123#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -070010124 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010125 directional_mode_skip_mask);
10126 angle_stats_ready = 1;
10127 }
10128 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010129 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -070010130 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
10131 intra_mode_cost[mbmi->mode], best_rd,
10132 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010133 } else {
10134 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010135 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010136 }
10137#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010138 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010139#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010140 rate_y = rd_stats_y.rate;
10141 distortion_y = rd_stats_y.dist;
10142 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010143
10144 if (rate_y == INT_MAX) continue;
10145
hui su5db97432016-10-14 16:10:14 -070010146#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010147 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010148#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010149
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010150 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10151 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010152 if (rate_uv_intra[uv_tx] == INT_MAX) {
10153 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010154 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10155 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010156#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010157 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010158#endif // CONFIG_PALETTE
10159
Yaowu Xuc27fc142016-08-22 16:08:15 -070010160#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010161 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10162#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010163#if CONFIG_FILTER_INTRA
10164 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10165#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010166 }
10167
10168 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010169 distortion_uv = dist_uvs[uv_tx];
10170 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010171 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010172#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010173 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010174 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10175 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10176 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10177 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10178 }
Urvang Joshib100db72016-10-12 16:28:56 -070010179#endif // CONFIG_PALETTE
10180
Yaowu Xuc27fc142016-08-22 16:08:15 -070010181#if CONFIG_EXT_INTRA
10182 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010183#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010184#if CONFIG_FILTER_INTRA
10185 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10186 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10187 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10188 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10189 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10190 }
10191#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010192
Jingning Han36fe3202017-02-20 22:31:49 -080010193#if CONFIG_CB4X4
10194 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10195 if (!x->skip_chroma_rd)
10196 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10197#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010198 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10199 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010200#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010201
Urvang Joshib100db72016-10-12 16:28:56 -070010202#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010203 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010204 rate2 += av1_cost_bit(
10205 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -070010206 }
Urvang Joshib100db72016-10-12 16:28:56 -070010207#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010208
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010209 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010210 // super_block_yrd above includes the cost of the tx_size in the
10211 // tokenonly rate, but for intra blocks, tx_size is always coded
10212 // (prediction granularity), so we account for it in the full rate,
10213 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010214 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010215 }
10216#if CONFIG_EXT_INTRA
10217 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -080010218#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010219 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -070010220 const int p_angle =
10221 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -070010222 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010223 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010224#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -070010225 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10226 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010227 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010228 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su0a6731f2017-04-26 15:23:47 -070010229 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10230 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010231 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010232#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010233#if CONFIG_FILTER_INTRA
10234 if (mbmi->mode == DC_PRED) {
10235 rate2 +=
10236 av1_cost_bit(cm->fc->filter_intra_probs[0],
10237 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10238 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10239 rate2 += write_uniform_cost(
10240 FILTER_INTRA_MODES,
10241 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10242 }
10243 }
10244 if (mbmi->uv_mode == DC_PRED) {
10245 rate2 +=
10246 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10247 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10248 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10249 rate2 += write_uniform_cost(
10250 FILTER_INTRA_MODES,
10251 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10252 }
10253#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -070010254 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010255 rate2 += intra_cost_penalty;
10256 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010257 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010258 int_mv backup_ref_mv[2];
10259
Jingning Hanc41a5492017-02-24 11:18:52 -080010260#if !SUB8X8_COMP_REF
10261 if (bsize < BLOCK_8X8 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010262#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010263
Yaowu Xuc27fc142016-08-22 16:08:15 -070010264 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10265 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010266#if CONFIG_EXT_INTER
10267 if (second_ref_frame == INTRA_FRAME) {
10268 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010269 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010270// TODO(debargha|geza.lore):
10271// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010272#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010273 mbmi->angle_delta[0] = 0;
10274 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010275#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010276 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010277#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010278#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010279#if CONFIG_FILTER_INTRA
10280 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10281 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10282#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010283 }
10284#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010285 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010286 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010287
David Barker404b2e82017-03-27 13:07:47 +010010288#if CONFIG_EXT_INTER
10289 if (comp_pred) {
10290 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +010010291 int ref_mv_idx = 0;
10292 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10293 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10294 // mbmi->ref_mv_idx (like NEWMV)
10295 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10296 ref_mv_idx = 1;
10297
10298 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10299 int_mv this_mv =
10300 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +010010301 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10302 xd->n8_h << MI_SIZE_LOG2, xd);
10303 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10304 }
David Barker3dfba992017-04-03 16:10:09 +010010305 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10306 int_mv this_mv =
10307 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +010010308 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10309 xd->n8_h << MI_SIZE_LOG2, xd);
10310 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10311 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010312 }
David Barker404b2e82017-03-27 13:07:47 +010010313 } else {
10314#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -070010315 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +010010316 int ref;
10317 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10318 int_mv this_mv =
10319 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10320 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10321 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10322 xd->n8_h << MI_SIZE_LOG2, xd);
10323 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10324 }
10325 }
10326#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010327 }
David Barker404b2e82017-03-27 13:07:47 +010010328#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010329 {
10330 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10331 av1_init_rd_stats(&rd_stats);
10332 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010333
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010334 // Point to variables that are maintained between loop iterations
10335 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010336#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010337 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010338 args.compmode_interintra_cost = &compmode_interintra_cost;
10339 args.compmode_interinter_cost = &compmode_interinter_cost;
10340 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010341#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010342 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10343 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010344 mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010345// Prevent pointers from escaping local scope
Yaowu Xuc27fc142016-08-22 16:08:15 -070010346#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010347 args.compmode_interintra_cost = NULL;
10348 args.compmode_interinter_cost = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010349#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010350
10351 rate2 = rd_stats.rate;
10352 skippable = rd_stats.skip;
10353 distortion2 = rd_stats.dist;
10354 total_sse = rd_stats.sse;
10355 rate_y = rd_stats_y.rate;
10356 rate_uv = rd_stats_uv.rate;
10357 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010358
David Barker404b2e82017-03-27 13:07:47 +010010359// TODO(jingning): This needs some refactoring to improve code quality
10360// and reduce redundant steps.
10361#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010362 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +010010363 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10364 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10365 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10366#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010367 if ((mbmi->mode == NEARMV &&
10368 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10369 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
David Barker404b2e82017-03-27 13:07:47 +010010370#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010371 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10372 MB_MODE_INFO backup_mbmi = *mbmi;
10373 int backup_skip = x->skip;
10374 int64_t tmp_ref_rd = this_rd;
10375 int ref_idx;
10376
Yue Chen6e601e92016-12-05 18:19:00 -080010377// TODO(jingning): This should be deprecated shortly.
10378#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010379 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010380#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010381 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010382#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010383 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010384 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010385
10386 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010387 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010388 // Dummy
10389 int_mv backup_fmv[2];
10390 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10391 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10392
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010393 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010394
10395 if (this_rd < INT64_MAX) {
10396 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10397 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10398 tmp_ref_rd =
10399 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010400 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010401 distortion2);
10402 else
10403 tmp_ref_rd =
10404 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010405 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010406 rate_y - rate_uv,
10407 total_sse);
10408 }
10409#if CONFIG_VAR_TX
10410 for (i = 0; i < MAX_MB_PLANE; ++i)
10411 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10412 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010413#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010414
10415 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10416 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010417 int dummy_disable_skip = 0;
10418 int ref;
10419 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010420 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010421#if CONFIG_EXT_INTER
10422 int tmp_compmode_interintra_cost = 0;
10423 int tmp_compmode_interinter_cost = 0;
10424#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010425
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010426 av1_invalid_rd_stats(&tmp_rd_stats);
Jingning Han52617b22017-04-11 12:50:08 -070010427 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010428
Yaowu Xuc27fc142016-08-22 16:08:15 -070010429 mbmi->ref_mv_idx = 1 + ref_idx;
10430
David Barker3dfba992017-04-03 16:10:09 +010010431#if CONFIG_EXT_INTER
10432 if (comp_pred) {
10433 int ref_mv_idx = mbmi->ref_mv_idx;
10434 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10435 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10436 // mbmi->ref_mv_idx (like NEWMV)
10437 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10438 ref_mv_idx = 1 + mbmi->ref_mv_idx;
10439
10440 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10441 int_mv this_mv =
10442 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10443 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10444 xd->n8_h << MI_SIZE_LOG2, xd);
10445 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10446 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
10447 int_mv this_mv =
10448 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10449 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10450 xd->n8_h << MI_SIZE_LOG2, xd);
10451 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10452 }
10453
10454 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10455 int_mv this_mv =
10456 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
10457 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10458 xd->n8_h << MI_SIZE_LOG2, xd);
10459 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10460 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10461 int_mv this_mv =
10462 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10463 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10464 xd->n8_h << MI_SIZE_LOG2, xd);
10465 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10466 }
10467 } else {
10468#endif // CONFIG_EXT_INTER
10469 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10470 int_mv this_mv =
10471 (ref == 0)
10472 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10473 .this_mv
10474 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10475 .comp_mv;
10476 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10477 xd->n8_h << MI_SIZE_LOG2, xd);
10478 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10479 }
10480#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010481 }
David Barker3dfba992017-04-03 16:10:09 +010010482#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010483
10484 cur_mv =
10485 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10486 .this_mv;
10487 clamp_mv2(&cur_mv.as_mv, xd);
10488
Alex Converse0fa0f422017-04-24 12:51:14 -070010489 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010490 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010491#if CONFIG_EXT_INTER
10492 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -080010493#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010494
10495 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010496 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010497
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010498 // Point to variables that are not maintained between iterations
10499 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010500#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010501 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010502 args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
10503 args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
10504 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010505#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010506 tmp_alt_rd = handle_inter_mode(
10507 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10508 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010509 // Prevent pointers from escaping local scope
10510 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010511#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010512 args.single_newmv_rate = NULL;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010513 args.compmode_interintra_cost = NULL;
10514 args.compmode_interinter_cost = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010515#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010516 }
10517
10518 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10519 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010520 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10521 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010522 tmp_rd_stats.rate +=
10523 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10524 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010525 }
10526
10527 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10528 mbmi->ref_mv_idx + idx_offset + 1 &&
10529 ref_idx < ref_set - 1) {
10530 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010531 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10532 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010533 tmp_rd_stats.rate +=
10534 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10535 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010536 }
10537
10538 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010539#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010540 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10541 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010542#else
Angie Chiang76159122016-11-09 12:13:22 -080010543 if (RDCOST(x->rdmult, x->rddiv,
10544 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10545 tmp_rd_stats.dist) <
10546 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010547 tmp_alt_rd =
10548 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010549 tmp_rd_stats.rate +
10550 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10551 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010552 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010553 tmp_alt_rd =
10554 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010555 tmp_rd_stats.rate +
10556 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10557 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10558 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010559#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010560 }
10561
10562 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010563 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010564 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010565 distortion2 = tmp_rd_stats.dist;
10566 skippable = tmp_rd_stats.skip;
10567 rate_y = tmp_rd_stats_y.rate;
10568 rate_uv = tmp_rd_stats_uv.rate;
10569 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010570 this_rd = tmp_alt_rd;
10571 tmp_ref_rd = tmp_alt_rd;
10572 backup_mbmi = *mbmi;
10573 backup_skip = x->skip;
10574#if CONFIG_VAR_TX
10575 for (i = 0; i < MAX_MB_PLANE; ++i)
10576 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10577 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010578#endif // CONFIG_VAR_TX
Yue Chen6e601e92016-12-05 18:19:00 -080010579#if CONFIG_EXT_INTER
10580 compmode_interintra_cost = tmp_compmode_interintra_cost;
10581 compmode_interinter_cost = tmp_compmode_interinter_cost;
Fergus Simpson4063a682017-02-28 16:52:22 -080010582#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010583 } else {
10584 *mbmi = backup_mbmi;
10585 x->skip = backup_skip;
10586 }
10587 }
10588
10589 frame_mv[NEARMV][ref_frame] = backup_mv;
10590 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10591 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10592#if CONFIG_VAR_TX
10593 for (i = 0; i < MAX_MB_PLANE; ++i)
10594 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10595 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010596#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010597 }
10598 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10599 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010600
10601 if (this_rd == INT64_MAX) continue;
10602
Jingning Hanc41a5492017-02-24 11:18:52 -080010603#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010604 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010605#else
10606 if (mbmi->sb_type >= BLOCK_8X8)
10607 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010608#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010609
10610 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10611 }
10612
10613#if CONFIG_EXT_INTER
10614 rate2 += compmode_interintra_cost;
10615 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010616#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10617 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10618#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010619 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010620#endif // CONFIG_EXT_INTER
10621
10622 // Estimate the reference frame signaling cost and add it
10623 // to the rolling cost variable.
10624 if (comp_pred) {
10625 rate2 += ref_costs_comp[ref_frame];
10626#if CONFIG_EXT_REFS
10627 rate2 += ref_costs_comp[second_ref_frame];
10628#endif // CONFIG_EXT_REFS
10629 } else {
10630 rate2 += ref_costs_single[ref_frame];
10631 }
10632
Yue Chen69f18e12016-09-08 14:48:15 -070010633#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010634 if (ref_frame == INTRA_FRAME) {
10635#else
10636 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010637#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010638 if (skippable) {
10639 // Back out the coefficient coding costs
10640 rate2 -= (rate_y + rate_uv);
10641 rate_y = 0;
10642 rate_uv = 0;
10643 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010644 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010645 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010646 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10647 distortion2) <
10648 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010649 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010650 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010651 } else {
10652 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010653 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010654 distortion2 = total_sse;
10655 assert(total_sse >= 0);
10656 rate2 -= (rate_y + rate_uv);
10657 this_skip2 = 1;
10658 rate_y = 0;
10659 rate_uv = 0;
10660 }
10661 } else {
10662 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010663 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010664 }
10665
10666 // Calculate the final RD estimate for this mode.
10667 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010668#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010669 } else {
10670 this_skip2 = mbmi->skip;
10671 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10672 if (this_skip2) {
10673 rate_y = 0;
10674 rate_uv = 0;
10675 }
Yue Chen69f18e12016-09-08 14:48:15 -070010676#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010677 }
10678
Yaowu Xuc27fc142016-08-22 16:08:15 -070010679 if (ref_frame == INTRA_FRAME) {
10680 // Keep record of best intra rd
10681 if (this_rd < best_intra_rd) {
10682 best_intra_rd = this_rd;
10683 best_intra_mode = mbmi->mode;
10684 }
10685#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -050010686 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010687 if (this_rd < best_single_inter_rd) {
10688 best_single_inter_rd = this_rd;
10689 best_single_inter_ref = mbmi->ref_frame[0];
10690 }
10691#endif // CONFIG_EXT_INTER
10692 }
10693
10694 if (!disable_skip && ref_frame == INTRA_FRAME) {
10695 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010696 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010697 }
10698
10699 // Did this mode help.. i.e. is it the new best mode
10700 if (this_rd < best_rd || x->skip) {
10701 if (!mode_excluded) {
10702 // Note index of best mode so far
10703 best_mode_index = mode_index;
10704
10705 if (ref_frame == INTRA_FRAME) {
10706 /* required for left and above block mv */
10707 mbmi->mv[0].as_int = 0;
10708 } else {
10709 best_pred_sse = x->pred_sse[ref_frame];
10710 }
10711
10712 rd_cost->rate = rate2;
10713#if CONFIG_SUPERTX
10714 if (x->skip)
10715 *returnrate_nocoef = rate2;
10716 else
10717 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010718 *returnrate_nocoef -= av1_cost_bit(
10719 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10720 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10721 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010722#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -070010723#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10724 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -080010725 const MOTION_MODE motion_allowed = motion_mode_allowed(
10726#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10727 0, xd->global_motion,
10728#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10729 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -080010730 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -070010731 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -080010732 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010733 *returnrate_nocoef -=
10734 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -070010735#else
10736 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010737#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010738#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010739#endif // CONFIG_SUPERTX
10740 rd_cost->dist = distortion2;
10741 rd_cost->rdcost = this_rd;
10742 best_rd = this_rd;
10743 best_mbmode = *mbmi;
10744 best_skip2 = this_skip2;
10745 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010746 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10747 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010748 best_rate_uv = rate_uv;
10749
10750#if CONFIG_VAR_TX
10751 for (i = 0; i < MAX_MB_PLANE; ++i)
10752 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10753 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010754#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010755 }
10756 }
10757
10758 /* keep record of best compound/single-only prediction */
10759 if (!disable_skip && ref_frame != INTRA_FRAME) {
10760 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10761
10762 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10763 single_rate = rate2 - compmode_cost;
10764 hybrid_rate = rate2;
10765 } else {
10766 single_rate = rate2;
10767 hybrid_rate = rate2 + compmode_cost;
10768 }
10769
10770 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10771 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10772
10773 if (!comp_pred) {
10774 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10775 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10776 } else {
10777 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10778 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10779 }
10780 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10781 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10782 }
10783
Yaowu Xuc27fc142016-08-22 16:08:15 -070010784 if (x->skip && !comp_pred) break;
10785 }
10786
10787 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10788 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10789 is_inter_mode(best_mbmode.mode)) ||
10790 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10791 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010792 int skip_blk = 0;
10793 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010794
10795 x->use_default_inter_tx_type = 0;
10796 x->use_default_intra_tx_type = 0;
10797
10798 *mbmi = best_mbmode;
10799
10800 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10801
10802 // Select prediction reference frames.
10803 for (i = 0; i < MAX_MB_PLANE; i++) {
10804 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10805 if (has_second_ref(mbmi))
10806 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10807 }
10808
10809 if (is_inter_mode(mbmi->mode)) {
Jingning Hanc44009c2017-05-06 11:36:49 -070010810 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -070010811#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010812 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -080010813 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010814 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10815 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010816 }
Yue Chencb60b182016-10-13 15:18:22 -070010817#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010818 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010819#if CONFIG_VAR_TX
10820 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010821 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010822 } else {
10823 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010824 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010825 for (idy = 0; idy < xd->n8_h; ++idy)
10826 for (idx = 0; idx < xd->n8_w; ++idx)
10827 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010828 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010829 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10830 }
10831
Angie Chiangb5dda482016-11-02 16:19:58 -070010832 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010833#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010834 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010835 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010836#endif // CONFIG_VAR_TX
10837 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010838 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010839 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010840 }
10841
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010842 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10843 (rd_stats_y.dist + rd_stats_uv.dist)) >
10844 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010845 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010846 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10847 rd_stats_uv.rate = 0;
10848 rd_stats_y.dist = rd_stats_y.sse;
10849 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010850 } else {
10851 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010852 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010853 }
10854
10855 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010856 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10857 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010858#if CONFIG_VAR_TX
10859 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080010860#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010861 best_mbmode.tx_type = mbmi->tx_type;
10862 best_mbmode.tx_size = mbmi->tx_size;
10863#if CONFIG_VAR_TX
10864 for (idy = 0; idy < xd->n8_h; ++idy)
10865 for (idx = 0; idx < xd->n8_w; ++idx)
10866 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
10867
10868 for (i = 0; i < MAX_MB_PLANE; ++i)
10869 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10870 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070010871
10872 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080010873#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010874 rd_cost->rate +=
10875 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
10876 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010877 rd_cost->rdcost =
10878 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
10879 best_skip2 = skip_blk;
10880 }
10881 }
10882
Urvang Joshib100db72016-10-12 16:28:56 -070010883#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010884 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -070010885 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010886 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010887#if CONFIG_SUPERTX
10888 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010889#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080010890 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10891 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010892 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010893 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010894 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010895 uint8_t *const best_palette_color_map =
10896 x->palette_buffer->best_palette_color_map;
10897 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010898 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010899
10900 mbmi->mode = DC_PRED;
10901 mbmi->uv_mode = DC_PRED;
10902 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010903 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010904 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010905 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10906 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10907 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010908 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10909 memcpy(color_map, best_palette_color_map,
10910 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010911 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10912 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010913 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10914 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010915 if (rate_uv_intra[uv_tx] == INT_MAX) {
10916 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010917 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10918 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010919 pmi_uv[uv_tx] = *pmi;
10920#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010921 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10922#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010923#if CONFIG_FILTER_INTRA
10924 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10925#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010926 }
10927 mbmi->uv_mode = mode_uv[uv_tx];
10928 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080010929 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010930 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10931 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10932 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080010933 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010934#if CONFIG_EXT_INTRA
10935 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010936#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010937#if CONFIG_FILTER_INTRA
10938 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10939 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10940 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10941 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10942 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10943 }
10944#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010945 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
10946 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
10947 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010948 rate2 += ref_costs_single[INTRA_FRAME];
10949
10950 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010951 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010952#if CONFIG_SUPERTX
10953 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080010954#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010955 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010956 } else {
10957#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010958 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080010959#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010960 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010961 }
10962 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10963 if (this_rd < best_rd) {
10964 best_mode_index = 3;
10965 mbmi->mv[0].as_int = 0;
10966 rd_cost->rate = rate2;
10967#if CONFIG_SUPERTX
10968 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010969#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010970 rd_cost->dist = distortion2;
10971 rd_cost->rdcost = this_rd;
10972 best_rd = this_rd;
10973 best_mbmode = *mbmi;
10974 best_skip2 = 0;
10975 best_mode_skippable = skippable;
10976 }
10977 }
10978PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070010979#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010980
hui su5db97432016-10-14 16:10:14 -070010981#if CONFIG_FILTER_INTRA
10982 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070010983 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070010984 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070010985#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080010986 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070010987#endif // CONFIG_PALETTE
10988 !dc_skipped && best_mode_index >= 0 &&
10989 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070010990 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080010991 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
10992 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070010993#if CONFIG_EXT_INTRA
10994 uv_angle_delta,
10995#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070010996#if CONFIG_PALETTE
10997 pmi_uv, palette_ctx,
10998#endif // CONFIG_PALETTE
10999 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011000 &best_mode_index, &best_skip2, &best_mode_skippable,
11001#if CONFIG_SUPERTX
11002 returnrate_nocoef,
11003#endif // CONFIG_SUPERTX
11004 best_pred_rd, &best_mbmode, rd_cost);
11005 }
hui su5db97432016-10-14 16:10:14 -070011006#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011007
11008 // The inter modes' rate costs are not calculated precisely in some cases.
11009 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11010 // ZEROMV. Here, checks are added for those cases, and the mode decisions
11011 // are corrected.
11012 if (best_mbmode.mode == NEWMV
11013#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070011014 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011015#endif // CONFIG_EXT_INTER
11016 ) {
11017 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11018 best_mbmode.ref_frame[1] };
11019 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011020 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070011021 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011022#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011023 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11024 cm->allow_high_precision_mv, bsize,
11025 mi_col, mi_row, 0)
11026 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011027 zeromv[1].as_int = comp_pred_mode
11028 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11029 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011030 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011031 .as_int
11032 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011033#else
11034 zeromv[0].as_int = 0;
11035 zeromv[1].as_int = 0;
11036#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011037 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011038 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011039 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011040 : INT_MAX;
11041
11042 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11043 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11044 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11045 best_mbmode.mode = NEARMV;
11046 best_mbmode.ref_mv_idx = i;
11047 }
11048 }
11049
11050 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11051 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011052 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011053 best_mbmode.mode = ZEROMV;
11054 } else {
11055 int_mv nearestmv[2];
11056 int_mv nearmv[2];
11057
11058#if CONFIG_EXT_INTER
11059 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11060 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11061 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11062 } else {
11063 nearmv[0] = frame_mv[NEARMV][refs[0]];
11064 nearmv[1] = frame_mv[NEARMV][refs[1]];
11065 }
11066#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011067 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011068 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011069 : INT_MAX;
11070
11071 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11072 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11073 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11074
11075 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11076 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11077 best_mbmode.mode = NEARMV;
11078 best_mbmode.ref_mv_idx = i;
11079 }
11080 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011081#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011082 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11083 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11084 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11085 } else {
11086 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11087 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11088 }
11089
11090 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011091 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011092#if CONFIG_EXT_INTER
11093 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011094 } else {
11095 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
11096 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
11097 : INT_MAX;
11098
11099 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11100 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11101 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11102
David Barker3dfba992017-04-03 16:10:09 +010011103 // Try switching to the NEAR_NEAREST type modes first
11104 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011105 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
David Barker3dfba992017-04-03 16:10:09 +010011106 best_mbmode.mode = NEAREST_NEARMV;
11107 best_mbmode.ref_mv_idx = i;
11108 } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11109 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
11110 best_mbmode.mode = NEAR_NEARESTMV;
11111 best_mbmode.ref_mv_idx = i;
11112 } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11113 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
David Barker404b2e82017-03-27 13:07:47 +010011114 best_mbmode.mode = NEAR_NEARMV;
11115 best_mbmode.ref_mv_idx = i;
11116 }
11117 }
11118
David Barker3dfba992017-04-03 16:10:09 +010011119 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010011120 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11121 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11122 best_mbmode.mode = ZERO_ZEROMV;
11123 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011124#else
11125 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011126 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11127 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011128 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010011129 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011130#endif // CONFIG_EXT_INTER
11131 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011132 }
11133
David Barker9620bcd2017-03-22 14:46:42 +000011134 // Make sure that the ref_mv_idx is only nonzero when we're
11135 // using a mode which can support ref_mv_idx
11136 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010011137#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010011138 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
11139 have_nearmv_in_inter_mode(best_mbmode.mode))) {
David Barker404b2e82017-03-27 13:07:47 +010011140#else
David Barker9620bcd2017-03-22 14:46:42 +000011141 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
David Barker404b2e82017-03-27 13:07:47 +010011142#endif
David Barker9620bcd2017-03-22 14:46:42 +000011143 best_mbmode.ref_mv_idx = 0;
11144 }
11145
David Barkercdcac6d2016-12-01 17:04:16 +000011146 {
Jingning Han731af492016-11-17 11:53:23 -080011147 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11148 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011149 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011150 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011151#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011152 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11153 best_mbmode.ref_frame[1] };
11154 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011155 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011156 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011157 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070011158 zeromv[1].as_int = (refs[1] != NONE_FRAME)
11159 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11160 cm->allow_high_precision_mv,
11161 bsize, mi_col, mi_row, 0)
11162 .as_int
11163 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000011164 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11165 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11166#else
11167 zeromv[0].as_int = zeromv[1].as_int = 0;
11168#endif // CONFIG_GLOBAL_MOTION
11169 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11170 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11171#if CONFIG_EXT_INTER
11172 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11173#else
Emil Keyder01770b32017-01-20 18:03:11 -050011174 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011175 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11176#endif // CONFIG_EXT_INTER
11177 ) {
11178 best_mbmode.mode = ZEROMV;
11179 }
David Barker68e6e862016-11-24 15:10:15 +000011180 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011181 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011182
11183 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11184 rd_cost->rate = INT_MAX;
11185 rd_cost->rdcost = INT64_MAX;
11186 return;
11187 }
11188
Yaowu Xuc27fc142016-08-22 16:08:15 -070011189#if CONFIG_DUAL_FILTER
11190 assert((cm->interp_filter == SWITCHABLE) ||
11191 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11192 !is_inter_block(&best_mbmode));
11193 assert((cm->interp_filter == SWITCHABLE) ||
11194 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11195 !is_inter_block(&best_mbmode));
11196 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11197 assert((cm->interp_filter == SWITCHABLE) ||
11198 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11199 !is_inter_block(&best_mbmode));
11200 assert((cm->interp_filter == SWITCHABLE) ||
11201 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11202 !is_inter_block(&best_mbmode));
11203 }
11204#else
11205 assert((cm->interp_filter == SWITCHABLE) ||
11206 (cm->interp_filter == best_mbmode.interp_filter) ||
11207 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011208#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011209
11210 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011211 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11212 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011213
11214 // macroblock modes
11215 *mbmi = best_mbmode;
11216 x->skip |= best_skip2;
11217
Yue Chen19e7aa82016-11-30 14:05:39 -080011218// Note: this section is needed since the mode may have been forced to
11219// ZEROMV by the all-zero mode handling of ref-mv.
11220#if CONFIG_GLOBAL_MOTION
11221 if (mbmi->mode == ZEROMV
11222#if CONFIG_EXT_INTER
11223 || mbmi->mode == ZERO_ZEROMV
11224#endif // CONFIG_EXT_INTER
11225 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011226#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11227 // Correct the motion mode for ZEROMV
11228 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11229#if SEPARATE_GLOBAL_MOTION
11230 0, xd->global_motion,
11231#endif // SEPARATE_GLOBAL_MOTION
11232 xd->mi[0]);
11233 if (mbmi->motion_mode > last_motion_mode_allowed)
11234 mbmi->motion_mode = last_motion_mode_allowed;
11235#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11236
11237 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011238 if (is_nontrans_global_motion(xd)) {
11239#if CONFIG_DUAL_FILTER
11240 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11241 ? EIGHTTAP_REGULAR
11242 : cm->interp_filter;
11243 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11244 ? EIGHTTAP_REGULAR
11245 : cm->interp_filter;
11246#else
11247 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11248 : cm->interp_filter;
11249#endif // CONFIG_DUAL_FILTER
11250 }
11251 }
11252#endif // CONFIG_GLOBAL_MOTION
11253
Yaowu Xuc27fc142016-08-22 16:08:15 -070011254 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11255 if (mbmi->mode != NEWMV)
11256 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11257 else
11258 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11259 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011260
11261 for (i = 0; i < REFERENCE_MODES; ++i) {
11262 if (best_pred_rd[i] == INT64_MAX)
11263 best_pred_diff[i] = INT_MIN;
11264 else
11265 best_pred_diff[i] = best_rd - best_pred_rd[i];
11266 }
11267
11268 x->skip |= best_mode_skippable;
11269
11270 assert(best_mode_index >= 0);
11271
11272 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11273 best_mode_skippable);
11274
Urvang Joshib100db72016-10-12 16:28:56 -070011275#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011276 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11277 restore_uv_color_map(cpi, x);
11278 }
Urvang Joshib100db72016-10-12 16:28:56 -070011279#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011280}
11281
Urvang Joshi52648442016-10-13 17:27:51 -070011282void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11283 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011284 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011285 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011286 PICK_MODE_CONTEXT *ctx,
11287 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011288 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011289 MACROBLOCKD *const xd = &x->e_mbd;
11290 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11291 unsigned char segment_id = mbmi->segment_id;
11292 const int comp_pred = 0;
11293 int i;
11294 int64_t best_pred_diff[REFERENCE_MODES];
11295 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11296 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011297 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011298 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011299 int64_t this_rd = INT64_MAX;
11300 int rate2 = 0;
11301 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011302 (void)mi_row;
11303 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011304
11305 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11306 &comp_mode_p);
11307
11308 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11309 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11310 x->pred_mv_sad[i] = INT_MAX;
11311
11312 rd_cost->rate = INT_MAX;
11313
11314 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11315
Urvang Joshib100db72016-10-12 16:28:56 -070011316#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011317 mbmi->palette_mode_info.palette_size[0] = 0;
11318 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011319#endif // CONFIG_PALETTE
11320
hui su5db97432016-10-14 16:10:14 -070011321#if CONFIG_FILTER_INTRA
11322 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11323 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11324#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011325 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011326 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011327 mbmi->uv_mode = DC_PRED;
11328 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011329 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011330#if CONFIG_GLOBAL_MOTION
11331 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011332 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011333 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11334 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011335 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011336#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011337 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011338#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011339 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011340 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011341
Yaowu Xuc27fc142016-08-22 16:08:15 -070011342 mbmi->ref_mv_idx = 0;
11343 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011344
Yue Chendead17d2017-04-20 16:19:39 -070011345 mbmi->motion_mode = SIMPLE_TRANSLATION;
11346#if CONFIG_MOTION_VAR
11347 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
11348#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070011349#if CONFIG_WARPED_MOTION
11350 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
11351 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
11352 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
11353 }
11354#endif
Yue Chendead17d2017-04-20 16:19:39 -070011355
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011356 set_default_interp_filters(mbmi, cm->interp_filter);
11357
11358 if (cm->interp_filter != SWITCHABLE) {
11359 best_filter = cm->interp_filter;
11360 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011361 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011362 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011363 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11364 int rs;
11365 int best_rs = INT_MAX;
11366 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11367#if CONFIG_DUAL_FILTER
11368 int k;
11369 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11370#else
11371 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011372#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011373 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011374 if (rs < best_rs) {
11375 best_rs = rs;
11376#if CONFIG_DUAL_FILTER
11377 best_filter = mbmi->interp_filter[0];
11378#else
11379 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011380#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011381 }
11382 }
11383 }
11384 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011385// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070011386#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011387 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011388#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011389 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011390#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011391 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011392
11393 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011394 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011395
11396 // Estimate the reference frame signaling cost and add it
11397 // to the rolling cost variable.
11398 rate2 += ref_costs_single[LAST_FRAME];
11399 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11400
11401 rd_cost->rate = rate2;
11402 rd_cost->dist = distortion2;
11403 rd_cost->rdcost = this_rd;
11404
11405 if (this_rd >= best_rd_so_far) {
11406 rd_cost->rate = INT_MAX;
11407 rd_cost->rdcost = INT64_MAX;
11408 return;
11409 }
11410
11411#if CONFIG_DUAL_FILTER
11412 assert((cm->interp_filter == SWITCHABLE) ||
11413 (cm->interp_filter == mbmi->interp_filter[0]));
11414#else
11415 assert((cm->interp_filter == SWITCHABLE) ||
11416 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011417#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011418
Yaowu Xuf883b422016-08-30 14:01:10 -070011419 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11420 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011421
Yaowu Xuf883b422016-08-30 14:01:10 -070011422 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011423
11424 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11425}
11426
Urvang Joshi52648442016-10-13 17:27:51 -070011427void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11428 TileDataEnc *tile_data, struct macroblock *x,
11429 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011430 struct RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011431#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011432 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011433#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011434 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11435 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011436 const AV1_COMMON *const cm = &cpi->common;
11437 const RD_OPT *const rd_opt = &cpi->rd;
11438 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011439 MACROBLOCKD *const xd = &x->e_mbd;
11440 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11441 const struct segmentation *const seg = &cm->seg;
11442 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11443 unsigned char segment_id = mbmi->segment_id;
11444 int comp_pred, i;
11445 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11446 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11447 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11448 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011449 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011450#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011451 AOM_LAST2_FLAG,
11452 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011453#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011454 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011455#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011456 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011457#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011458 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011459 };
11460 int64_t best_rd = best_rd_so_far;
11461 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11462 int64_t best_pred_diff[REFERENCE_MODES];
11463 int64_t best_pred_rd[REFERENCE_MODES];
11464 MB_MODE_INFO best_mbmode;
11465 int ref_index, best_ref_index = 0;
11466 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11467 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011468 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011469#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011470 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011471#else
James Zern7b9407a2016-05-18 23:48:05 -070011472 InterpFilter tmp_best_filter = SWITCHABLE;
Fergus Simpson4063a682017-02-28 16:52:22 -080011473#endif // CONFIG_DUAL_FILTER
Jingning Han3f167252016-06-07 16:11:42 -070011474 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11475 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011476 int skip_uv;
11477 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011478 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011479 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011480 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011481 b_mode_info best_bmodes[4];
11482 int best_skip2 = 0;
11483 int ref_frame_skip_mask[2] = { 0 };
11484 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011485 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011486#if CONFIG_PVQ
11487 od_rollback_buffer pre_buf;
11488
11489 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011490#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070011491
11492#if CONFIG_SUPERTX
11493 best_rd_so_far = INT64_MAX;
11494 best_rd = best_rd_so_far;
11495 best_yrd = best_rd_so_far;
11496#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011497 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011498
hui su5db97432016-10-14 16:10:14 -070011499#if CONFIG_FILTER_INTRA
11500 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11501 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11502#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011503 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011504#if CONFIG_EXT_INTER
Sarah Parker2d0e9b72017-05-04 01:34:16 +000011505 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011506 mbmi->use_wedge_interintra = 0;
11507#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011508#if CONFIG_WARPED_MOTION
11509 mbmi->num_proj_ref[0] = 0;
11510 mbmi->num_proj_ref[1] = 0;
11511#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011512
11513 for (i = 0; i < 4; i++) {
11514 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011515 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11516 seg_mvs[i][j].as_int = INVALID_MV;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011517 }
11518
11519 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11520 &comp_mode_p);
11521
11522 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11523 rate_uv_intra = INT_MAX;
11524
11525 rd_cost->rate = INT_MAX;
11526#if CONFIG_SUPERTX
11527 *returnrate_nocoef = INT_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -080011528#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011529
11530 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11531 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011532#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011533 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011534#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011535 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11536 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11537 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11538 } else {
11539 ref_frame_skip_mask[0] |= (1 << ref_frame);
11540 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11541 }
11542 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11543#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011544#endif // CONFIG_EXT_INTER
11545 frame_mv[ZEROMV][ref_frame].as_int = 0;
11546 }
11547
Urvang Joshib100db72016-10-12 16:28:56 -070011548#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011549 mbmi->palette_mode_info.palette_size[0] = 0;
11550 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011551#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011552
11553 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11554 int mode_excluded = 0;
11555 int64_t this_rd = INT64_MAX;
11556 int disable_skip = 0;
11557 int compmode_cost = 0;
11558 int rate2 = 0, rate_y = 0, rate_uv = 0;
11559 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11560 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011561 int this_skip2 = 0;
11562 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011563
Yushin Cho77bba8d2016-11-04 16:36:56 -070011564#if CONFIG_PVQ
11565 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011566#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -070011567
Yaowu Xuf883b422016-08-30 14:01:10 -070011568 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11569 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011570
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011571 mbmi->ref_mv_idx = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011572
Yaowu Xuc27fc142016-08-22 16:08:15 -070011573 // Look at the reference frame of the best mode so far and set the
11574 // skip mask to look at a subset of the remaining modes.
11575 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11576 if (ref_index == 3) {
11577 switch (best_mbmode.ref_frame[0]) {
11578 case INTRA_FRAME: break;
11579 case LAST_FRAME:
11580 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11581#if CONFIG_EXT_REFS
11582 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11583 (1 << BWDREF_FRAME) |
11584#endif // CONFIG_EXT_REFS
11585 (1 << ALTREF_FRAME);
11586 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11587 break;
11588#if CONFIG_EXT_REFS
11589 case LAST2_FRAME:
11590 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11591 (1 << GOLDEN_FRAME) |
11592 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11593 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11594 break;
11595 case LAST3_FRAME:
11596 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11597 (1 << GOLDEN_FRAME) |
11598 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11599 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11600 break;
11601#endif // CONFIG_EXT_REFS
11602 case GOLDEN_FRAME:
11603 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11604#if CONFIG_EXT_REFS
11605 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11606 (1 << BWDREF_FRAME) |
11607#endif // CONFIG_EXT_REFS
11608 (1 << ALTREF_FRAME);
11609 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11610 break;
11611#if CONFIG_EXT_REFS
11612 case BWDREF_FRAME:
11613 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11614 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11615 (1 << ALTREF_FRAME);
11616 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11617 break;
11618#endif // CONFIG_EXT_REFS
11619 case ALTREF_FRAME:
11620 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11621#if CONFIG_EXT_REFS
11622 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11623 (1 << BWDREF_FRAME) |
11624#endif // CONFIG_EXT_REFS
11625 (1 << GOLDEN_FRAME);
11626#if CONFIG_EXT_REFS
11627 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11628#endif // CONFIG_EXT_REFS
11629 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011630 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011631 case TOTAL_REFS_PER_FRAME:
11632 assert(0 && "Invalid Reference frame");
11633 break;
11634 }
11635 }
11636 }
11637
11638 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011639 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011640 continue;
11641
11642 // Test best rd so far against threshold for trying this mode.
11643 if (!internal_active_edge &&
11644 rd_less_than_thresh(best_rd,
11645 rd_opt->threshes[segment_id][bsize][ref_index],
11646 tile_data->thresh_freq_fact[bsize][ref_index]))
11647 continue;
11648
Yunqing Wangff4fa062017-04-21 10:56:08 -070011649 // This is only used in motion vector unit test.
11650 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
11651
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020011652#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
11653#if CONFIG_EXT_REFS
11654 if (cpi->oxcf.pass == 0) {
11655 // Complexity-compression trade-offs
11656 // if (ref_frame == ALTREF_FRAME) continue;
11657 // if (ref_frame == BWDREF_FRAME) continue;
11658 if (second_ref_frame == ALTREF_FRAME) continue;
11659 // if (second_ref_frame == BWDREF_FRAME) continue;
11660 }
11661#endif
11662#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011663 comp_pred = second_ref_frame > INTRA_FRAME;
11664 if (comp_pred) {
11665 if (!cpi->allow_comp_inter_inter) continue;
11666 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11667 // Do not allow compound prediction if the segment level reference frame
11668 // feature is in use as in this case there can only be one reference.
11669 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11670
11671 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11672 best_mbmode.ref_frame[0] == INTRA_FRAME)
11673 continue;
11674 }
11675
11676 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11677 // sub8x8 blocks.
11678 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011679 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011680 continue;
11681
11682 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011683 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011684 continue;
11685
11686 if (comp_pred)
11687 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11688 else if (ref_frame != INTRA_FRAME)
11689 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11690
11691 // If the segment reference frame feature is enabled....
11692 // then do nothing if the current ref frame is not allowed..
11693 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11694 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11695 continue;
11696 // Disable this drop out case if the ref frame
11697 // segment level feature is enabled for this segment. This is to
11698 // prevent the possibility that we end up unable to pick any mode.
11699 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11700 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11701 // unless ARNR filtering is enabled in which case we want
11702 // an unfiltered alternative. We allow near/nearest as well
11703 // because they may result in zero-zero MVs but be cheaper.
11704 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11705 continue;
11706 }
11707
11708 mbmi->tx_size = TX_4X4;
11709 mbmi->uv_mode = DC_PRED;
11710 mbmi->ref_frame[0] = ref_frame;
11711 mbmi->ref_frame[1] = second_ref_frame;
11712// Evaluate all sub-pel filters irrespective of whether we can use
11713// them for this frame.
11714#if CONFIG_DUAL_FILTER
11715 for (i = 0; i < 4; ++i)
11716 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11717 ? EIGHTTAP_REGULAR
11718 : cm->interp_filter;
11719#else
11720 mbmi->interp_filter =
11721 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011722#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011723 x->skip = 0;
11724 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11725
11726 // Select prediction reference frames.
11727 for (i = 0; i < MAX_MB_PLANE; i++) {
11728 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11729 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11730 }
11731
11732#if CONFIG_VAR_TX
11733 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011734 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -080011735#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011736
11737 if (ref_frame == INTRA_FRAME) {
11738 int rate;
11739 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011740 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011741 continue;
11742 rate2 += rate;
11743 rate2 += intra_cost_penalty;
11744 distortion2 += distortion_y;
11745
11746 if (rate_uv_intra == INT_MAX) {
11747 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11748 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11749 }
11750 rate2 += rate_uv_intra;
11751 rate_uv = rate_uv_tokenonly;
11752 distortion2 += dist_uv;
11753 distortion_uv = dist_uv;
11754 mbmi->uv_mode = mode_uv;
11755 } else {
11756 int rate;
11757 int64_t distortion;
11758 int64_t this_rd_thresh;
11759 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11760 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11761 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11762 int tmp_best_skippable = 0;
11763 int switchable_filter_index;
11764 int_mv *second_ref =
11765 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11766 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11767 MB_MODE_INFO tmp_best_mbmode;
11768#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011769 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011770#else
11771 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
Fergus Simpson4063a682017-02-28 16:52:22 -080011772#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011773 int pred_exists = 0;
11774 int uv_skippable;
11775#if CONFIG_EXT_INTER
11776 int_mv compound_seg_newmvs[4][2];
11777 for (i = 0; i < 4; i++) {
11778 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11779 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11780 }
11781#endif // CONFIG_EXT_INTER
11782
11783 this_rd_thresh = (ref_frame == LAST_FRAME)
11784 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11785 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11786#if CONFIG_EXT_REFS
11787 this_rd_thresh = (ref_frame == LAST2_FRAME)
11788 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11789 : this_rd_thresh;
11790 this_rd_thresh = (ref_frame == LAST3_FRAME)
11791 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11792 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011793 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11794 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11795 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011796#endif // CONFIG_EXT_REFS
11797 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11798 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11799 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011800
11801 // TODO(any): Add search of the tx_type to improve rd performance at the
11802 // expense of speed.
11803 mbmi->tx_type = DCT_DCT;
11804
11805 if (cm->interp_filter != BILINEAR) {
11806#if CONFIG_DUAL_FILTER
11807 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11808 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11809 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11810 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11811#else
11812 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011813#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011814 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11815#if CONFIG_DUAL_FILTER
11816 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11817#else
11818 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011819#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011820 } else if (sf->adaptive_pred_interp_filter == 1 &&
11821 ctx->pred_interp_filter < SWITCHABLE) {
11822#if CONFIG_DUAL_FILTER
11823 tmp_best_filter[0] = ctx->pred_interp_filter;
11824#else
11825 tmp_best_filter = ctx->pred_interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011826#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011827 } else if (sf->adaptive_pred_interp_filter == 2) {
11828#if CONFIG_DUAL_FILTER
11829 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
11830 ? ctx->pred_interp_filter
11831 : 0;
11832#else
11833 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
11834 ? ctx->pred_interp_filter
11835 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011836#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011837 } else {
11838#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011839 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011840#else
Angie Chiang5678ad92016-11-21 09:38:40 -080011841 const int filter_set_size = SWITCHABLE_FILTERS;
Fergus Simpson4063a682017-02-28 16:52:22 -080011842#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011843 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080011844 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011845 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011846 int newbest, rs;
11847 int64_t rs_rd;
11848 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
11849#if CONFIG_DUAL_FILTER
11850 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
11851 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
11852 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
11853 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
11854#else
11855 mbmi->interp_filter = switchable_filter_index;
Fergus Simpson4063a682017-02-28 16:52:22 -080011856#endif // CONFIG_DUAL_FILTER
Yushin Cho482016d2017-01-06 14:06:13 -080011857 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011858 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11859 &rate, &rate_y, &distortion, &skippable, &total_sse,
11860 (int)this_rd_thresh, seg_mvs,
11861#if CONFIG_EXT_INTER
11862 compound_seg_newmvs,
11863#endif // CONFIG_EXT_INTER
11864 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011865 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070011866 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011867 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
11868 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
11869
11870 newbest = (tmp_rd < tmp_best_rd);
11871 if (newbest) {
11872#if CONFIG_DUAL_FILTER
11873 tmp_best_filter[0] = mbmi->interp_filter[0];
11874 tmp_best_filter[1] = mbmi->interp_filter[1];
11875 tmp_best_filter[2] = mbmi->interp_filter[2];
11876 tmp_best_filter[3] = mbmi->interp_filter[3];
11877#else
11878 tmp_best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011879#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011880 tmp_best_rd = tmp_rd;
11881 }
11882 if ((newbest && cm->interp_filter == SWITCHABLE) ||
11883 (
11884#if CONFIG_DUAL_FILTER
11885 mbmi->interp_filter[0] == cm->interp_filter
11886#else
11887 mbmi->interp_filter == cm->interp_filter
Fergus Simpson4063a682017-02-28 16:52:22 -080011888#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011889 && cm->interp_filter != SWITCHABLE)) {
11890 tmp_best_rdu = tmp_rd;
11891 tmp_best_rate = rate;
11892 tmp_best_ratey = rate_y;
11893 tmp_best_distortion = distortion;
11894 tmp_best_sse = total_sse;
11895 tmp_best_skippable = skippable;
11896 tmp_best_mbmode = *mbmi;
11897 for (i = 0; i < 4; i++) {
11898 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
11899 }
11900 pred_exists = 1;
11901 }
11902 } // switchable_filter_index loop
11903 }
11904 }
11905
11906 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
11907
11908#if CONFIG_DUAL_FILTER
11909 mbmi->interp_filter[0] =
11910 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
11911 : cm->interp_filter);
11912 mbmi->interp_filter[1] =
11913 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
11914 : cm->interp_filter);
11915 mbmi->interp_filter[2] =
11916 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
11917 : cm->interp_filter);
11918 mbmi->interp_filter[3] =
11919 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
11920 : cm->interp_filter);
11921#else
11922 mbmi->interp_filter =
11923 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
11924 : cm->interp_filter);
Fergus Simpson4063a682017-02-28 16:52:22 -080011925#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011926
11927 if (!pred_exists) {
11928 // Handles the special case when a filter that is not in the
11929 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080011930 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011931 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11932 &rate, &rate_y, &distortion, &skippable, &total_sse,
11933 (int)this_rd_thresh, seg_mvs,
11934#if CONFIG_EXT_INTER
11935 compound_seg_newmvs,
11936#endif // CONFIG_EXT_INTER
11937 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011938 if (tmp_rd == INT64_MAX) continue;
11939 } else {
11940 total_sse = tmp_best_sse;
11941 rate = tmp_best_rate;
11942 rate_y = tmp_best_ratey;
11943 distortion = tmp_best_distortion;
11944 skippable = tmp_best_skippable;
11945 *mbmi = tmp_best_mbmode;
11946 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
11947 }
11948 // Add in the cost of the transform type
11949 if (!xd->lossless[mbmi->segment_id]) {
11950 int rate_tx_type = 0;
11951#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080011952 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
11953 1) {
11954 const int eset =
11955 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011956 rate_tx_type =
11957 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
11958 }
11959#else
11960 if (mbmi->tx_size < TX_32X32) {
11961 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
11962 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011963#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011964 rate += rate_tx_type;
11965 rate_y += rate_tx_type;
11966 }
11967
11968 rate2 += rate;
11969 distortion2 += distortion;
11970
11971 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070011972 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011973
11974 if (!mode_excluded)
11975 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
11976 : cm->reference_mode == COMPOUND_REFERENCE;
11977
Yaowu Xuf883b422016-08-30 14:01:10 -070011978 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011979
11980 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070011981 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011982 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
11983
11984 if (tmp_best_rdu > 0) {
11985 // If even the 'Y' rd value of split is higher than best so far
11986 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070011987 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070011988 RD_STATS rd_stats_uv;
Jingning Hanc44009c2017-05-06 11:36:49 -070011989 av1_build_inter_predictors_sbuv(cm, &x->e_mbd, mi_row, mi_col, NULL,
David Barkerac37fa32016-12-02 12:30:21 +000011990 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011991#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070011992 is_cost_valid_uv =
11993 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080011994#else
11995 is_cost_valid_uv =
11996 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Fergus Simpson4063a682017-02-28 16:52:22 -080011997#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070011998 rate_uv = rd_stats_uv.rate;
11999 distortion_uv = rd_stats_uv.dist;
12000 uv_skippable = rd_stats_uv.skip;
12001 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080012002
Angie Chiangb5dda482016-11-02 16:19:58 -070012003 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012004 rate2 += rate_uv;
12005 distortion2 += distortion_uv;
12006 skippable = skippable && uv_skippable;
12007 total_sse += uv_sse;
12008 } else {
12009 continue;
12010 }
12011 }
12012
12013 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
12014
12015 // Estimate the reference frame signaling cost and add it
12016 // to the rolling cost variable.
12017 if (second_ref_frame > INTRA_FRAME) {
12018 rate2 += ref_costs_comp[ref_frame];
12019#if CONFIG_EXT_REFS
12020 rate2 += ref_costs_comp[second_ref_frame];
12021#endif // CONFIG_EXT_REFS
12022 } else {
12023 rate2 += ref_costs_single[ref_frame];
12024 }
12025
12026 if (!disable_skip) {
12027 // Skip is never coded at the segment level for sub8x8 blocks and instead
12028 // always coded in the bitstream at the mode info level.
12029
12030 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
12031 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
12032 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
12033 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012034 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012035 } else {
12036 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070012037 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012038 distortion2 = total_sse;
12039 assert(total_sse >= 0);
12040 rate2 -= (rate_y + rate_uv);
12041 rate_y = 0;
12042 rate_uv = 0;
12043 this_skip2 = 1;
12044 }
12045 } else {
12046 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012047 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012048 }
12049
12050 // Calculate the final RD estimate for this mode.
12051 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
12052 }
12053
12054 if (!disable_skip && ref_frame == INTRA_FRAME) {
12055 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070012056 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012057 }
12058
12059 // Did this mode help.. i.e. is it the new best mode
12060 if (this_rd < best_rd || x->skip) {
12061 if (!mode_excluded) {
12062 // Note index of best mode so far
12063 best_ref_index = ref_index;
12064
12065 if (ref_frame == INTRA_FRAME) {
12066 /* required for left and above block mv */
12067 mbmi->mv[0].as_int = 0;
12068 }
12069
12070 rd_cost->rate = rate2;
12071#if CONFIG_SUPERTX
12072 *returnrate_nocoef = rate2 - rate_y - rate_uv;
12073 if (!disable_skip)
12074 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070012075 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
12076 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
12077 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012078 assert(*returnrate_nocoef > 0);
12079#endif // CONFIG_SUPERTX
12080 rd_cost->dist = distortion2;
12081 rd_cost->rdcost = this_rd;
12082 best_rd = this_rd;
12083 best_yrd =
12084 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
12085 best_mbmode = *mbmi;
12086 best_skip2 = this_skip2;
12087
12088#if CONFIG_VAR_TX
12089 for (i = 0; i < MAX_MB_PLANE; ++i)
12090 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080012091#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012092
12093 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070012094 }
12095 }
12096
12097 /* keep record of best compound/single-only prediction */
12098 if (!disable_skip && ref_frame != INTRA_FRAME) {
12099 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
12100
12101 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
12102 single_rate = rate2 - compmode_cost;
12103 hybrid_rate = rate2;
12104 } else {
12105 single_rate = rate2;
12106 hybrid_rate = rate2 + compmode_cost;
12107 }
12108
12109 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
12110 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
12111
12112 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
12113 best_pred_rd[SINGLE_REFERENCE] = single_rd;
12114 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
12115 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
12116
12117 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
12118 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
12119 }
12120
Yaowu Xuc27fc142016-08-22 16:08:15 -070012121 if (x->skip && !comp_pred) break;
12122 }
12123
12124 if (best_rd >= best_rd_so_far) {
12125 rd_cost->rate = INT_MAX;
12126 rd_cost->rdcost = INT64_MAX;
12127#if CONFIG_SUPERTX
12128 *returnrate_nocoef = INT_MAX;
12129#endif // CONFIG_SUPERTX
12130 return;
12131 }
12132
Yaowu Xuc27fc142016-08-22 16:08:15 -070012133 if (best_rd == INT64_MAX) {
12134 rd_cost->rate = INT_MAX;
12135 rd_cost->dist = INT64_MAX;
12136 rd_cost->rdcost = INT64_MAX;
12137#if CONFIG_SUPERTX
12138 *returnrate_nocoef = INT_MAX;
12139#endif // CONFIG_SUPERTX
12140 return;
12141 }
12142
12143#if CONFIG_DUAL_FILTER
12144 assert((cm->interp_filter == SWITCHABLE) ||
12145 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12146 !is_inter_block(&best_mbmode));
12147#else
12148 assert((cm->interp_filter == SWITCHABLE) ||
12149 (cm->interp_filter == best_mbmode.interp_filter) ||
12150 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080012151#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012152
Yaowu Xuf883b422016-08-30 14:01:10 -070012153 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12154 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012155
12156 // macroblock modes
12157 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012158#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012159 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080012160#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012161
12162 x->skip |= best_skip2;
12163 if (!is_inter_block(&best_mbmode)) {
12164 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12165 } else {
12166 for (i = 0; i < 4; ++i)
12167 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12168
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012169 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12170 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012171 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12172 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012173 }
12174
Yue Chen19e7aa82016-11-30 14:05:39 -080012175// Note: this section is needed since the mode may have been forced to ZEROMV
12176#if CONFIG_GLOBAL_MOTION
12177 if (mbmi->mode == ZEROMV
12178#if CONFIG_EXT_INTER
12179 || mbmi->mode == ZERO_ZEROMV
12180#endif // CONFIG_EXT_INTER
12181 ) {
12182 if (is_nontrans_global_motion(xd)) {
12183#if CONFIG_DUAL_FILTER
12184 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12185 ? EIGHTTAP_REGULAR
12186 : cm->interp_filter;
12187 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12188 ? EIGHTTAP_REGULAR
12189 : cm->interp_filter;
12190#else
12191 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12192 : cm->interp_filter;
12193#endif // CONFIG_DUAL_FILTER
12194 }
12195 }
12196#endif // CONFIG_GLOBAL_MOTION
12197
Yaowu Xuc27fc142016-08-22 16:08:15 -070012198 for (i = 0; i < REFERENCE_MODES; ++i) {
12199 if (best_pred_rd[i] == INT64_MAX)
12200 best_pred_diff[i] = INT_MIN;
12201 else
12202 best_pred_diff[i] = best_rd - best_pred_rd[i];
12203 }
12204
12205 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12206}
12207
Yue Chencb60b182016-10-13 15:18:22 -070012208#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012209// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012210//
12211// The OBMC predictor is computed as:
12212//
12213// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012214// AOM_BLEND_A64(Mh(x),
12215// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012216// PLeft(x, y))
12217//
Yaowu Xuf883b422016-08-30 14:01:10 -070012218// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012219// rounding, this can be written as:
12220//
Yaowu Xuf883b422016-08-30 14:01:10 -070012221// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012222// Mh(x) * Mv(y) * P(x,y) +
12223// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012224// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012225//
12226// Where :
12227//
Yaowu Xuf883b422016-08-30 14:01:10 -070012228// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12229// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012230//
12231// This function computes 'wsrc' and 'mask' as:
12232//
12233// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012234// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012235// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012236// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012237//
12238// mask(x, y) = Mh(x) * Mv(y)
12239//
12240// These can then be used to efficiently approximate the error for any
12241// predictor P in the context of the provided neighbouring predictors by
12242// computing:
12243//
12244// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012245// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012246//
Yaowu Xuf883b422016-08-30 14:01:10 -070012247static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012248 const MACROBLOCKD *xd, int mi_row,
12249 int mi_col, const uint8_t *above,
12250 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012251 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012252 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12253 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012254 const int bw = xd->n8_w << MI_SIZE_LOG2;
12255 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012256 int32_t *mask_buf = x->mask_buf;
12257 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012258 const int wsrc_stride = bw;
12259 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012260 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012261#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012262 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12263#else
12264 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012265#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012266
12267 // plane 0 should not be subsampled
12268 assert(xd->plane[0].subsampling_x == 0);
12269 assert(xd->plane[0].subsampling_y == 0);
12270
Yaowu Xuf883b422016-08-30 14:01:10 -070012271 av1_zero_array(wsrc_buf, bw * bh);
12272 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012273
12274 // handle above row
12275 if (xd->up_available) {
12276 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012277 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012278 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012279 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012280 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
12281 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012282
12283 assert(miw > 0);
12284
12285 i = 0;
12286 do { // for each mi in the above row
12287 const int mi_col_offset = i;
12288 const MB_MODE_INFO *const above_mbmi =
12289 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012290 const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012291 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012292 const int neighbor_bw = mi_step * MI_SIZE;
12293
12294 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012295 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
12296 neighbor_count += 2;
12297 else
12298 neighbor_count++;
12299 if (neighbor_count > neighbor_limit) break;
12300
Yaowu Xuc27fc142016-08-22 16:08:15 -070012301 const int tmp_stride = above_stride;
12302 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12303 int32_t *mask = mask_buf + (i * MI_SIZE);
12304
12305 if (!is_hbd) {
12306 const uint8_t *tmp = above;
12307
12308 for (row = 0; row < overlap; ++row) {
12309 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012310 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012311 for (col = 0; col < neighbor_bw; ++col) {
12312 wsrc[col] = m1 * tmp[col];
12313 mask[col] = m0;
12314 }
12315 wsrc += wsrc_stride;
12316 mask += mask_stride;
12317 tmp += tmp_stride;
12318 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012319#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012320 } else {
12321 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12322
12323 for (row = 0; row < overlap; ++row) {
12324 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012325 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012326 for (col = 0; col < neighbor_bw; ++col) {
12327 wsrc[col] = m1 * tmp[col];
12328 mask[col] = m0;
12329 }
12330 wsrc += wsrc_stride;
12331 mask += mask_stride;
12332 tmp += tmp_stride;
12333 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012334#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012335 }
12336 }
12337
12338 above += neighbor_bw;
12339 i += mi_step;
12340 } while (i < miw);
12341 }
12342
12343 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012344 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12345 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012346 }
12347
12348 // handle left column
12349 if (xd->left_available) {
12350 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012351 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012352 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012353 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012354 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
12355 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012356
12357 assert(mih > 0);
12358
12359 i = 0;
12360 do { // for each mi in the left column
12361 const int mi_row_offset = i;
12362 const MB_MODE_INFO *const left_mbmi =
12363 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012364 const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012365 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012366 const int neighbor_bh = mi_step * MI_SIZE;
12367
12368 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012369 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
12370 neighbor_count += 2;
12371 else
12372 neighbor_count++;
12373 if (neighbor_count > neighbor_limit) break;
12374
Yaowu Xuc27fc142016-08-22 16:08:15 -070012375 const int tmp_stride = left_stride;
12376 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12377 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12378
12379 if (!is_hbd) {
12380 const uint8_t *tmp = left;
12381
12382 for (row = 0; row < neighbor_bh; ++row) {
12383 for (col = 0; col < overlap; ++col) {
12384 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012385 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12386 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12387 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12388 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012389 }
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(left);
12397
12398 for (row = 0; row < neighbor_bh; ++row) {
12399 for (col = 0; col < overlap; ++col) {
12400 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012401 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12402 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12403 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12404 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012405 }
12406 wsrc += wsrc_stride;
12407 mask += mask_stride;
12408 tmp += tmp_stride;
12409 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012410#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012411 }
12412 }
12413
12414 left += neighbor_bh * left_stride;
12415 i += mi_step;
12416 } while (i < mih);
12417 }
12418
12419 if (!is_hbd) {
12420 const uint8_t *src = x->plane[0].src.buf;
12421
12422 for (row = 0; row < bh; ++row) {
12423 for (col = 0; col < bw; ++col) {
12424 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12425 }
12426 wsrc_buf += wsrc_stride;
12427 src += x->plane[0].src.stride;
12428 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012429#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012430 } else {
12431 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12432
12433 for (row = 0; row < bh; ++row) {
12434 for (col = 0; col < bw; ++col) {
12435 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12436 }
12437 wsrc_buf += wsrc_stride;
12438 src += x->plane[0].src.stride;
12439 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012440#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012441 }
12442}
Yue Chenf27b1602017-01-13 11:11:43 -080012443
12444#if CONFIG_NCOBMC
12445void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12446 int mi_row, int mi_col) {
12447 const AV1_COMMON *const cm = &cpi->common;
12448 MACROBLOCKD *const xd = &x->e_mbd;
12449 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12450 MB_MODE_INFO backup_mbmi;
12451 BLOCK_SIZE bsize = mbmi->sb_type;
12452 int ref, skip_blk, backup_skip = x->skip;
12453 int64_t rd_causal;
12454 RD_STATS rd_stats_y, rd_stats_uv;
12455 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12456 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12457
12458 // Recompute the best causal predictor and rd
12459 mbmi->motion_mode = SIMPLE_TRANSLATION;
12460 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12461 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12462 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12463 assert(cfg != NULL);
12464 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12465 &xd->block_refs[ref]->sf);
12466 }
Jingning Han91d9a792017-04-18 12:01:52 -070012467 av1_setup_dst_planes(x->e_mbd.plane, bsize,
12468 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080012469
Jingning Hanc44009c2017-05-06 11:36:49 -070012470 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chenf27b1602017-01-13 11:11:43 -080012471
12472 av1_subtract_plane(x, bsize, 0);
12473 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12474 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12475 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12476 if (rd_stats_y.skip && rd_stats_uv.skip) {
12477 rd_stats_y.rate = rate_skip1;
12478 rd_stats_uv.rate = 0;
12479 rd_stats_y.dist = rd_stats_y.sse;
12480 rd_stats_uv.dist = rd_stats_uv.sse;
12481 skip_blk = 0;
12482 } else if (RDCOST(x->rdmult, x->rddiv,
12483 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12484 (rd_stats_y.dist + rd_stats_uv.dist)) >
12485 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12486 (rd_stats_y.sse + rd_stats_uv.sse))) {
12487 rd_stats_y.rate = rate_skip1;
12488 rd_stats_uv.rate = 0;
12489 rd_stats_y.dist = rd_stats_y.sse;
12490 rd_stats_uv.dist = rd_stats_uv.sse;
12491 skip_blk = 1;
12492 } else {
12493 rd_stats_y.rate += rate_skip0;
12494 skip_blk = 0;
12495 }
12496 backup_skip = skip_blk;
12497 backup_mbmi = *mbmi;
12498 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12499 (rd_stats_y.dist + rd_stats_uv.dist));
12500 rd_causal += RDCOST(x->rdmult, x->rddiv,
12501 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12502
12503 // Check non-causal mode
12504 mbmi->motion_mode = OBMC_CAUSAL;
12505 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12506
12507 av1_subtract_plane(x, bsize, 0);
12508 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12509 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12510 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12511 if (rd_stats_y.skip && rd_stats_uv.skip) {
12512 rd_stats_y.rate = rate_skip1;
12513 rd_stats_uv.rate = 0;
12514 rd_stats_y.dist = rd_stats_y.sse;
12515 rd_stats_uv.dist = rd_stats_uv.sse;
12516 skip_blk = 0;
12517 } else if (RDCOST(x->rdmult, x->rddiv,
12518 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12519 (rd_stats_y.dist + rd_stats_uv.dist)) >
12520 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12521 (rd_stats_y.sse + rd_stats_uv.sse))) {
12522 rd_stats_y.rate = rate_skip1;
12523 rd_stats_uv.rate = 0;
12524 rd_stats_y.dist = rd_stats_y.sse;
12525 rd_stats_uv.dist = rd_stats_uv.sse;
12526 skip_blk = 1;
12527 } else {
12528 rd_stats_y.rate += rate_skip0;
12529 skip_blk = 0;
12530 }
12531
12532 if (rd_causal >
12533 RDCOST(x->rdmult, x->rddiv,
12534 rd_stats_y.rate + rd_stats_uv.rate +
12535 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12536 (rd_stats_y.dist + rd_stats_uv.dist))) {
12537 x->skip = skip_blk;
12538 } else {
12539 *mbmi = backup_mbmi;
12540 x->skip = backup_skip;
12541 }
12542}
Fergus Simpson4063a682017-02-28 16:52:22 -080012543#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070012544#endif // CONFIG_MOTION_VAR