blob: abe1b01ff9e7d63fe267a6054f974bc42f620325 [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;
2341 RD_STATS this_rd_stats;
2342 int row, col;
2343 int64_t temp_sse, this_rd;
2344 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2345 const int stepr = tx_size_high_unit[tx_size];
2346 const int stepc = tx_size_wide_unit[tx_size];
2347 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2348 const int max_blocks_high = max_block_high(xd, bsize, 0);
2349 mbmi->tx_size = tx_size;
2350 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002351 const int step = stepr * stepc;
2352 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002353 for (row = 0; row < max_blocks_high; row += stepr) {
2354 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002355#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09002356 const struct macroblockd_plane *const pd = &xd->plane[0];
2357 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
2358 av1_predict_intra_block_encoder_facade(x, 0, block, col, row, tx_size,
2359 plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04002360#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002361 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002362#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002363 block += step;
hui su308a6392017-01-12 14:49:57 -08002364 }
2365 }
2366 // RD estimation.
2367 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2368 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002369#if CONFIG_EXT_INTRA
2370 if (av1_is_directional_mode(mbmi->mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002371 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2372 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002373 }
2374#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002375#if CONFIG_FILTER_INTRA
2376 if (mbmi->mode == DC_PRED) {
2377 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2378 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2379 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2380 mode_cost += (av1_cost_bit(prob, 1) +
2381 write_uniform_cost(FILTER_INTRA_MODES, mode));
2382 } else {
2383 mode_cost += av1_cost_bit(prob, 0);
2384 }
2385 }
2386#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002387 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2388 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002389 return this_rd;
2390}
2391
Urvang Joshib100db72016-10-12 16:28:56 -07002392#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002393// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2394// new_height'. Extra rows and columns are filled in by copying last valid
2395// row/column.
2396static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2397 int orig_height, int new_width,
2398 int new_height) {
2399 int j;
2400 assert(new_width >= orig_width);
2401 assert(new_height >= orig_height);
2402 if (new_width == orig_width && new_height == orig_height) return;
2403
2404 for (j = orig_height - 1; j >= 0; --j) {
2405 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2406 // Copy last column to extra columns.
2407 memset(color_map + j * new_width + orig_width,
2408 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2409 }
2410 // Copy last row to extra rows.
2411 for (j = orig_height; j < new_height; ++j) {
2412 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2413 new_width);
2414 }
2415}
2416
hui sude0c70a2017-01-09 17:12:17 -08002417static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2418 BLOCK_SIZE bsize, int palette_ctx,
2419 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2420 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002421 int64_t *best_rd, int64_t *best_model_rd,
2422 int *rate, int *rate_tokenonly,
2423 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002424 int rate_overhead = 0;
2425 MACROBLOCKD *const xd = &x->e_mbd;
2426 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002427 MB_MODE_INFO *const mbmi = &mic->mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002428 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002429 const int src_stride = x->plane[0].src.stride;
2430 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002431 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002432 int block_width, block_height, rows, cols;
2433 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2434 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435
2436 assert(cpi->common.allow_screen_content_tools);
2437
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002438#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002439 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002440 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2441 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002442 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002443#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002444 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002445#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002446 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002447#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448
2449 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002450 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002451 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002452 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002453 float *const data = x->palette_buffer->kmeans_data_buf;
2454 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002455 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002456 RD_STATS tokenonly_rd_stats;
2457 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002458 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002459#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2461 if (cpi->common.use_highbitdepth)
2462 lb = ub = src16[0];
2463 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002464#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002465 lb = ub = src[0];
2466
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002467#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002468 if (cpi->common.use_highbitdepth) {
2469 for (r = 0; r < rows; ++r) {
2470 for (c = 0; c < cols; ++c) {
2471 val = src16[r * src_stride + c];
2472 data[r * cols + c] = val;
2473 if (val < lb)
2474 lb = val;
2475 else if (val > ub)
2476 ub = val;
2477 }
2478 }
2479 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002480#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002481 for (r = 0; r < rows; ++r) {
2482 for (c = 0; c < cols; ++c) {
2483 val = src[r * src_stride + c];
2484 data[r * cols + c] = val;
2485 if (val < lb)
2486 lb = val;
2487 else if (val > ub)
2488 ub = val;
2489 }
2490 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002491#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002492 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002493#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494
2495 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002496#if CONFIG_FILTER_INTRA
2497 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2498#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002499
2500 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2501
2502 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2503 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002504 if (colors == PALETTE_MIN_SIZE) {
2505 // Special case: These colors automatically become the centroids.
2506 assert(colors == n);
2507 assert(colors == 2);
2508 centroids[0] = lb;
2509 centroids[1] = ub;
2510 k = 2;
2511 } else {
2512 for (i = 0; i < n; ++i) {
2513 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2514 }
2515 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
2516 k = av1_remove_duplicates(centroids, n);
2517 if (k < PALETTE_MIN_SIZE) {
2518 // Too few unique colors to create a palette. And DC_PRED will work
2519 // well for that case anyway. So skip.
2520 continue;
2521 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002522 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002523
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002524#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002525 if (cpi->common.use_highbitdepth)
2526 for (i = 0; i < k; ++i)
2527 pmi->palette_colors[i] =
2528 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2529 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002530#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002531 for (i = 0; i < k; ++i)
2532 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2533 pmi->palette_size[0] = k;
2534
Yaowu Xuf883b422016-08-30 14:01:10 -07002535 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002536 extend_palette_color_map(color_map, cols, rows, block_width,
2537 block_height);
hui su78c611a2017-01-13 17:06:04 -08002538 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002539 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002540 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002542 av1_cost_bit(
2543 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002544 1);
hui sud13c24a2017-04-07 16:13:07 -07002545 palette_mode_cost += av1_palette_color_cost_y(pmi, cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 for (i = 0; i < rows; ++i) {
2547 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002548 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002549 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002550 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002551 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002552 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2553 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002554 }
2555 }
hui su78c611a2017-01-13 17:06:04 -08002556 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2557 if (*best_model_rd != INT64_MAX &&
2558 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2559 continue;
2560 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2561 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2562 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2563 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002564 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002565 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002566 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002567 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002568 if (this_rd < *best_rd) {
2569 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002571 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002572 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002573 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002574 if (rate) *rate = this_rate;
2575 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2576 if (distortion) *distortion = tokenonly_rd_stats.dist;
2577 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578 }
2579 }
2580 }
hui sude0c70a2017-01-09 17:12:17 -08002581
2582 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2583 memcpy(color_map, best_palette_color_map,
2584 rows * cols * sizeof(best_palette_color_map[0]));
2585 }
2586 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002587 return rate_overhead;
2588}
Urvang Joshib100db72016-10-12 16:28:56 -07002589#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590
Urvang Joshifeb925f2016-12-05 10:37:29 -08002591static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002592 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2593 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2594 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002595 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002596 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002597 PREDICTION_MODE mode;
2598 MACROBLOCKD *const xd = &x->e_mbd;
2599 int64_t best_rd = rd_thresh;
2600 struct macroblock_plane *p = &x->plane[0];
2601 struct macroblockd_plane *pd = &xd->plane[0];
2602 const int src_stride = p->src.stride;
2603 const int dst_stride = pd->dst.stride;
2604 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002605 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Jingning Han276c2942016-12-05 12:37:02 -08002606#if CONFIG_CB4X4
2607 // TODO(jingning): This is a temporal change. The whole function should be
2608 // out when cb4x4 is enabled.
2609 ENTROPY_CONTEXT ta[4], tempa[4];
2610 ENTROPY_CONTEXT tl[4], templ[4];
2611#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002612 ENTROPY_CONTEXT ta[2], tempa[2];
2613 ENTROPY_CONTEXT tl[2], templ[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08002614#endif // CONFIG_CB4X4
Urvang Joshifeb925f2016-12-05 10:37:29 -08002615
2616 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2617 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2618 const int tx_width_unit = tx_size_wide_unit[tx_size];
2619 const int tx_height_unit = tx_size_high_unit[tx_size];
2620 const int pred_block_width = block_size_wide[bsize];
2621 const int pred_block_height = block_size_high[bsize];
2622 const int tx_width = tx_size_wide[tx_size];
2623 const int tx_height = tx_size_high[tx_size];
2624 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2625 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002626 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002627 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002628 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002629#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002630 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002631#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002632 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2633#if CONFIG_EXT_TX && CONFIG_RECT_TX
2634 const int sub_bsize = bsize;
2635#else
2636 const int sub_bsize = BLOCK_4X4;
2637#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002638
Yushin Cho77bba8d2016-11-04 16:36:56 -07002639#if CONFIG_PVQ
2640 od_rollback_buffer pre_buf, post_buf;
2641 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2642 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002643#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002644
Urvang Joshifeb925f2016-12-05 10:37:29 -08002645 assert(bsize < BLOCK_8X8);
2646 assert(tx_width < 8 || tx_height < 8);
2647#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002648 if (is_lossless)
2649 assert(tx_width == 4 && tx_height == 4);
2650 else
2651 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002652#else
2653 assert(tx_width == 4 && tx_height == 4);
2654#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2655
2656 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2657 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2658
2659 xd->mi[0]->mbmi.tx_size = tx_size;
2660
Urvang Joshib100db72016-10-12 16:28:56 -07002661#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002662 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002663#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002664
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002665#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002666 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002667#if CONFIG_PVQ
2668 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2669#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002670 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2671 int64_t this_rd;
2672 int ratey = 0;
2673 int64_t distortion = 0;
2674 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002675 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002676
Urvang Joshifeb925f2016-12-05 10:37:29 -08002677 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2678 (1 << mode)))
2679 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002680
2681 // Only do the oblique modes if the best so far is
2682 // one of the neighboring directional modes
2683 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2684 if (conditional_skipintra(mode, *best_mode)) continue;
2685 }
2686
Urvang Joshifeb925f2016-12-05 10:37:29 -08002687 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2688 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002689
Urvang Joshifeb925f2016-12-05 10:37:29 -08002690 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2691 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2692 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2693 const int block =
2694 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002695 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2696 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08002697#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002698 int16_t *const src_diff = av1_raster_block_offset_int16(
2699 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002700#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002701 int skip;
2702 assert(block < 4);
2703 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2704 idx == 0 && idy == 0));
2705 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2706 block == 0 || block == 2));
2707 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002708 av1_predict_intra_block(
2709 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2710 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002711#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002712 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2713 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002714#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002715 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07002716 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002717 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002718 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002719 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002720#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002721 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002722 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07002723 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002724 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002725 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002726 skip = (p->eobs[block] == 0);
2727 can_skip &= skip;
2728 tempa[idx] = !skip;
2729 templ[idy] = !skip;
2730#if CONFIG_EXT_TX
2731 if (tx_size == TX_8X4) {
2732 tempa[idx + 1] = tempa[idx];
2733 } else if (tx_size == TX_4X8) {
2734 templ[idy + 1] = templ[idy];
2735 }
2736#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002737#else
2738 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002739
Thomas Daede6ff6af62017-02-03 16:29:24 -08002740 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2741 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
2742
2743 ratey += x->rate;
2744 skip = x->pvq_skip[0];
2745 tempa[idx] = !skip;
2746 templ[idy] = !skip;
2747 can_skip &= skip;
2748#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002749 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2750 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08002751#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002752 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002753#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002754 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2755 DCT_DCT, tx_size, dst, dst_stride,
2756 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757 } else {
2758 int64_t dist;
2759 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07002760 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002761 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002763 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002764#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002765 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002766 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002767 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07002768 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002769 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002770 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002771 skip = (p->eobs[block] == 0);
2772 can_skip &= skip;
2773 tempa[idx] = !skip;
2774 templ[idy] = !skip;
2775#if CONFIG_EXT_TX
2776 if (tx_size == TX_8X4) {
2777 tempa[idx + 1] = tempa[idx];
2778 } else if (tx_size == TX_4X8) {
2779 templ[idy + 1] = templ[idy];
2780 }
2781#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002782#else
2783 (void)scan_order;
2784
2785 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2786 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2787 ratey += x->rate;
2788 skip = x->pvq_skip[0];
2789 tempa[idx] = !skip;
2790 templ[idy] = !skip;
2791 can_skip &= skip;
2792#endif
2793#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002794 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002795#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002796 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2797 tx_type, tx_size, dst, dst_stride,
2798 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002799 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002800 dist = (int64_t)tmp << 4;
2801 distortion += dist;
2802 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2803 goto next_highbd;
2804 }
2805 }
2806 }
2807
2808 rate += ratey;
2809 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2810
2811 if (this_rd < best_rd) {
2812 *bestrate = rate;
2813 *bestratey = ratey;
2814 *bestdistortion = distortion;
2815 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002816 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002817 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002818 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2819 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08002820#if CONFIG_PVQ
2821 od_encode_checkpoint(&x->daala_enc, &post_buf);
2822#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002823 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002824 memcpy(best_dst16 + idy * 8,
2825 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002826 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 }
2828 }
2829 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08002830#if CONFIG_PVQ
2831 od_encode_rollback(&x->daala_enc, &pre_buf);
2832#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002833 }
2834
2835 if (best_rd >= rd_thresh) return best_rd;
2836
Thomas Daede6ff6af62017-02-03 16:29:24 -08002837#if CONFIG_PVQ
2838 od_encode_rollback(&x->daala_enc, &post_buf);
2839#endif
2840
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002841 if (y_skip) *y_skip &= best_can_skip;
2842
Urvang Joshifeb925f2016-12-05 10:37:29 -08002843 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002845 best_dst16 + idy * 8,
2846 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847 }
2848
2849 return best_rd;
2850 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002851#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852
Yushin Cho77bba8d2016-11-04 16:36:56 -07002853#if CONFIG_PVQ
2854 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002855#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002856
Yaowu Xuc27fc142016-08-22 16:08:15 -07002857 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2858 int64_t this_rd;
2859 int ratey = 0;
2860 int64_t distortion = 0;
2861 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002862 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002863
Urvang Joshifeb925f2016-12-05 10:37:29 -08002864 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2865 (1 << mode))) {
2866 continue;
2867 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002868
2869 // Only do the oblique modes if the best so far is
2870 // one of the neighboring directional modes
2871 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2872 if (conditional_skipintra(mode, *best_mode)) continue;
2873 }
2874
Urvang Joshifeb925f2016-12-05 10:37:29 -08002875 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2876 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877
Urvang Joshifeb925f2016-12-05 10:37:29 -08002878 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2879 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2880 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2881 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2883 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002884#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002885 int16_t *const src_diff = av1_raster_block_offset_int16(
2886 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08002887#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002888 int skip;
2889 assert(block < 4);
2890 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2891 idx == 0 && idy == 0));
2892 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2893 block == 0 || block == 2));
2894 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002895 av1_predict_intra_block(xd, pd->width, pd->height,
2896 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2897 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002898#if CONFIG_CB4X4
2899 2 * (col + idx), 2 * (row + idy),
2900#else
2901 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002902#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002903 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002904#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002905 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2906 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002907#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002908
Urvang Joshi14731732017-04-27 18:40:49 -07002909 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
2910 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
2911 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002912#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002913 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002914#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002915#if !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002916 const AV1_XFORM_QUANT xform_quant =
2917 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
2918 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08002919#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002920 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08002921#else
Urvang Joshi14731732017-04-27 18:40:49 -07002922 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002923#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002924 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08002925
Angie Chiang7dec6c42017-05-03 17:58:17 -07002926 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Urvang Joshi14731732017-04-27 18:40:49 -07002927
2928 ratey +=
2929 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
2930 templ + idy, cpi->sf.use_fast_coef_costing);
2931 skip = (p->eobs[block] == 0);
2932 can_skip &= skip;
2933 tempa[idx] = !skip;
2934 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002935#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07002936 if (tx_size == TX_8X4) {
2937 tempa[idx + 1] = tempa[idx];
2938 } else if (tx_size == TX_4X8) {
2939 templ[idy + 1] = templ[idy];
2940 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08002941#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002942#else
Urvang Joshi14731732017-04-27 18:40:49 -07002943 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08002944
Urvang Joshi14731732017-04-27 18:40:49 -07002945 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08002946#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002947 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08002948#else
Urvang Joshi14731732017-04-27 18:40:49 -07002949 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002950#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002951 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2952
2953 ratey += x->rate;
2954 skip = x->pvq_skip[0];
2955 tempa[idx] = !skip;
2956 templ[idy] = !skip;
2957 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002958#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002959
2960 if (!is_lossless) { // To use the pixel domain distortion, we need to
2961 // calculate inverse txfm *before* calculating RD
2962 // cost. Compared to calculating the distortion in
2963 // the frequency domain, the overhead of encoding
2964 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08002965#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002966 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08002967#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002968 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2969 tx_type, tx_size, dst, dst_stride,
2970 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07002971 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002972 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07002973 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002974 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07002975 }
2976
2977 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2978 goto next;
2979
2980 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
2981#if CONFIG_PVQ
2982 if (!skip)
2983#endif // CONFIG_PVQ
2984 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2985 DCT_DCT, tx_size, dst, dst_stride,
2986 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987 }
2988 }
2989 }
2990
2991 rate += ratey;
2992 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2993
2994 if (this_rd < best_rd) {
2995 *bestrate = rate;
2996 *bestratey = ratey;
2997 *bestdistortion = distortion;
2998 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002999 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003000 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003001 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3002 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003003#if CONFIG_PVQ
3004 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003005#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003006 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003007 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003008 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003009 }
3010 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003011#if CONFIG_PVQ
3012 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003013#endif // CONFIG_PVQ
3014 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003015
3016 if (best_rd >= rd_thresh) return best_rd;
3017
Yushin Cho77bba8d2016-11-04 16:36:56 -07003018#if CONFIG_PVQ
3019 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003020#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003021
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003022 if (y_skip) *y_skip &= best_can_skip;
3023
Urvang Joshifeb925f2016-12-05 10:37:29 -08003024 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003025 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003026 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003027
3028 return best_rd;
3029}
3030
Urvang Joshi52648442016-10-13 17:27:51 -07003031static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3032 MACROBLOCK *mb, int *rate,
3033 int *rate_y, int64_t *distortion,
3034 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003035 const MACROBLOCKD *const xd = &mb->e_mbd;
3036 MODE_INFO *const mic = xd->mi[0];
3037 const MODE_INFO *above_mi = xd->above_mi;
3038 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003039 MB_MODE_INFO *const mbmi = &mic->mbmi;
3040 const BLOCK_SIZE bsize = mbmi->sb_type;
3041 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3042 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043 int idx, idy;
3044 int cost = 0;
3045 int64_t total_distortion = 0;
3046 int tot_rate_y = 0;
3047 int64_t total_rd = 0;
3048 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003049 const int is_lossless = xd->lossless[mbmi->segment_id];
3050#if CONFIG_EXT_TX && CONFIG_RECT_TX
3051 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3052#else
3053 const TX_SIZE tx_size = TX_4X4;
3054#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055
3056#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003057#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003058 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003059#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003060#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003061#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003062 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003063#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003064
3065 // TODO(any): Add search of the tx_type to improve rd performance at the
3066 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003067 mbmi->tx_type = DCT_DCT;
3068 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003070 if (y_skip) *y_skip = 1;
3071
Urvang Joshifeb925f2016-12-05 10:37:29 -08003072 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3073 // 8x8 coding block.
3074 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3075 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003076 PREDICTION_MODE best_mode = DC_PRED;
3077 int r = INT_MAX, ry = INT_MAX;
3078 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003079 int j;
3080 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003082 const PREDICTION_MODE A =
3083 av1_above_block_mode(mic, above_mi, pred_block_idx);
3084 const PREDICTION_MODE L =
3085 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003086
3087 bmode_costs = cpi->y_mode_costs[A][L];
3088 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003089 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003090 cpi, mb, idy, idx, &best_mode, bmode_costs,
3091 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003092 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003093#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003094 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003095#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003096 total_rd += this_rd;
3097 cost += r;
3098 total_distortion += d;
3099 tot_rate_y += ry;
3100
Urvang Joshifeb925f2016-12-05 10:37:29 -08003101 mic->bmi[pred_block_idx].as_mode = best_mode;
3102 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3103 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3104 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3105 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003106
3107 if (total_rd >= best_rd) return INT64_MAX;
3108 }
3109 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003110 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003111
Yushin Cho7a428ba2017-01-12 16:28:49 -08003112#if CONFIG_DAALA_DIST
3113 {
3114 const struct macroblock_plane *p = &mb->plane[0];
3115 const struct macroblockd_plane *pd = &xd->plane[0];
3116 const int src_stride = p->src.stride;
3117 const int dst_stride = pd->dst.stride;
3118 uint8_t *src = p->src.buf;
3119 uint8_t *dst = pd->dst.buf;
3120 int use_activity_masking = 0;
3121 int qm = OD_HVS_QM;
3122
3123#if CONFIG_PVQ
3124 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003125#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003126 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho4483e3d2017-04-18 19:41:20 -07003127 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8,
Yushin Cho7a428ba2017-01-12 16:28:49 -08003128 qm, use_activity_masking, mb->qindex)
3129 << 4;
3130 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003131#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003132 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003133 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003134 int rate_tx_type = 0;
3135#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003136 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3137 1) {
3138 const int eset =
3139 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003140 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3141 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003142 }
3143#else
clang-format67948d32016-09-07 22:40:40 -07003144 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003145 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3146 [intra_mode_to_tx_type_context[mbmi->mode]]
3147 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003148#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003149 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003150 cost += rate_tx_type;
3151 tot_rate_y += rate_tx_type;
3152 }
3153
3154 *rate = cost;
3155 *rate_y = tot_rate_y;
3156 *distortion = total_distortion;
3157
3158 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3159}
3160
hui su5db97432016-10-14 16:10:14 -07003161#if CONFIG_FILTER_INTRA
3162// Return 1 if an filter intra mode is selected; return 0 otherwise.
3163static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3164 int *rate, int *rate_tokenonly,
3165 int64_t *distortion, int *skippable,
3166 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003167 int64_t *best_rd, int64_t *best_model_rd,
3168 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003169 MACROBLOCKD *const xd = &x->e_mbd;
3170 MODE_INFO *const mic = xd->mi[0];
3171 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003172 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003173 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003174 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003175 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003176 TX_TYPE best_tx_type;
3177
hui su5db97432016-10-14 16:10:14 -07003178 av1_zero(filter_intra_mode_info);
3179 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003181#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003182 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003183#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003184
3185 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003186 int this_rate;
3187 int64_t this_rd, this_model_rd;
3188 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003189 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003190 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003191 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3192 if (*best_model_rd != INT64_MAX &&
3193 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3194 continue;
3195 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003196 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3197 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003198 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003199 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003200 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003201 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003202
3203 if (this_rd < *best_rd) {
3204 *best_rd = this_rd;
3205 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003206 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003207 best_tx_type = mic->mbmi.tx_type;
3208 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003209 *rate_tokenonly = tokenonly_rd_stats.rate;
3210 *distortion = tokenonly_rd_stats.dist;
3211 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003212 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003213 }
3214 }
3215
hui su5db97432016-10-14 16:10:14 -07003216 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003217 mbmi->mode = DC_PRED;
3218 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003219 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3220 filter_intra_mode_info.use_filter_intra_mode[0];
3221 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3222 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003223 mbmi->tx_type = best_tx_type;
3224 return 1;
3225 } else {
3226 return 0;
3227 }
3228}
hui su5db97432016-10-14 16:10:14 -07003229#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003230
hui su5db97432016-10-14 16:10:14 -07003231#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003232// Run RD calculation with given luma intra prediction angle., and return
3233// the RD cost. Update the best mode info. if the RD cost is the best so far.
3234static int64_t calc_rd_given_intra_angle(
3235 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3236 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3237 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3238 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003239#if CONFIG_INTRA_INTERP
3240 INTRA_FILTER *best_filter,
3241#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003242 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003243 int this_rate;
3244 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003245 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003246 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003247
hui su45dc5972016-12-08 17:42:50 -08003248 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003249 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3250 if (*best_model_rd != INT64_MAX &&
3251 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3252 return INT64_MAX;
3253 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003254 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3255 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3256
3257 this_rate = tokenonly_rd_stats.rate + mode_cost +
3258 write_uniform_cost(2 * max_angle_delta + 1,
3259 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003260 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003261
3262 if (this_rd < *best_rd) {
3263 *best_rd = this_rd;
3264 *best_angle_delta = mbmi->angle_delta[0];
3265 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003266#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003267 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003268#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003269 *best_tx_type = mbmi->tx_type;
3270 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003271 rd_stats->rate = tokenonly_rd_stats.rate;
3272 rd_stats->dist = tokenonly_rd_stats.dist;
3273 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003274 }
hui su45dc5972016-12-08 17:42:50 -08003275 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003276}
3277
hui su45dc5972016-12-08 17:42:50 -08003278// With given luma directional intra prediction mode, pick the best angle delta
3279// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003280static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003281 int *rate, RD_STATS *rd_stats,
3282 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003283 int64_t best_rd,
3284 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003285 MACROBLOCKD *const xd = &x->e_mbd;
3286 MODE_INFO *const mic = xd->mi[0];
3287 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su45dc5972016-12-08 17:42:50 -08003288 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003289 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003290#if CONFIG_INTRA_INTERP
3291 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003292 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003293 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003294#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003295 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003296 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3297 TX_TYPE best_tx_type = mbmi->tx_type;
3298
hui su0a6731f2017-04-26 15:23:47 -07003299 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003300
hui su0a6731f2017-04-26 15:23:47 -07003301 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003302#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003303 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3304 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3305 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003306#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003307 for (i = 0; i < 2; ++i) {
3308 best_rd_in = (best_rd == INT64_MAX)
3309 ? INT64_MAX
3310 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3311 this_rd = calc_rd_given_intra_angle(
3312 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003313#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003314 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003315#else
hui su45dc5972016-12-08 17:42:50 -08003316 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003317#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003318 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003319 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003320#if CONFIG_INTRA_INTERP
3321 &best_filter,
3322#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003323 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003324 rd_cost[2 * angle_delta + i] = this_rd;
3325 if (first_try && this_rd == INT64_MAX) return best_rd;
3326 first_try = 0;
3327 if (angle_delta == 0) {
3328 rd_cost[1] = this_rd;
3329 break;
3330 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003331 }
hui su45dc5972016-12-08 17:42:50 -08003332#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003333 }
hui su45dc5972016-12-08 17:42:50 -08003334#endif // CONFIG_INTRA_INTERP
3335 }
3336
3337 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003338 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003339 int64_t rd_thresh;
3340#if CONFIG_INTRA_INTERP
3341 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3342 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3343 mic->mbmi.intra_filter = filter;
3344#endif // CONFIG_INTRA_INTERP
3345 for (i = 0; i < 2; ++i) {
3346 int skip_search = 0;
3347 rd_thresh = best_rd + (best_rd >> 5);
3348 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3349 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3350 skip_search = 1;
3351 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003352 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003353 cpi, x, bsize,
3354#if CONFIG_INTRA_INTERP
3355 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3356#else
3357 mode_cost,
3358#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003359 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003360 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3361#if CONFIG_INTRA_INTERP
3362 &best_filter,
3363#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003364 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003365 }
3366 }
3367#if CONFIG_INTRA_INTERP
3368 }
3369#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003370 }
3371
hui sueda3d762016-12-06 16:58:23 -08003372#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003373 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003374 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003375 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3377 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003378 this_rd = calc_rd_given_intra_angle(
3379 cpi, x, bsize,
3380 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003381 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003382 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003383 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003384 }
3385 }
3386 }
hui sueda3d762016-12-06 16:58:23 -08003387#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003388
3389 mbmi->tx_size = best_tx_size;
3390 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003391#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003392 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003393#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003394 mbmi->tx_type = best_tx_type;
3395 return best_rd;
3396}
3397
3398// Indices are sign, integer, and fractional part of the gradient value
3399static const uint8_t gradient_to_angle_bin[2][7][16] = {
3400 {
3401 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3402 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3403 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3404 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3405 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3406 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3407 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3408 },
3409 {
3410 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3411 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3412 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3413 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3414 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3415 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3416 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3417 },
3418};
3419
3420static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3421 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003422#if CONFIG_ALT_INTRA
3423 0,
3424#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003425};
3426
3427static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003428 int cols, BLOCK_SIZE bsize,
3429 uint8_t *directional_mode_skip_mask) {
3430 memset(directional_mode_skip_mask, 0,
3431 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3432 // Sub-8x8 blocks do not use extra directions.
3433 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003434 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003435 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3436 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003437 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003438 for (r = 1; r < rows; ++r) {
3439 for (c = 1; c < cols; ++c) {
3440 dx = src[c] - src[c - 1];
3441 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003442 int index;
3443 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003444 if (dy == 0) {
3445 index = 2;
3446 } else {
hui su9cc10652017-04-27 17:22:07 -07003447 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003448 dx = abs(dx);
3449 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003450 const int remd = (dx % dy) * 16 / dy;
3451 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003452 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003453 }
3454 hist[index] += temp;
3455 }
3456 src += src_stride;
3457 }
3458
hui su9cc10652017-04-27 17:22:07 -07003459 int i;
3460 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003461 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3462 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003463 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003464 const uint8_t angle_bin = mode_to_angle_bin[i];
3465 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003466 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003467 if (angle_bin > 0) {
3468 score += hist[angle_bin - 1];
3469 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003470 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003471 if (angle_bin < DIRECTIONAL_MODES - 1) {
3472 score += hist[angle_bin + 1];
3473 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003474 }
3475 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3476 directional_mode_skip_mask[i] = 1;
3477 }
3478 }
3479}
3480
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003481#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003482static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003483 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003484 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003485 memset(directional_mode_skip_mask, 0,
3486 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3487 // Sub-8x8 blocks do not use extra directions.
3488 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003489 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003490 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003491 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3492 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003493 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003494 for (r = 1; r < rows; ++r) {
3495 for (c = 1; c < cols; ++c) {
3496 dx = src[c] - src[c - 1];
3497 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003498 int index;
3499 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003500 if (dy == 0) {
3501 index = 2;
3502 } else {
hui su9cc10652017-04-27 17:22:07 -07003503 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003504 dx = abs(dx);
3505 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003506 const int remd = (dx % dy) * 16 / dy;
3507 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003508 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003509 }
3510 hist[index] += temp;
3511 }
3512 src += src_stride;
3513 }
3514
hui su9cc10652017-04-27 17:22:07 -07003515 int i;
3516 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003517 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3518 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003519 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003520 const uint8_t angle_bin = mode_to_angle_bin[i];
3521 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003522 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003523 if (angle_bin > 0) {
3524 score += hist[angle_bin - 1];
3525 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003526 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003527 if (angle_bin < DIRECTIONAL_MODES - 1) {
3528 score += hist[angle_bin + 1];
3529 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003530 }
3531 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3532 directional_mode_skip_mask[i] = 1;
3533 }
3534 }
3535}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003536#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003537#endif // CONFIG_EXT_INTRA
3538
3539// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003540static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3541 int *rate, int *rate_tokenonly,
3542 int64_t *distortion, int *skippable,
3543 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003544 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 MACROBLOCKD *const xd = &x->e_mbd;
3546 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003547 MB_MODE_INFO *const mbmi = &mic->mbmi;
3548 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003549 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003550#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003551 const int rows = block_size_high[bsize];
3552 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003553#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003554 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003555#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003556 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003557 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003558 const int src_stride = x->plane[0].src.stride;
3559 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003560#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003561#if CONFIG_FILTER_INTRA
3562 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003563 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3564#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003565 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003566#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003567 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003568 uint8_t *best_palette_color_map =
3569 cpi->common.allow_screen_content_tools
3570 ? x->palette_buffer->best_palette_color_map
3571 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003572 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003573 const int try_palette =
3574 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003575#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003576 const MODE_INFO *above_mi = xd->above_mi;
3577 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003578 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3579 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003580 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003581#if CONFIG_PVQ
3582 od_rollback_buffer pre_buf, post_buf;
3583
3584 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3585 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003586#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003587 bmode_costs = cpi->y_mode_costs[A][L];
3588
3589#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003590 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003591#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003592 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003593 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 directional_mode_skip_mask);
3595 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003596#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003597 angle_estimation(src, src_stride, rows, cols, bsize,
3598 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003599#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003600#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003601 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003602#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003603#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003604 pmi->palette_size[0] = 0;
3605 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003606 palette_y_mode_ctx +=
3607 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003608 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003609 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003610#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003611
3612 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3613 x->use_default_intra_tx_type = 1;
3614 else
3615 x->use_default_intra_tx_type = 0;
3616
3617 /* Y Search for intra prediction mode */
3618 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003619 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003620 int this_rate, this_rate_tokenonly, s;
3621 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622 if (mode_idx == FINAL_MODE_SEARCH) {
3623 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003624 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003625 x->use_default_intra_tx_type = 0;
3626 } else {
hui sude0c70a2017-01-09 17:12:17 -08003627 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003628 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003629#if CONFIG_PVQ
3630 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003631#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003633 mbmi->angle_delta[0] = 0;
3634#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003635 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003636 if (best_model_rd != INT64_MAX &&
3637 this_model_rd > best_model_rd + (best_model_rd >> 1))
3638 continue;
3639 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3640#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003641 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3642 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003643 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003644 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07003645 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
3646 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003647 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003648 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 }
3650#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003651 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003652#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003653 this_rate_tokenonly = this_rd_stats.rate;
3654 this_distortion = this_rd_stats.dist;
3655 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003656
3657 if (this_rate_tokenonly == INT_MAX) continue;
3658
hui sude0c70a2017-01-09 17:12:17 -08003659 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003660
hui sude0c70a2017-01-09 17:12:17 -08003661 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003662 // super_block_yrd above includes the cost of the tx_size in the
3663 // tokenonly rate, but for intra blocks, tx_size is always coded
3664 // (prediction granularity), so we account for it in the full rate,
3665 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003666 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003667 }
Urvang Joshib100db72016-10-12 16:28:56 -07003668#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003669 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003670 this_rate +=
3671 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3672 [palette_y_mode_ctx],
3673 0);
hui su9bc1d8d2017-03-24 12:36:03 -07003674 }
Urvang Joshib100db72016-10-12 16:28:56 -07003675#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003676#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003677 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003678 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3679#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003680#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08003682#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003683 const int p_angle =
3684 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003685 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003686 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003687 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003688#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003689 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
3690 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003691 }
3692#endif // CONFIG_EXT_INTRA
3693 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003694#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003695 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003696 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003697 }
hui su5db97432016-10-14 16:10:14 -07003698#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699
3700 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003701 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003702 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003703#if CONFIG_FILTER_INTRA
3704 beat_best_rd = 1;
3705#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706 *rate = this_rate;
3707 *rate_tokenonly = this_rate_tokenonly;
3708 *distortion = this_distortion;
3709 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003710#if CONFIG_PVQ
3711 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003712#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003713 }
3714 }
3715
Yushin Cho77bba8d2016-11-04 16:36:56 -07003716#if CONFIG_PVQ
3717 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003718#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003719
Luc Trudeaue3980282017-04-25 23:17:21 -04003720#if CONFIG_CFL
3721 // Perform one extra txfm_rd_in_plane() call, this time with the best value so
3722 // we can store reconstructed luma values
3723 RD_STATS this_rd_stats;
3724 x->cfl_store_y = 1;
3725 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, 0, bsize,
3726 mic->mbmi.tx_size, cpi->sf.use_fast_coef_costing);
3727 x->cfl_store_y = 0;
3728#endif
3729
Urvang Joshib100db72016-10-12 16:28:56 -07003730#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003731 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003732 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3733 bmode_costs[DC_PRED], &best_mbmi,
3734 best_palette_color_map, &best_rd, &best_model_rd,
3735 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003736 }
Urvang Joshib100db72016-10-12 16:28:56 -07003737#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003738
hui su5db97432016-10-14 16:10:14 -07003739#if CONFIG_FILTER_INTRA
3740 if (beat_best_rd) {
3741 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3742 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003743 &best_rd, &best_model_rd,
3744 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003745 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003746 }
3747 }
hui su5db97432016-10-14 16:10:14 -07003748#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003749
hui sude0c70a2017-01-09 17:12:17 -08003750 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003751 return best_rd;
3752}
3753
Yue Chena1e48dc2016-08-29 17:29:33 -07003754// Return value 0: early termination triggered, no valid rd cost available;
3755// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003756static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3757 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3758 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003759 MACROBLOCKD *const xd = &x->e_mbd;
3760 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3761 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3762 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003763 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003764 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003765
3766 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003767
Jingning Han31b6a4f2017-02-23 11:05:53 -08003768#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003769 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07003770
3771 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
3772 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08003773#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003774
Yushin Cho77bba8d2016-11-04 16:36:56 -07003775#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003776 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003777 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3778 av1_subtract_plane(x, bsize, plane);
3779 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003780#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003781
Yushin Cho09de28b2016-06-21 14:51:23 -07003782 if (is_cost_valid) {
3783 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003784 RD_STATS pn_rd_stats;
3785 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3786 uv_tx_size, cpi->sf.use_fast_coef_costing);
3787 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003788 is_cost_valid = 0;
3789 break;
3790 }
Angie Chiang284d7772016-11-08 11:06:45 -08003791 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3792 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003793 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003794 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003795 is_cost_valid = 0;
3796 break;
3797 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003798 }
3799 }
3800
3801 if (!is_cost_valid) {
3802 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003803 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003804 }
3805
3806 return is_cost_valid;
3807}
3808
Yaowu Xuc27fc142016-08-22 16:08:15 -07003809#if CONFIG_VAR_TX
Alex Converse61f37b82017-03-29 15:26:03 -07003810// FIXME crop these calls
3811static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
3812 TX_SIZE tx_size) {
3813 return aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size],
3814 tx_size_high[tx_size]);
3815}
3816
Yaowu Xuf883b422016-08-30 14:01:10 -07003817void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3818 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07003819 int plane_bsize, const ENTROPY_CONTEXT *a,
3820 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003821 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003822 MACROBLOCKD *xd = &x->e_mbd;
3823 const struct macroblock_plane *const p = &x->plane[plane];
3824 struct macroblockd_plane *const pd = &xd->plane[plane];
3825 int64_t tmp;
3826 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003827 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003828 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003829 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003830 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003832 int bh = block_size_high[txm_bsize];
3833 int bw = block_size_wide[txm_bsize];
3834 int txb_h = tx_size_high_unit[tx_size];
3835 int txb_w = tx_size_wide_unit[tx_size];
3836
Yaowu Xuc27fc142016-08-22 16:08:15 -07003837 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003838 uint8_t *src =
3839 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3840 uint8_t *dst =
3841 &pd->dst
3842 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003843#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3845 uint8_t *rec_buffer;
3846#else
3847 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003848#endif // CONFIG_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003849 int max_blocks_high = block_size_high[plane_bsize];
3850 int max_blocks_wide = block_size_wide[plane_bsize];
3851 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003852 const int16_t *diff =
3853 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003854 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003855
3856 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857
3858 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003859 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003860 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003861 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3862
3863 max_blocks_high >>= tx_size_wide_log2[0];
3864 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865
Angie Chiang77368af2017-03-23 16:22:07 -07003866 int coeff_ctx = get_entropy_context(tx_size, a, l);
3867
Angie Chiangff6d8902016-10-21 11:02:09 -07003868 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003869 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003870
Angie Chiangff6d8902016-10-21 11:02:09 -07003871 av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003872
Angie Chiang808d8592017-04-06 18:36:55 -07003873// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003874#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003875 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3876 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003877 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003878 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879 } else {
3880 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003881 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003882 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003883 }
3884#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003885 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003886 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003887#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003888
Jingning Han9fdc4222016-10-27 21:32:19 -07003889 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003890 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003891 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3892 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003893 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003894 for (idy = 0; idy < blocks_height; ++idy) {
3895 for (idx = 0; idx < blocks_width; ++idx) {
3896 const int16_t *d =
3897 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003898 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003899 }
3900 }
3901 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003902 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 }
3904
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003905#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003906 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3907 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003908#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003909 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07003910 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003911
Angie Chiang41fffae2017-04-03 10:33:18 -07003912 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
3913 MAX_TX_SIZE, eob);
3914 if (eob > 0) {
Jingning Han4b47c932016-11-03 09:20:08 -07003915 if (txb_w + blk_col > max_blocks_wide ||
3916 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003917 int idx, idy;
3918 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003919 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3920 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003921 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003922 for (idy = 0; idy < blocks_height; ++idy) {
3923 for (idx = 0; idx < blocks_width; ++idx) {
3924 uint8_t *const s =
3925 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3926 uint8_t *const r =
3927 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003928 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929 tmp += this_dist;
3930 }
3931 }
3932 } else {
3933 uint32_t this_dist;
3934 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3935 &this_dist);
3936 tmp = this_dist;
3937 }
3938 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003939 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07003940 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07003941 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003942 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07003943 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003944
Angie Chiangd81fdb42016-11-03 12:20:58 -07003945#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003946 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3947 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08003948#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003949}
3950
Yaowu Xuf883b422016-08-30 14:01:10 -07003951static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003952 int blk_col, int plane, int block, int block32,
3953 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003954 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3955 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003956 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003957 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003958 MACROBLOCKD *const xd = &x->e_mbd;
3959 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3960 struct macroblock_plane *const p = &x->plane[plane];
3961 struct macroblockd_plane *const pd = &xd->plane[plane];
3962 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3963 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003964 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965 [MAX_MIB_SIZE] =
3966 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003967 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3968 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003969 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003970 int64_t this_rd = INT64_MAX;
3971 ENTROPY_CONTEXT *pta = ta + blk_col;
3972 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003973 int coeff_ctx, i;
Jingning Hanc8b89362016-11-01 10:28:53 -07003974 int ctx =
3975 txfm_partition_context(tx_above + (blk_col >> 1),
3976 tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003977 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978 int tmp_eob = 0;
3979 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07003980 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08003981 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982
Jingning Han63cbf342016-11-09 15:37:48 -08003983 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08003984
Jingning Hand3fada82016-11-22 10:46:55 -08003985 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986
3987 if (ref_best_rd < 0) {
3988 *is_cost_valid = 0;
3989 return;
3990 }
3991
Jingning Hance059e82016-10-31 16:27:28 -07003992 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993
Angie Chiangc0feea82016-11-03 15:36:18 -07003994 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003995
3996 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
3997
Jingning Han1c019f92016-11-21 12:53:32 -08003998 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
3999 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004000
4001 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4002 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004003
4004 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4005 rd_stats_stack[block32].rate != INT_MAX) {
4006 *rd_stats = rd_stats_stack[block32];
4007 p->eobs[block] = !rd_stats->skip;
4008 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4009 } else {
4010 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004011 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004012 if (tx_size == TX_32X32) {
4013 rd_stats_stack[block32] = *rd_stats;
4014 }
4015 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004016
Angie Chiangb5dda482016-11-02 16:19:58 -07004017 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4018 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4019 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004020 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004021#if CONFIG_RD_DEBUG
4022 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4023 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004024#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004025 rd_stats->rate = zero_blk_rate;
4026 rd_stats->dist = rd_stats->sse;
4027 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004028 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4029 p->eobs[block] = 0;
4030 } else {
4031 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004032 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004033 }
4034
Jingning Han571189c2016-10-24 10:38:43 -07004035 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004036 rd_stats->rate +=
4037 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4038 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004039 tmp_eob = p->eobs[block];
4040 }
4041
Jingning Han571189c2016-10-24 10:38:43 -07004042 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004043 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4044 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004045 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004046 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004047 int this_cost_valid = 1;
4048 int64_t tmp_rd = 0;
4049
Angie Chiangd7246172016-11-03 11:49:15 -07004050 sum_rd_stats.rate =
4051 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004052
4053 assert(tx_size < TX_SIZES_ALL);
4054
Yaowu Xuc27fc142016-08-22 16:08:15 -07004055 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004056 int offsetr = blk_row + (i >> 1) * bsl;
4057 int offsetc = blk_col + (i & 0x01) * bsl;
4058
4059 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4060
Jingning Han63cbf342016-11-09 15:37:48 -08004061 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004062 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004063 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4064 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004065
Angie Chiangc0feea82016-11-03 15:36:18 -07004066 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004067
Angie Chiangd7246172016-11-03 11:49:15 -07004068 tmp_rd =
4069 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004070 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004071 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004072 }
4073 if (this_cost_valid) sum_rd = tmp_rd;
4074 }
4075
4076 if (this_rd < sum_rd) {
4077 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004078 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4079 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004080 txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
Jingning Han581d1692017-01-05 16:03:54 -08004081 tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004082 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004083 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4084 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004085 inter_tx_size[idy][idx] = tx_size;
4086 mbmi->tx_size = tx_size;
4087 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004088 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004089 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004090 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004091 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4092 }
4093}
4094
Angie Chiangb5dda482016-11-02 16:19:58 -07004095static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4096 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004097 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004098 MACROBLOCKD *const xd = &x->e_mbd;
4099 int is_cost_valid = 1;
4100 int64_t this_rd = 0;
4101
4102 if (ref_best_rd < 0) is_cost_valid = 0;
4103
Angie Chiangc0feea82016-11-03 15:36:18 -07004104 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105
4106 if (is_cost_valid) {
4107 const struct macroblockd_plane *const pd = &xd->plane[0];
4108 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004109 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4110 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004111 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004112 const int bh = tx_size_high_unit[max_tx_size];
4113 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114 int idx, idy;
4115 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004116 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004117 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004118 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4119 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
4120 TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
4121 TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
4122
Angie Chiangb5dda482016-11-02 16:19:58 -07004123 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004124 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004125
Jingning Han9ca05b72017-01-03 14:41:36 -08004126 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004127 memcpy(tx_above, xd->above_txfm_context,
4128 sizeof(TXFM_CONTEXT) * (mi_width >> 1));
4129 memcpy(tx_left, xd->left_txfm_context,
4130 sizeof(TXFM_CONTEXT) * (mi_height >> 1));
4131
4132 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004133 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004134 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004135 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004136 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004137 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004138 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004139 this_rd += AOMMIN(
4140 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4141 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004143 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144 }
4145 }
4146 }
4147
Angie Chiangb5dda482016-11-02 16:19:58 -07004148 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4149 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004150 if (this_rd > ref_best_rd) is_cost_valid = 0;
4151
4152 if (!is_cost_valid) {
4153 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004154 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004155 }
4156}
4157
Yaowu Xuf883b422016-08-30 14:01:10 -07004158static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004159 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004160 int64_t ref_best_rd, TX_TYPE tx_type,
4161 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004162 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004163 MACROBLOCKD *const xd = &x->e_mbd;
4164 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004165 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004166 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4167 int s0 = av1_cost_bit(skip_prob, 0);
4168 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004169 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004170 int row, col;
4171 const int max_blocks_high = max_block_high(xd, bsize, 0);
4172 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173
4174 mbmi->tx_type = tx_type;
Jingning Hane67b38a2016-11-04 10:30:00 -07004175 mbmi->min_tx_size = TX_SIZES_ALL;
Jingning Han63cbf342016-11-09 15:37:48 -08004176 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177
Angie Chiangb5dda482016-11-02 16:19:58 -07004178 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004179
Jingning Hane67b38a2016-11-04 10:30:00 -07004180 for (row = 0; row < max_blocks_high / 2; ++row)
4181 for (col = 0; col < max_blocks_wide / 2; ++col)
4182 mbmi->min_tx_size = AOMMIN(
4183 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4184
Yaowu Xuc27fc142016-08-22 16:08:15 -07004185#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004186 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4187 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004188 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004189 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4190 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191 if (is_inter) {
4192 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004193 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004194 cpi->inter_tx_type_costs[ext_tx_set]
4195 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004196 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197 } else {
4198 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004199 rd_stats->rate +=
4200 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4201 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004202 }
4203 }
4204#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004205 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4206 rd_stats->rate +=
4207 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004208#endif // CONFIG_EXT_TX
4209
Angie Chiangb5dda482016-11-02 16:19:58 -07004210 if (rd_stats->skip)
4211 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004212 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004213 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004214
Angie Chiangb5dda482016-11-02 16:19:58 -07004215 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4216 !(rd_stats->skip))
4217 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004218
4219 return rd;
4220}
4221
Angie Chiangb5dda482016-11-02 16:19:58 -07004222static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4223 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004224 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004225 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4227 MACROBLOCKD *const xd = &x->e_mbd;
4228 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4229 int64_t rd = INT64_MAX;
4230 int64_t best_rd = INT64_MAX;
4231 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4232 const int is_inter = is_inter_block(mbmi);
4233 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004234 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004235 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004236 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Angie Chiangf1cb0752017-04-10 16:01:20 -07004237 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238 int idx, idy;
4239 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004240 const int count32 =
4241 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004242#if CONFIG_EXT_PARTITION
4243 RD_STATS rd_stats_stack[16];
4244#else
Jingning Han63cbf342016-11-09 15:37:48 -08004245 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004246#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004247#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004248 const int ext_tx_set =
4249 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004250#endif // CONFIG_EXT_TX
4251
4252 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4253#if CONFIG_EXT_TX
4254 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4255#else
4256 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004257#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004258
Angie Chiangc0feea82016-11-03 15:36:18 -07004259 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004260
Jingning Han89d648b2016-11-22 11:22:08 -08004261 for (idx = 0; idx < count32; ++idx)
4262 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004263
Yaowu Xuc27fc142016-08-22 16:08:15 -07004264 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004265 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004266 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004267#if CONFIG_EXT_TX
4268 if (is_inter) {
4269 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4270 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4271 if (!do_tx_type_search(tx_type, prune)) continue;
4272 }
4273 } else {
4274 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4275 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4276 }
4277 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4278 }
4279#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004280 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4281 !do_tx_type_search(tx_type, prune))
4282 continue;
4283#endif // CONFIG_EXT_TX
4284 if (is_inter && x->use_default_inter_tx_type &&
4285 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4286 continue;
4287
Jingning Hane67b38a2016-11-04 10:30:00 -07004288 if (xd->lossless[mbmi->segment_id])
4289 if (tx_type != DCT_DCT) continue;
4290
Angie Chiangb5dda482016-11-02 16:19:58 -07004291 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004292 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004293
4294 if (rd < best_rd) {
4295 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004296 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004297 best_tx_type = mbmi->tx_type;
4298 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004299 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004300 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4301 for (idy = 0; idy < xd->n8_h; ++idy)
4302 for (idx = 0; idx < xd->n8_w; ++idx)
4303 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4304 }
4305 }
4306
4307 mbmi->tx_type = best_tx_type;
4308 for (idy = 0; idy < xd->n8_h; ++idy)
4309 for (idx = 0; idx < xd->n8_w; ++idx)
4310 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4311 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004312 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004313 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4314}
4315
Yaowu Xuf883b422016-08-30 14:01:10 -07004316static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004317 int blk_col, int plane, int block, TX_SIZE tx_size,
4318 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004319 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004320 MACROBLOCKD *const xd = &x->e_mbd;
4321 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4322 struct macroblock_plane *const p = &x->plane[plane];
4323 struct macroblockd_plane *const pd = &xd->plane[plane];
4324 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4325 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4326 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4327 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004328 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4329 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004330
Jingning Hand3fada82016-11-22 10:46:55 -08004331 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004332
Yaowu Xuc27fc142016-08-22 16:08:15 -07004333 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4334
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004335 plane_tx_size =
4336 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4337 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004338
4339 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004340 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004341 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4342 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004343 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004344 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004345
Jingning Han58224042016-10-27 16:35:32 -07004346 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004347 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004348 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004349 tl[i] = !(p->eobs[block] == 0);
4350 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004351 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4352 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004353 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004354 int i;
4355
4356 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004357
4358 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004359 int offsetr = blk_row + (i >> 1) * bsl;
4360 int offsetc = blk_col + (i & 0x01) * bsl;
4361
4362 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4363
4364 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4365 above_ctx, left_ctx, rd_stats);
4366 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004367 }
4368 }
4369}
4370
4371// Return value 0: early termination triggered, no valid rd cost available;
4372// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004373static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4374 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4375 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004376 MACROBLOCKD *const xd = &x->e_mbd;
4377 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4378 int plane;
4379 int is_cost_valid = 1;
4380 int64_t this_rd;
4381
4382 if (ref_best_rd < 0) is_cost_valid = 0;
4383
Angie Chiangc0feea82016-11-03 15:36:18 -07004384 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004385
Jingning Han31b6a4f2017-02-23 11:05:53 -08004386#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004387 if (x->skip_chroma_rd) return is_cost_valid;
4388 bsize = AOMMAX(BLOCK_8X8, bsize);
Fergus Simpson4063a682017-02-28 16:52:22 -08004389#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004390
Yue Chena1e48dc2016-08-29 17:29:33 -07004391#if CONFIG_EXT_TX && CONFIG_RECT_TX
4392 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004393 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004394 }
4395#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4396
Yaowu Xuc27fc142016-08-22 16:08:15 -07004397 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004398 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004399 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004400 }
4401
Yaowu Xuc27fc142016-08-22 16:08:15 -07004402 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4403 const struct macroblockd_plane *const pd = &xd->plane[plane];
4404 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004405 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4406 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004407 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004408 const int bh = tx_size_high_unit[max_tx_size];
4409 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410 int idx, idy;
4411 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004412 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004413 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4414 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004415 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004416 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417
Jingning Han9ca05b72017-01-03 14:41:36 -08004418 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419
4420 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004421 for (idx = 0; idx < mi_width; idx += bw) {
4422 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004423 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004424 block += step;
4425 }
4426 }
4427
Angie Chiangb5dda482016-11-02 16:19:58 -07004428 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004429 is_cost_valid = 0;
4430 break;
4431 }
4432
Angie Chiang628d7c92016-11-03 16:24:56 -07004433 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434
Angie Chiangb5dda482016-11-02 16:19:58 -07004435 this_rd =
4436 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4437 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004438
4439 if (this_rd > ref_best_rd) {
4440 is_cost_valid = 0;
4441 break;
4442 }
4443 }
4444
4445 if (!is_cost_valid) {
4446 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004447 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004448 }
4449
4450 return is_cost_valid;
4451}
4452#endif // CONFIG_VAR_TX
4453
Urvang Joshib100db72016-10-12 16:28:56 -07004454#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004455static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4456 int dc_mode_cost,
4457 uint8_t *best_palette_color_map,
4458 MB_MODE_INFO *const best_mbmi,
4459 int64_t *best_rd, int *rate,
4460 int *rate_tokenonly, int64_t *distortion,
4461 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004462 MACROBLOCKD *const xd = &x->e_mbd;
4463 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui sude0c70a2017-01-09 17:12:17 -08004464 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004465 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004466 int this_rate;
4467 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004468 int colors_u, colors_v, colors;
4469 const int src_stride = x->plane[1].src.stride;
4470 const uint8_t *const src_u = x->plane[1].src.buf;
4471 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004472 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004473 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004474 int plane_block_width, plane_block_height, rows, cols;
4475 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4476 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004477 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4478
hui su83c26632017-01-24 17:19:06 -08004479 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004480#if CONFIG_FILTER_INTRA
4481 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4482#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004483
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004484#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004485 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004486 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4487 cpi->common.bit_depth);
4488 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4489 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004490 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004491#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004492 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4493 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004494#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004495 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004496#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004497
4498 colors = colors_u > colors_v ? colors_u : colors_v;
4499 if (colors > 1 && colors <= 64) {
4500 int r, c, n, i, j;
4501 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004502 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004503 float lb_u, ub_u, val_u;
4504 float lb_v, ub_v, val_v;
4505 float *const data = x->palette_buffer->kmeans_data_buf;
4506 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004507
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004508#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4510 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4511 if (cpi->common.use_highbitdepth) {
4512 lb_u = src_u16[0];
4513 ub_u = src_u16[0];
4514 lb_v = src_v16[0];
4515 ub_v = src_v16[0];
4516 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004517#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004518 lb_u = src_u[0];
4519 ub_u = src_u[0];
4520 lb_v = src_v[0];
4521 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004522#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004523 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004524#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004525
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526 for (r = 0; r < rows; ++r) {
4527 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004528#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004529 if (cpi->common.use_highbitdepth) {
4530 val_u = src_u16[r * src_stride + c];
4531 val_v = src_v16[r * src_stride + c];
4532 data[(r * cols + c) * 2] = val_u;
4533 data[(r * cols + c) * 2 + 1] = val_v;
4534 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004535#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004536 val_u = src_u[r * src_stride + c];
4537 val_v = src_v[r * src_stride + c];
4538 data[(r * cols + c) * 2] = val_u;
4539 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004540#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004541 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004542#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004543 if (val_u < lb_u)
4544 lb_u = val_u;
4545 else if (val_u > ub_u)
4546 ub_u = val_u;
4547 if (val_v < lb_v)
4548 lb_v = val_v;
4549 else if (val_v > ub_v)
4550 ub_v = val_v;
4551 }
4552 }
4553
4554 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4555 --n) {
4556 for (i = 0; i < n; ++i) {
4557 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4558 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4559 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004560 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07004561#if CONFIG_PALETTE_DELTA_ENCODING
4562 // Sort the U channel colors in ascending order.
4563 for (i = 0; i < 2 * (n - 1); i += 2) {
4564 int min_idx = i;
4565 float min_val = centroids[i];
4566 for (j = i + 2; j < 2 * n; j += 2)
4567 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
4568 if (min_idx != i) {
4569 float temp_u = centroids[i], temp_v = centroids[i + 1];
4570 centroids[i] = centroids[min_idx];
4571 centroids[i + 1] = centroids[min_idx + 1];
4572 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
4573 }
4574 }
4575 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
4576#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004577 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4578 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004579 pmi->palette_size[1] = n;
4580 for (i = 1; i < 3; ++i) {
4581 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004582#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004583 if (cpi->common.use_highbitdepth)
4584 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4585 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4586 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004587#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004588 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4589 clip_pixel((int)centroids[j * 2 + i - 1]);
4590 }
4591 }
4592
Angie Chiang284d7772016-11-08 11:06:45 -08004593 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4594 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004595 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004596 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08004597 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004598 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004599 av1_cost_bit(
4600 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui sud13c24a2017-04-07 16:13:07 -07004601 this_rate += av1_palette_color_cost_uv(pmi, cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004602 for (i = 0; i < rows; ++i) {
4603 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004604 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004605 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004606 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004607 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004608 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4609 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610 }
4611 }
4612
Angie Chiang284d7772016-11-08 11:06:45 -08004613 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004614 if (this_rd < *best_rd) {
4615 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004616 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004617 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004618 plane_block_width * plane_block_height *
4619 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004620 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004621 *distortion = tokenonly_rd_stats.dist;
4622 *rate_tokenonly = tokenonly_rd_stats.rate;
4623 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004624 }
4625 }
4626 }
hui su83c26632017-01-24 17:19:06 -08004627 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004628 memcpy(color_map, best_palette_color_map,
4629 rows * cols * sizeof(best_palette_color_map[0]));
4630 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004631}
Urvang Joshib100db72016-10-12 16:28:56 -07004632#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004633
hui su5db97432016-10-14 16:10:14 -07004634#if CONFIG_FILTER_INTRA
4635// Return 1 if an filter intra mode is selected; return 0 otherwise.
4636static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4637 int *rate, int *rate_tokenonly,
4638 int64_t *distortion, int *skippable,
4639 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004640 MACROBLOCKD *const xd = &x->e_mbd;
4641 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004642 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004643 int this_rate;
4644 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004645 FILTER_INTRA_MODE mode;
4646 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004647 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004648
hui su5db97432016-10-14 16:10:14 -07004649 av1_zero(filter_intra_mode_info);
4650 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004651 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004652#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004654#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004655
4656 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004657 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004658 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004659 continue;
4660
Angie Chiang284d7772016-11-08 11:06:45 -08004661 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004662 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4664 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004665 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004666 if (this_rd < *best_rd) {
4667 *best_rd = this_rd;
4668 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004669 *rate_tokenonly = tokenonly_rd_stats.rate;
4670 *distortion = tokenonly_rd_stats.dist;
4671 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004672 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4673 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004674 }
4675 }
4676
hui su5db97432016-10-14 16:10:14 -07004677 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004678 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004679 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4680 filter_intra_mode_info.use_filter_intra_mode[1];
4681 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4682 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004683 return 1;
4684 } else {
4685 return 0;
4686 }
4687}
hui su5db97432016-10-14 16:10:14 -07004688#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004689
hui su5db97432016-10-14 16:10:14 -07004690#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004691// Run RD calculation with given chroma intra prediction angle., and return
4692// the RD cost. Update the best mode info. if the RD cost is the best so far.
4693static int64_t pick_intra_angle_routine_sbuv(
4694 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4695 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4696 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004697 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Angie Chiang284d7772016-11-08 11:06:45 -08004698 int this_rate;
4699 int64_t this_rd;
4700 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004701
hui su45dc5972016-12-08 17:42:50 -08004702 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4703 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004704 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4705 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004706 if (this_rd < *best_rd) {
4707 *best_rd = this_rd;
4708 *best_angle_delta = mbmi->angle_delta[1];
4709 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004710 rd_stats->rate = tokenonly_rd_stats.rate;
4711 rd_stats->dist = tokenonly_rd_stats.dist;
4712 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004713 }
hui su45dc5972016-12-08 17:42:50 -08004714 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004715}
4716
hui su45dc5972016-12-08 17:42:50 -08004717// With given chroma directional intra prediction mode, pick the best angle
4718// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004719static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004720 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004721 int64_t best_rd, int *rate,
4722 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004723 MACROBLOCKD *const xd = &x->e_mbd;
4724 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su45dc5972016-12-08 17:42:50 -08004725 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07004726 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004727
hui su45dc5972016-12-08 17:42:50 -08004728 rd_stats->rate = INT_MAX;
4729 rd_stats->skip = 0;
4730 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07004731 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732
hui su0a6731f2017-04-26 15:23:47 -07004733 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004734 for (i = 0; i < 2; ++i) {
4735 best_rd_in = (best_rd == INT64_MAX)
4736 ? INT64_MAX
4737 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4738 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4739 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4740 best_rd_in, rate, rd_stats,
4741 &best_angle_delta, &best_rd);
4742 rd_cost[2 * angle_delta + i] = this_rd;
4743 if (angle_delta == 0) {
4744 if (this_rd == INT64_MAX) return 0;
4745 rd_cost[1] = this_rd;
4746 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004747 }
4748 }
hui su45dc5972016-12-08 17:42:50 -08004749 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004750
hui su45dc5972016-12-08 17:42:50 -08004751 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07004752 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004753 int64_t rd_thresh;
4754 for (i = 0; i < 2; ++i) {
4755 int skip_search = 0;
4756 rd_thresh = best_rd + (best_rd >> 5);
4757 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4758 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4759 skip_search = 1;
4760 if (!skip_search) {
4761 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07004762 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4763 rate, rd_stats, &best_angle_delta,
4764 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004765 }
4766 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004767 }
4768
4769 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004770 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004771}
4772#endif // CONFIG_EXT_INTRA
4773
Urvang Joshi52648442016-10-13 17:27:51 -07004774static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4775 int *rate, int *rate_tokenonly,
4776 int64_t *distortion, int *skippable,
4777 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004778 MACROBLOCKD *xd = &x->e_mbd;
4779 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su83c26632017-01-24 17:19:06 -08004780 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004781 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004782 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004783 int this_rate;
4784 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004785#if CONFIG_PVQ
4786 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004787 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004788#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004789#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004790 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004791 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004792#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004793
hui su83c26632017-01-24 17:19:06 -08004794#if CONFIG_FILTER_INTRA
hui su5db97432016-10-14 16:10:14 -07004795 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4796#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004797#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004798 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004799#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004800 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004801#if CONFIG_EXT_INTRA
4802 const int is_directional_mode =
4803 av1_is_directional_mode(mode, mbmi->sb_type);
4804#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004805 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4806 (1 << mode)))
4807 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004808
4809 mbmi->uv_mode = mode;
4810#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004811 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004812 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004813 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4814 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004815 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4816 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004817 continue;
4818 } else {
hui su83c26632017-01-24 17:19:06 -08004819#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004820 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004821#if CONFIG_PVQ
4822 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004823#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004825 }
hui su83c26632017-01-24 17:19:06 -08004826#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004827 }
hui su83c26632017-01-24 17:19:06 -08004828#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004829 this_rate =
4830 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004831
4832#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004833 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004834 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4835 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08004836 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004837#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004838#if CONFIG_FILTER_INTRA
4839 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4840 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4841#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004842#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004843 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4844 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004845 this_rate += av1_cost_bit(
4846 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004847#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004848
Yushin Cho77bba8d2016-11-04 16:36:56 -07004849#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004850 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004851#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004852 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853
4854 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004855 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004856 best_rd = this_rd;
4857 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004858 *rate_tokenonly = tokenonly_rd_stats.rate;
4859 *distortion = tokenonly_rd_stats.dist;
4860 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861 }
4862 }
4863
Urvang Joshib100db72016-10-12 16:28:56 -07004864#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004865 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4866 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004867 rd_pick_palette_intra_sbuv(cpi, x,
4868 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4869 best_palette_color_map, &best_mbmi, &best_rd,
4870 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004871 }
Urvang Joshib100db72016-10-12 16:28:56 -07004872#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004873
hui su5db97432016-10-14 16:10:14 -07004874#if CONFIG_FILTER_INTRA
4875 if (mbmi->sb_type >= BLOCK_8X8) {
4876 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004877 skippable, bsize, &best_rd))
4878 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004879 }
hui su5db97432016-10-14 16:10:14 -07004880#endif // CONFIG_FILTER_INTRA
4881
hui su83c26632017-01-24 17:19:06 -08004882 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004883 // Make sure we actually chose a mode
4884 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885 return best_rd;
4886}
4887
Urvang Joshi52648442016-10-13 17:27:51 -07004888static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004889 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4890 TX_SIZE max_tx_size, int *rate_uv,
4891 int *rate_uv_tokenonly, int64_t *dist_uv,
4892 int *skip_uv, PREDICTION_MODE *mode_uv) {
4893 // Use an estimated rd for uv_intra based on DC_PRED if the
4894 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004895 (void)ctx;
Jingning Han271bb2c2016-12-14 12:34:46 -08004896#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004897#if CONFIG_CHROMA_2X2
4898 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4899 bsize, max_tx_size);
4900#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004901 max_tx_size = AOMMAX(max_tx_size, TX_4X4);
4902 if (x->skip_chroma_rd) {
4903 *rate_uv = 0;
4904 *rate_uv_tokenonly = 0;
4905 *dist_uv = 0;
4906 *skip_uv = 1;
4907 *mode_uv = DC_PRED;
4908 return;
4909 }
Jingning Han65113f32017-04-12 10:06:58 -07004910 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
4911 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07004912 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07004913 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004914#endif // CONFIG_CHROMA_2X2
4915#else
4916 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4917 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4918#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004919 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4920}
4921
Urvang Joshi52648442016-10-13 17:27:51 -07004922static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004923 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004924#if CONFIG_EXT_INTER
4925 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004926 return cpi
4927 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004928 }
David Barkercb03dc32017-04-07 13:05:09 +01004929#endif
4930
David Barkercb03dc32017-04-07 13:05:09 +01004931 int mode_cost = 0;
4932 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4933 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4934
4935 assert(is_inter_mode(mode));
4936
4937 if (mode == NEWMV) {
4938 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4939 return mode_cost;
4940 } else {
4941 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4942 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4943
4944 if (is_all_zero_mv) return mode_cost;
4945
4946 if (mode == ZEROMV) {
4947 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4948 return mode_cost;
4949 } else {
4950 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4951 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4952
4953 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4954 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4955 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4956
4957 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4958 return mode_cost;
4959 }
4960 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961}
4962
Sarah Parker6fdc8532016-11-16 17:47:13 -08004963#if CONFIG_EXT_INTER
4964static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
4965 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004966 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08004967 switch (comp_type) {
4968 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004969#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08004970 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00004971#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08004972#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08004973 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08004974#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08004975 default: assert(0); return 0;
4976 }
4977}
4978#endif // CONFIG_EXT_INTER
4979
clang-format55ce9e02017-02-15 22:27:12 -08004980static int set_and_cost_bmi_mvs(
4981 const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
4982 PREDICTION_MODE mode, int_mv this_mv[2],
4983 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
4984 int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004985#if CONFIG_EXT_INTER
clang-format55ce9e02017-02-15 22:27:12 -08004986 int_mv compound_seg_newmvs[2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004987#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00004988 int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
4989 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004990 MODE_INFO *const mic = xd->mi[0];
4991 const MB_MODE_INFO *const mbmi = &mic->mbmi;
4992 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
4993 int thismvcost = 0;
4994 int idx, idy;
4995 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
4996 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
4997 const int is_compound = has_second_ref(mbmi);
Yaowu Xub0d0d002016-11-22 09:26:43 -08004998 int mode_ctx;
David Barker45390c12017-02-20 14:44:40 +00004999 (void)mi_row;
5000 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005001
5002 switch (mode) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005003 case NEWMV: this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005004#if CONFIG_EXT_INTER
Alex Converse6317c882016-09-29 14:21:37 -07005005 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005006 lower_mv_precision(&this_mv[0].as_mv, 0);
5007#endif // CONFIG_EXT_INTER
5008
Yaowu Xuc27fc142016-08-22 16:08:15 -07005009 for (idx = 0; idx < 1 + is_compound; ++idx) {
5010 this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005011 av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005012 thismvcost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07005013 av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
5014 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005015 }
5016 (void)mvjcost;
5017 (void)mvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005018 break;
5019 case NEARMV:
5020 case NEARESTMV:
5021 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5022 if (is_compound)
5023 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5024 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005025 case ZEROMV: {
5026 int ref;
5027 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkere5299862016-08-16 14:57:37 -07005028#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005029 this_mv[ref].as_int =
5030 gm_get_motion_vector(
5031 &cpi->common.global_motion[mbmi->ref_frame[ref]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005032 cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005033 mi_row, i)
Debargha Mukherjee5f305852016-11-03 15:47:21 -07005034 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005035#else
5036 this_mv[ref].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005037#endif // CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005038 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005039 break;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005040 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005041#if CONFIG_EXT_INTER
5042 case NEW_NEWMV:
5043 if (compound_seg_newmvs[0].as_int == INVALID_MV ||
5044 compound_seg_newmvs[1].as_int == INVALID_MV) {
5045 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
5046 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
5047 } else {
5048 this_mv[0].as_int = compound_seg_newmvs[0].as_int;
5049 this_mv[1].as_int = compound_seg_newmvs[1].as_int;
5050 }
Alex Converse6317c882016-09-29 14:21:37 -07005051 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005052 lower_mv_precision(&this_mv[0].as_mv, 0);
Alex Converse6317c882016-09-29 14:21:37 -07005053 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005054 lower_mv_precision(&this_mv[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005055 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005056 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5057 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
David Barker404b2e82017-03-27 13:07:47 +01005058 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005059 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5060 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005061 break;
5062 case NEW_NEARMV:
5063 case NEW_NEARESTMV:
5064 this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
Alex Converse6317c882016-09-29 14:21:37 -07005065 if (!cpi->common.allow_high_precision_mv)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005066 lower_mv_precision(&this_mv[0].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005067 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005068 thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
5069 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5071 break;
5072 case NEAR_NEWMV:
5073 case NEAREST_NEWMV:
5074 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5075 this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].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[1].as_mv, 0);
David Barker404b2e82017-03-27 13:07:47 +01005078 av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07005079 thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
5080 mvjcost, mvcost, MV_COST_WEIGHT_SUB);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005081 break;
5082 case NEAREST_NEARMV:
5083 case NEAR_NEARESTMV:
5084 case NEAREST_NEARESTMV:
5085 case NEAR_NEARMV:
5086 this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
5087 this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
5088 break;
5089 case ZERO_ZEROMV:
Sarah Parkerc2d38712017-01-24 15:15:41 -08005090#if CONFIG_GLOBAL_MOTION
5091 this_mv[0].as_int =
5092 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
David Barker45390c12017-02-20 14:44:40 +00005093 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005094 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005095 .as_int;
5096 this_mv[1].as_int =
5097 gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
David Barker45390c12017-02-20 14:44:40 +00005098 cpi->common.allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005099 mbmi->sb_type, mi_col, mi_row, i)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005100 .as_int;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005101#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005102 this_mv[0].as_int = 0;
5103 this_mv[1].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005104#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005105 break;
5106#endif // CONFIG_EXT_INTER
5107 default: break;
5108 }
5109
5110 mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
5111 if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
5112
5113 mic->bmi[i].as_mode = mode;
5114
Yaowu Xuc27fc142016-08-22 16:08:15 -07005115 if (mode == NEWMV) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005116 mic->bmi[i].pred_mv[0].as_int =
5117 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
5118 if (is_compound)
5119 mic->bmi[i].pred_mv[1].as_int =
5120 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005121 } else {
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07005122 mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
5123 if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005125
5126 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
5127 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
5128 memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
5129
Yaowu Xuc27fc142016-08-22 16:08:15 -07005130#if CONFIG_EXT_INTER
5131 if (is_compound)
5132 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
5133 else
5134#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005135 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
5136 mbmi->ref_frame, mbmi->sb_type, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137 return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005138}
5139
Yushin Choab44fd12017-01-09 16:06:53 -08005140static int64_t encode_inter_mb_segment_sub8x8(
5141 const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
5142 int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
5143 ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
Angie Chiang22ba7512016-10-20 17:10:33 -07005144 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005145 MACROBLOCKD *xd = &x->e_mbd;
5146 struct macroblockd_plane *const pd = &xd->plane[0];
5147 struct macroblock_plane *const p = &x->plane[0];
5148 MODE_INFO *const mi = xd->mi[0];
5149 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanbafee8d2016-12-02 10:25:03 -08005150 const int txb_width = max_block_wide(xd, plane_bsize, 0);
5151 const int txb_height = max_block_high(xd, plane_bsize, 0);
Jingning Hanc4049db2016-10-27 14:44:13 -07005152 const int width = block_size_wide[plane_bsize];
5153 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005154 int idx, idy;
5155 const uint8_t *const src =
Yaowu Xuf883b422016-08-30 14:01:10 -07005156 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005157 uint8_t *const dst =
Yaowu Xuf883b422016-08-30 14:01:10 -07005158 &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005159 int64_t thisdistortion = 0, thissse = 0;
5160 int thisrate = 0;
5161 TX_SIZE tx_size = mi->mbmi.tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005162 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
Jingning Hanc4049db2016-10-27 14:44:13 -07005163 const int num_4x4_w = tx_size_wide_unit[tx_size];
5164 const int num_4x4_h = tx_size_high_unit[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -07005165#if !CONFIG_PVQ
5166 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
5167#else
5168 (void)cpi;
5169 (void)ta;
5170 (void)tl;
Yushin Cho38395482017-01-03 13:10:41 -08005171 (void)tx_type;
Fergus Simpson4063a682017-02-28 16:52:22 -08005172#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005173
5174#if CONFIG_EXT_TX && CONFIG_RECT_TX
5175 assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
5176 assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
5177 tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
5178#else
5179 assert(tx_size == TX_4X4);
5180#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yushin Cho38395482017-01-03 13:10:41 -08005181
Yaowu Xuc27fc142016-08-22 16:08:15 -07005182 assert(tx_type == DCT_DCT);
5183
Yaowu Xuf883b422016-08-30 14:01:10 -07005184 av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005185
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005186#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005188 aom_highbd_subtract_block(
5189 height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
5190 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005191 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005192 aom_subtract_block(height, width,
5193 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005194 8, src, p->src.stride, dst, pd->dst.stride);
5195 }
5196#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005197 aom_subtract_block(height, width,
5198 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
Yaowu Xuc27fc142016-08-22 16:08:15 -07005199 8, src, p->src.stride, dst, pd->dst.stride);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005200#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005201
Jingning Hanbafee8d2016-12-02 10:25:03 -08005202 for (idy = 0; idy < txb_height; idy += num_4x4_h) {
5203 for (idx = 0; idx < txb_width; idx += num_4x4_w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005204 int64_t dist, ssz, rd, rd1, rd2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 int coeff_ctx;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005206 const int k = i + (idy * 2 + idx);
5207 const int block = av1_raster_order_to_block_index(tx_size, k);
5208 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
5209 idx == 0 && idy == 0));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
Angie Chiangff6d8902016-10-21 11:02:09 -07005211 av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
Debargha Mukherjeef0305582016-11-24 09:55:34 -08005212 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07005213 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Angie Chiang808d8592017-04-06 18:36:55 -07005214 av1_dist_block(cpi, x, 0, BLOCK_8X8, block, idy + (i >> 1),
5215 idx + (i & 0x1), tx_size, &dist, &ssz,
5216 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005217 thisdistortion += dist;
5218 thissse += ssz;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005219#if !CONFIG_PVQ
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07005220 thisrate +=
Angie Chiang05917872017-04-15 12:28:56 -07005221 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, (ta + (k & 1)),
Angie Chiang77368af2017-03-23 16:22:07 -07005222 (tl + (k >> 1)), cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005223 *(ta + (k & 1)) = !(p->eobs[block] == 0);
5224 *(tl + (k >> 1)) = !(p->eobs[block] == 0);
Yushin Cho38395482017-01-03 13:10:41 -08005225#else
5226 thisrate += x->rate;
Fergus Simpson4063a682017-02-28 16:52:22 -08005227#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005228#if CONFIG_EXT_TX
5229 if (tx_size == TX_8X4) {
5230 *(ta + (k & 1) + 1) = *(ta + (k & 1));
5231 }
5232 if (tx_size == TX_4X8) {
5233 *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
5234 }
5235#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236 rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
5237 rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
Yaowu Xuf883b422016-08-30 14:01:10 -07005238 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239 if (rd >= best_yrd) return INT64_MAX;
5240 }
5241 }
5242
5243 *distortion = thisdistortion;
5244 *labelyrate = thisrate;
5245 *sse = thissse;
5246
5247 return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
5248}
5249
5250typedef struct {
5251 int eobs;
5252 int brate;
5253 int byrate;
5254 int64_t bdist;
5255 int64_t bsse;
5256 int64_t brdcost;
5257 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005258 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005259#if CONFIG_EXT_INTER
5260 int_mv ref_mv[2];
5261#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005262
5263#if CONFIG_CB4X4
5264 ENTROPY_CONTEXT ta[4];
5265 ENTROPY_CONTEXT tl[4];
5266#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267 ENTROPY_CONTEXT ta[2];
5268 ENTROPY_CONTEXT tl[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005269#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005270} SEG_RDSTAT;
5271
5272typedef struct {
5273 int_mv *ref_mv[2];
5274 int_mv mvp;
5275
5276 int64_t segment_rd;
5277 int r;
5278 int64_t d;
5279 int64_t sse;
5280 int segment_yrate;
5281 PREDICTION_MODE modes[4];
5282#if CONFIG_EXT_INTER
5283 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5284#else
5285 SEG_RDSTAT rdstat[4][INTER_MODES];
5286#endif // CONFIG_EXT_INTER
5287 int mvthresh;
5288} BEST_SEG_INFO;
5289
Alex Converse0fa0f422017-04-24 12:51:14 -07005290static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5291 return (mv->row >> 3) < mv_limits->row_min ||
5292 (mv->row >> 3) > mv_limits->row_max ||
5293 (mv->col >> 3) < mv_limits->col_min ||
5294 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005295}
5296
5297static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
5298 MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
5299 struct macroblock_plane *const p = &x->plane[0];
5300 struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
5301
5302 p->src.buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005303 &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005304 assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
5305 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005306 &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307 if (has_second_ref(mbmi))
5308 pd->pre[1].buf =
5309 &pd->pre[1]
Yaowu Xuf883b422016-08-30 14:01:10 -07005310 .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005311}
5312
5313static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
5314 struct buf_2d orig_pre[2]) {
5315 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
5316 x->plane[0].src = orig_src;
5317 x->e_mbd.plane[0].pre[0] = orig_pre[0];
5318 if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
5319}
5320
5321// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5322// TODO(aconverse): Find out if this is still productive then clean up or remove
5323static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005324 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005325#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005326 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005327#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005328 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005329 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5330 int mi_row, int mi_col) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005331 int_mv zeromv[2];
5332 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
5333 int cur_frm;
David Barker45390c12017-02-20 14:44:40 +00005334 (void)mi_row;
5335 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005336 for (cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
5337#if CONFIG_GLOBAL_MOTION
5338 if (this_mode == ZEROMV
5339#if CONFIG_EXT_INTER
5340 || this_mode == ZERO_ZEROMV
5341#endif // CONFIG_EXT_INTER
5342 )
5343 zeromv[cur_frm].as_int =
5344 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005345 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005346 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005347 .as_int;
5348 else
5349#endif // CONFIG_GLOBAL_MOTION
5350 zeromv[cur_frm].as_int = 0;
5351 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005352#if !CONFIG_EXT_INTER
5353 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005354#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005356 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005358 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005359 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005360 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005361 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5362 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5363 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364
Yaowu Xuc27fc142016-08-22 16:08:15 -07005365 if (this_mode == NEARMV) {
5366 if (c1 > c3) return 0;
5367 } else if (this_mode == NEARESTMV) {
5368 if (c2 > c3) return 0;
5369 } else {
5370 assert(this_mode == ZEROMV);
5371 if (ref_frames[1] <= INTRA_FRAME) {
5372 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5373 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5374 return 0;
5375 } else {
5376 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5377 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5378 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5379 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5380 return 0;
5381 }
5382 }
5383 }
5384#if CONFIG_EXT_INTER
5385 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
5386 this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
5387 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005388 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5389 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005390 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005391 int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
5392 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5393 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
5394 int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
5395 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005396
5397 if (this_mode == NEAREST_NEARMV) {
5398 if (c1 > c3) return 0;
5399 } else if (this_mode == NEAREST_NEARESTMV) {
5400 if (c2 > c3) return 0;
5401 } else if (this_mode == NEAR_NEARESTMV) {
5402 if (c4 > c3) return 0;
5403 } else if (this_mode == NEAR_NEARMV) {
5404 if (c5 > c3) return 0;
5405 } else {
5406 assert(this_mode == ZERO_ZEROMV);
5407 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5408 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
5409 (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
5410 frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
5411 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
5412 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
5413 (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
5414 frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
5415 return 0;
5416 }
5417 }
5418#endif // CONFIG_EXT_INTER
5419 return 1;
5420}
5421
Urvang Joshi52648442016-10-13 17:27:51 -07005422static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5423 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5424 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005425#if CONFIG_EXT_INTER
5426 int_mv *ref_mv_sub8x8[2],
Fergus Simpson4063a682017-02-28 16:52:22 -08005427#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005428 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005429 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005430 const int pw = block_size_wide[bsize];
5431 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005432 MACROBLOCKD *xd = &x->e_mbd;
5433 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005434 // This function should only ever be called for compound modes
5435 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005436 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005437 int_mv ref_mv[2];
5438 int ite, ref;
5439#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005440 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005441 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5442 mbmi->interp_filter[3],
5443 };
5444#else
James Zern7b9407a2016-05-18 23:48:05 -07005445 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005446#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005447 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005448 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005449#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005450 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5451 const int ic = block & 1;
5452 const int ir = (block - ic) >> 1;
5453 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5454 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005455#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005456 int is_global[2];
5457 for (ref = 0; ref < 2; ++ref) {
5458 WarpedMotionParams *const wm =
5459 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5460 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5461 }
5462#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005463#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005464
5465 // Do joint motion search in compound mode to get more accurate mv.
5466 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5467 int last_besterr[2] = { INT_MAX, INT_MAX };
5468 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005469 av1_get_scaled_ref_frame(cpi, refs[0]),
5470 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 };
5472
5473// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005474#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5476 uint8_t *second_pred;
5477#else
5478 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005479#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005480
Jingning Han61418bb2017-01-23 17:12:48 -08005481#if CONFIG_EXT_INTER && CONFIG_CB4X4
5482 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005483#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005484
Yaowu Xuc27fc142016-08-22 16:08:15 -07005485 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005486#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005487 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5488 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5489 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005490#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005491 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5492
5493 if (scaled_ref_frame[ref]) {
5494 int i;
5495 // Swap out the reference frame for a version that's been scaled to
5496 // match the resolution of the current frame, allowing the existing
5497 // motion search code to be used without additional modifications.
5498 for (i = 0; i < MAX_MB_PLANE; i++)
5499 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005500 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5501 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005502 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503 }
5504
5505// Since we have scaled the reference frames to match the size of the current
5506// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005507#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005508 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5509 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005510#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005511 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5512 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005513#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005514
5515 // Allow joint search multiple times iteratively for each reference frame
5516 // and break out of the search loop if it couldn't find a better mv.
5517 for (ite = 0; ite < 4; ite++) {
5518 struct buf_2d ref_yv12[2];
5519 int bestsme = INT_MAX;
5520 int sadpb = x->sadperbit16;
5521 MV *const best_mv = &x->best_mv.as_mv;
5522 int search_range = 3;
5523
Alex Converse0fa0f422017-04-24 12:51:14 -07005524 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525 int id = ite % 2; // Even iterations search in the first reference frame,
5526 // odd iterations search in the second. The predictor
5527 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005528 const int plane = 0;
5529 ConvolveParams conv_params = get_conv_params(0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005530#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5531 WarpTypesAllowed warp_types;
5532#if CONFIG_GLOBAL_MOTION
5533 warp_types.global_warp_allowed = is_global[!id];
5534#endif // CONFIG_GLOBAL_MOTION
5535#if CONFIG_WARPED_MOTION
5536 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5537#endif // CONFIG_WARPED_MOTION
5538#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005539
5540 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005541 ref_yv12[0] = xd->plane[plane].pre[0];
5542 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543
5544#if CONFIG_DUAL_FILTER
5545 // reload the filter types
5546 interp_filter[0] =
5547 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5548 interp_filter[1] =
5549 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005550#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551
5552// Get the prediction block from the 'other' reference frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005553#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005554 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5555 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005556 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005557 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5558 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005559#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5560 &warp_types, p_col, p_row,
5561#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005562 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005563 } else {
5564 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005565#endif // CONFIG_HIGHBITDEPTH
Angie Chiang9f45bc42017-01-13 16:27:54 -08005566 av1_build_inter_predictor(
5567 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5568 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005569#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5570 &warp_types, p_col, p_row, plane, !id,
5571#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005572 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005573#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005575#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005576
5577 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005578 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005579 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005580
5581 // Use the mv result from the single mode as mv predictor.
5582 *best_mv = frame_mv[refs[id]].as_mv;
5583
5584 best_mv->col >>= 3;
5585 best_mv->row >>= 3;
5586
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005587 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005588
5589 // Small-range full-pixel motion search.
5590 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005591 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
5592 &ref_mv[id].as_mv, second_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593 if (bestsme < INT_MAX)
Yaowu Xuf883b422016-08-30 14:01:10 -07005594 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5595 second_pred, &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005596
Alex Converse0fa0f422017-04-24 12:51:14 -07005597 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005598
5599 if (bestsme < INT_MAX) {
5600 int dis; /* TODO: use dis in distortion calculation later. */
5601 unsigned int sse;
5602 if (cpi->sf.use_upsampled_references) {
5603 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005604 struct buf_2d backup_pred = pd->pre[0];
5605 const YV12_BUFFER_CONFIG *upsampled_ref =
5606 get_upsampled_ref(cpi, refs[id]);
5607
5608 // Set pred for Y plane
Jingning Han91d9a792017-04-18 12:01:52 -07005609 setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610 upsampled_ref->y_crop_width,
5611 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5612 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5613 pd->subsampling_y);
5614
Jingning Han271bb2c2016-12-14 12:34:46 -08005615// If bsize < BLOCK_8X8, adjust pred pointer for this block
5616#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617 if (bsize < BLOCK_8X8)
5618 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005619 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5620 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005622#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005623
5624 bestsme = cpi->find_fractional_mv_step(
5625 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5626 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5627 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5628 &dis, &sse, second_pred, pw, ph, 1);
5629
5630 // Restore the reference frames.
5631 pd->pre[0] = backup_pred;
5632 } else {
5633 (void)block;
5634 bestsme = cpi->find_fractional_mv_step(
5635 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5636 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5637 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5638 &dis, &sse, second_pred, pw, ph, 0);
5639 }
5640 }
5641
5642 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005643 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005644
5645 if (bestsme < last_besterr[id]) {
5646 frame_mv[refs[id]].as_mv = *best_mv;
5647 last_besterr[id] = bestsme;
5648 } else {
5649 break;
5650 }
5651 }
5652
5653 *rate_mv = 0;
5654
5655 for (ref = 0; ref < 2; ++ref) {
5656 if (scaled_ref_frame[ref]) {
5657 // Restore the prediction frame pointers to their unscaled versions.
5658 int i;
5659 for (i = 0; i < MAX_MB_PLANE; i++)
5660 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5661 }
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005662 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Jingning Han61418bb2017-01-23 17:12:48 -08005663#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005665#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005666 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5667 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5668 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005669#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005670 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005671 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5672 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5673 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005674#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 }
5676}
5677
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005678#if !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005679static void update_mv_search_and_seg_mvs(
5680 int *const run_mv_search, int_mv *const seg_mvs, int has_second_rf,
5681 const MV_REFERENCE_FRAME *const ref_frame,
5682 const SEG_RDSTAT *const ref_rdstat, int_mv *const bsi_ref_mv[2]) {
5683 if (has_second_rf) {
5684 if (seg_mvs[ref_frame[0]].as_int == ref_rdstat->mvs[0].as_int &&
5685 ref_rdstat->mvs[0].as_int != INVALID_MV)
5686 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
5687 --*run_mv_search;
5688
5689 if (seg_mvs[ref_frame[1]].as_int == ref_rdstat->mvs[1].as_int &&
5690 ref_rdstat->mvs[1].as_int != INVALID_MV)
5691 if (bsi_ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
5692 --*run_mv_search;
5693 } else {
5694 if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
5695 ref_rdstat->mvs[0].as_int != INVALID_MV) {
5696 *run_mv_search = 0;
5697 seg_mvs[ref_frame[0]].as_int = ref_rdstat->mvs[0].as_int;
5698 }
5699 }
5700}
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005701#endif // !CONFIG_EXT_INTER
Urvang Joshif7751be2017-04-27 12:50:39 -07005702
Yushin Cho482016d2017-01-06 14:06:13 -08005703static int64_t rd_pick_inter_best_sub8x8_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07005704 const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005705 int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
5706 int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005707 int mvthresh, int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005708#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005709 int_mv compound_seg_newmvs[4][2],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005710#endif // CONFIG_EXT_INTER
5711 BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
5712 BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713 int_mv tmp_ref_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005714 MACROBLOCKD *xd = &x->e_mbd;
5715 MODE_INFO *mi = xd->mi[0];
5716 MB_MODE_INFO *mbmi = &mi->mbmi;
5717 int mode_idx;
5718 int k, br = 0, idx, idy;
5719 int64_t bd = 0, block_sse = 0;
5720 PREDICTION_MODE this_mode;
Urvang Joshi52648442016-10-13 17:27:51 -07005721 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005722 struct macroblock_plane *const p = &x->plane[0];
5723 struct macroblockd_plane *const pd = &xd->plane[0];
5724 const int label_count = 4;
5725 int64_t this_segment_rd = 0;
5726 int label_mv_thresh;
5727 int segmentyrate = 0;
5728 const BLOCK_SIZE bsize = mbmi->sb_type;
5729 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
5730 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
Jingning Han276c2942016-12-05 12:37:02 -08005731#if CONFIG_CB4X4
5732 ENTROPY_CONTEXT t_above[4], t_left[4];
5733#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734 ENTROPY_CONTEXT t_above[2], t_left[2];
Fergus Simpson4063a682017-02-28 16:52:22 -08005735#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005736 int subpelmv = 1, have_ref = 0;
5737 const int has_second_rf = has_second_ref(mbmi);
5738 const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
5739 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005740#if CONFIG_PVQ
5741 od_rollback_buffer pre_buf;
5742
5743 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005744#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005745#if CONFIG_EXT_TX && CONFIG_RECT_TX
5746 mbmi->tx_size =
5747 xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
5748#else
5749 mbmi->tx_size = TX_4X4;
5750#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5751
Yaowu Xuf883b422016-08-30 14:01:10 -07005752 av1_zero(*bsi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005753
5754 bsi->segment_rd = best_rd;
5755 bsi->ref_mv[0] = best_ref_mv;
5756 bsi->ref_mv[1] = second_best_ref_mv;
5757 bsi->mvp.as_int = best_ref_mv->as_int;
5758 bsi->mvthresh = mvthresh;
5759
5760 for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
5761
Yaowu Xuc27fc142016-08-22 16:08:15 -07005762 for (idx = 0; idx < 4; ++idx) {
5763 for (k = NEARESTMV; k <= NEWMV; ++k) {
5764 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
5765 bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
5766
5767 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
5768 bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
5769 }
5770 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005771
5772 memcpy(t_above, pd->above_context, sizeof(t_above));
5773 memcpy(t_left, pd->left_context, sizeof(t_left));
5774
5775 // 64 makes this threshold really big effectively
5776 // making it so that we very rarely check mvs on
5777 // segments. setting this to 1 would make mv thresh
5778 // roughly equal to what it is for macroblocks
5779 label_mv_thresh = 1 * bsi->mvthresh / label_count;
5780
5781 // Segmentation method overheads
5782 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
5783 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
5784 // TODO(jingning,rbultje): rewrite the rate-distortion optimization
5785 // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
5786 int_mv mode_mv[MB_MODE_COUNT][2];
5787 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
5788 PREDICTION_MODE mode_selected = ZEROMV;
Urvang Joshi454280d2016-10-14 16:51:44 -07005789 int64_t new_best_rd = INT64_MAX;
5790 const int index = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005791 int ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005792 CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
5793 uint8_t ref_mv_count[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005794#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005795 int_mv ref_mvs_sub8x8[2][2];
5796#endif // CONFIG_EXT_INTER
Yushin Cho77bba8d2016-11-04 16:36:56 -07005797#if CONFIG_PVQ
5798 od_rollback_buffer idx_buf, post_buf;
5799 od_encode_checkpoint(&x->daala_enc, &idx_buf);
5800 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005801#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005802
5803 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
5804 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
5805#if CONFIG_EXT_INTER
5806 int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
Yaowu Xu531d6af2017-03-07 17:48:52 -08005807 av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
5808 mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005810#if CONFIG_GLOBAL_MOTION
5811 frame_mv[ZEROMV][frame].as_int =
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -08005812 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005813 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005814 mi_col, mi_row, index)
David Barkercdcac6d2016-12-01 17:04:16 +00005815 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07005816#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005817 frame_mv[ZEROMV][frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07005818#endif // CONFIG_GLOBAL_MOTION
Urvang Joshi454280d2016-10-14 16:51:44 -07005819 av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -07005820 ref_mv_stack[ref], &ref_mv_count[ref],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005822 mv_ref_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005823#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005824 &frame_mv[NEARESTMV][frame],
5825 &frame_mv[NEARMV][frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005826
Yaowu Xuc27fc142016-08-22 16:08:15 -07005827 tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
5828 lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
5829 bsi->ref_mv[ref] = &tmp_ref_mv[ref];
5830 mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005831
5832#if CONFIG_EXT_INTER
5833 mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
5834 mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
Yaowu Xuf883b422016-08-30 14:01:10 -07005835 av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
5836 &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005837
5838 if (has_second_rf) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005839#if CONFIG_GLOBAL_MOTION
5840 frame_mv[ZERO_ZEROMV][frame].as_int =
5841 gm_get_motion_vector(&cm->global_motion[frame],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005842 cm->allow_high_precision_mv, mbmi->sb_type,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005843 mi_col, mi_row, index)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005844 .as_int;
5845#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005846 frame_mv[ZERO_ZEROMV][frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005847#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848 frame_mv[NEAREST_NEARESTMV][frame].as_int =
5849 frame_mv[NEARESTMV][frame].as_int;
5850
5851 if (ref == 0) {
5852 frame_mv[NEAREST_NEARMV][frame].as_int =
5853 frame_mv[NEARESTMV][frame].as_int;
5854 frame_mv[NEAR_NEARESTMV][frame].as_int =
5855 frame_mv[NEARMV][frame].as_int;
5856 frame_mv[NEAREST_NEWMV][frame].as_int =
5857 frame_mv[NEARESTMV][frame].as_int;
5858 frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5859 frame_mv[NEAR_NEARMV][frame].as_int =
5860 frame_mv[NEARMV][frame].as_int;
5861 } else if (ref == 1) {
5862 frame_mv[NEAREST_NEARMV][frame].as_int =
5863 frame_mv[NEARMV][frame].as_int;
5864 frame_mv[NEAR_NEARESTMV][frame].as_int =
5865 frame_mv[NEARESTMV][frame].as_int;
5866 frame_mv[NEW_NEARESTMV][frame].as_int =
5867 frame_mv[NEARESTMV][frame].as_int;
5868 frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
5869 frame_mv[NEAR_NEARMV][frame].as_int =
5870 frame_mv[NEARMV][frame].as_int;
5871 }
5872 }
5873#endif // CONFIG_EXT_INTER
5874 }
5875
5876// search for the best motion vector on this segment
5877#if CONFIG_EXT_INTER
5878 for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005879 this_mode <= (has_second_rf ? NEW_NEWMV : NEWMV); ++this_mode)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005880#else
5881 for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
5882#endif // CONFIG_EXT_INTER
5883 {
5884 const struct buf_2d orig_src = x->plane[0].src;
5885 struct buf_2d orig_pre[2];
5886 // This flag controls if the motion estimation will kick off. When it
5887 // is set to a non-zero value, the encoder will force motion estimation.
5888 int run_mv_search = 0;
5889
5890 mode_idx = INTER_OFFSET(this_mode);
5891#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005892 for (ref = 0; ref < 1 + has_second_rf; ++ref)
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005893 bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[0][ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005894#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005895 bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005896 if (!(inter_mode_mask & (1 << this_mode))) continue;
5897
Yaowu Xuc27fc142016-08-22 16:08:15 -07005898 run_mv_search = 2;
5899#if !CONFIG_EXT_INTER
5900 if (filter_idx > 0 && this_mode == NEWMV) {
Urvang Joshif7751be2017-04-27 12:50:39 -07005901 const BEST_SEG_INFO *ref_bsi = bsi_buf;
5902 const SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005903
Urvang Joshif7751be2017-04-27 12:50:39 -07005904 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5905 has_second_rf, mbmi->ref_frame,
5906 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005907
5908 if (run_mv_search != 0 && filter_idx > 1) {
5909 ref_bsi = bsi_buf + 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07005910 ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005911 run_mv_search = 2;
Urvang Joshif7751be2017-04-27 12:50:39 -07005912 update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
5913 has_second_rf, mbmi->ref_frame,
5914 ref_rdstat, bsi->ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005915 }
5916 }
Fergus Simpson4063a682017-02-28 16:52:22 -08005917#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918
Sarah Parkere5299862016-08-16 14:57:37 -07005919#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00005920 if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07005921 (!has_second_rf ||
David Barkercf3d0b02016-11-10 10:14:49 +00005922 cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
Sarah Parkere5299862016-08-16 14:57:37 -07005923#endif // CONFIG_GLOBAL_MOTION
5924
5925 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005926#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005927 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005928#endif // CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07005929 frame_mv, this_mode, mbmi->ref_frame, bsize,
David Barker45390c12017-02-20 14:44:40 +00005930 index, mi_row, mi_col))
Sarah Parkere5299862016-08-16 14:57:37 -07005931 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005932
5933 memcpy(orig_pre, pd->pre, sizeof(orig_pre));
Urvang Joshi454280d2016-10-14 16:51:44 -07005934 memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
5935 sizeof(bsi->rdstat[index][mode_idx].ta));
5936 memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
5937 sizeof(bsi->rdstat[index][mode_idx].tl));
Yushin Cho77bba8d2016-11-04 16:36:56 -07005938#if CONFIG_PVQ
5939 od_encode_rollback(&x->daala_enc, &idx_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005940#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005941
5942 // motion search for newmv (single predictor case only)
5943 if (!has_second_rf &&
5944#if CONFIG_EXT_INTER
5945 have_newmv_in_inter_mode(this_mode) &&
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005946 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005947#else
5948 this_mode == NEWMV &&
Urvang Joshi454280d2016-10-14 16:51:44 -07005949 (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005950 run_mv_search)
5951#endif // CONFIG_EXT_INTER
5952 ) {
5953 int step_param = 0;
5954 int bestsme = INT_MAX;
5955 int sadpb = x->sadperbit4;
5956 MV mvp_full;
5957 int max_mv;
5958 int cost_list[5];
Alex Converse0fa0f422017-04-24 12:51:14 -07005959 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005960
5961 /* Is the best so far sufficiently good that we cant justify doing
5962 * and new motion search. */
Urvang Joshi454280d2016-10-14 16:51:44 -07005963 if (new_best_rd < label_mv_thresh) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005964
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965#if CONFIG_EXT_INTER
Thomas Daede6eca8352017-03-17 14:14:12 -07005966 bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005967#else
5968// use previous block's result as next block's MV predictor.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005969#endif // CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07005970 max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
5971 : AOMMAX(abs(bsi->mvp.as_mv.row),
5972 abs(bsi->mvp.as_mv.col)) >>
5973 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974
5975 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5976 // Take wtd average of the step_params based on the last frame's
5977 // max mv magnitude and the best ref mvs of the current block for
5978 // the given reference.
5979 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005980 (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005981 } else {
5982 step_param = cpi->mv_step_param;
5983 }
5984
Yaowu Xuc27fc142016-08-22 16:08:15 -07005985 mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
5986 mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005987
5988 if (cpi->sf.adaptive_motion_search) {
5989 mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
5990 mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
Yaowu Xuf883b422016-08-30 14:01:10 -07005991 step_param = AOMMAX(step_param, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005992 }
5993
5994 // adjust src pointer for this block
Urvang Joshi454280d2016-10-14 16:51:44 -07005995 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005996
Alex Converse0fa0f422017-04-24 12:51:14 -07005997 av1_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005998
5999 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6000
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006001 av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07006002 bestsme = av1_full_pixel_search(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003 cpi, x, bsize, &mvp_full, step_param, sadpb,
6004 cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
6005 &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
6006
Alex Converse0fa0f422017-04-24 12:51:14 -07006007 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006008
6009 if (bestsme < INT_MAX) {
6010 int distortion;
6011 if (cpi->sf.use_upsampled_references) {
6012 int best_mv_var;
6013 const int try_second =
6014 x->second_best_mv.as_int != INVALID_MV &&
6015 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006016 const int pw = block_size_wide[bsize];
6017 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006018 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006019 struct buf_2d backup_pred = pd->pre[0];
6020 const YV12_BUFFER_CONFIG *upsampled_ref =
6021 get_upsampled_ref(cpi, mbmi->ref_frame[0]);
6022
6023 // Set pred for Y plane
6024 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006025 &pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006026 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6027 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6028 pd->subsampling_x, pd->subsampling_y);
6029
6030 // adjust pred pointer for this block
6031 pd->pre[0].buf =
Urvang Joshi454280d2016-10-14 16:51:44 -07006032 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
Yaowu Xuf883b422016-08-30 14:01:10 -07006033 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006034 << 3];
6035
6036 best_mv_var = cpi->find_fractional_mv_step(
6037 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6038 x->errorperbit, &cpi->fn_ptr[bsize],
6039 cpi->sf.mv.subpel_force_stop,
6040 cpi->sf.mv.subpel_iters_per_step,
6041 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6042 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
6043 1);
6044
6045 if (try_second) {
6046 int this_var;
6047 MV best_mv = x->best_mv.as_mv;
6048 const MV ref_mv = bsi->ref_mv[0]->as_mv;
Alex Converse0fa0f422017-04-24 12:51:14 -07006049 const int minc =
6050 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6051 const int maxc =
6052 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6053 const int minr =
6054 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6055 const int maxr =
6056 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057
6058 x->best_mv = x->second_best_mv;
6059 if (x->best_mv.as_mv.row * 8 <= maxr &&
6060 x->best_mv.as_mv.row * 8 >= minr &&
6061 x->best_mv.as_mv.col * 8 <= maxc &&
6062 x->best_mv.as_mv.col * 8 >= minc) {
6063 this_var = cpi->find_fractional_mv_step(
6064 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6065 x->errorperbit, &cpi->fn_ptr[bsize],
6066 cpi->sf.mv.subpel_force_stop,
6067 cpi->sf.mv.subpel_iters_per_step,
6068 cond_cost_list(cpi, cost_list), x->nmvjointcost,
6069 x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
6070 NULL, pw, ph, 1);
6071 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6072 x->best_mv.as_mv = best_mv;
6073 }
6074 }
6075
6076 // Restore the reference frames.
6077 pd->pre[0] = backup_pred;
6078 } else {
6079 cpi->find_fractional_mv_step(
6080 x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
6081 x->errorperbit, &cpi->fn_ptr[bsize],
6082 cpi->sf.mv.subpel_force_stop,
6083 cpi->sf.mv.subpel_iters_per_step,
6084 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6085 &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
6086 }
6087
6088// save motion search result for use in compound prediction
6089#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006090 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006091#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006092 seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006093#endif // CONFIG_EXT_INTER
6094 }
6095
6096 if (cpi->sf.adaptive_motion_search)
6097 x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
6098
6099#if CONFIG_EXT_INTER
6100 mode_mv[this_mode][0] = x->best_mv;
6101#else
6102 mode_mv[NEWMV][0] = x->best_mv;
6103#endif // CONFIG_EXT_INTER
6104
6105 // restore src pointers
6106 mi_buf_restore(x, orig_src, orig_pre);
6107 }
6108
6109 if (has_second_rf) {
6110#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006111 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6112 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006113#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006114 if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
6115 seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006116#endif // CONFIG_EXT_INTER
6117 continue;
6118 }
6119
6120#if CONFIG_DUAL_FILTER
6121 (void)run_mv_search;
Fergus Simpson4063a682017-02-28 16:52:22 -08006122#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123
6124 if (has_second_rf &&
6125#if CONFIG_EXT_INTER
6126 this_mode == NEW_NEWMV &&
6127#else
6128 this_mode == NEWMV &&
6129#endif // CONFIG_EXT_INTER
6130#if CONFIG_DUAL_FILTER
6131 (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
6132#else
6133 (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
Fergus Simpson4063a682017-02-28 16:52:22 -08006134#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006135 {
6136 // adjust src pointers
Urvang Joshi454280d2016-10-14 16:51:44 -07006137 mi_buf_shift(x, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006138 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6139 int rate_mv;
Zoe Liu122f3942017-04-25 11:18:38 -07006140 frame_mv[this_mode][mbmi->ref_frame[0]].as_int =
6141 seg_mvs[index][mbmi->ref_frame[0]].as_int;
6142 frame_mv[this_mode][mbmi->ref_frame[1]].as_int =
6143 seg_mvs[index][mbmi->ref_frame[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006144 joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
6145 mi_col,
6146#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006147 bsi->ref_mv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006148#endif // CONFIG_EXT_INTER
Zoe Liu122f3942017-04-25 11:18:38 -07006149 &rate_mv, index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006150#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006151 compound_seg_newmvs[index][0].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006152 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006153 compound_seg_newmvs[index][1].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006154 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6155#else
Urvang Joshi454280d2016-10-14 16:51:44 -07006156 seg_mvs[index][mbmi->ref_frame[0]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006158 seg_mvs[index][mbmi->ref_frame[1]].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
6160#endif // CONFIG_EXT_INTER
6161 }
6162 // restore src pointers
6163 mi_buf_restore(x, orig_src, orig_pre);
6164 }
6165
Urvang Joshi454280d2016-10-14 16:51:44 -07006166 bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
6167 cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
Urvang Joshi454280d2016-10-14 16:51:44 -07006168 seg_mvs[index],
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006169#if CONFIG_EXT_INTER
6170 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006171#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00006172 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006173
6174 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006175 bsi->rdstat[index][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006176 mode_mv[this_mode][ref].as_int;
6177 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006178 bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006179 mode_mv[this_mode][ref].as_int;
6180 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006181 bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006182 mode_mv[this_mode][ref].as_int;
Urvang Joshi454280d2016-10-14 16:51:44 -07006183 bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
6184 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006185 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006186 bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
6187 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006188 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006189 bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
6190 mi->bmi[index].pred_mv[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006191#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006192 bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193 bsi->ref_mv[ref]->as_int;
6194 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006195 bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 bsi->ref_mv[ref]->as_int;
6197 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006198 bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
Yaowu Xuc27fc142016-08-22 16:08:15 -07006199 bsi->ref_mv[ref]->as_int;
6200#endif // CONFIG_EXT_INTER
6201 }
6202
6203 // Trap vectors that reach beyond the UMV borders
Alex Converse0fa0f422017-04-24 12:51:14 -07006204 if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) ||
6205 (has_second_rf &&
6206 mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv)))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006207 continue;
6208
6209 if (filter_idx > 0) {
6210 BEST_SEG_INFO *ref_bsi = bsi_buf;
6211 subpelmv = 0;
6212 have_ref = 1;
6213
6214 for (ref = 0; ref < 1 + has_second_rf; ++ref) {
6215 subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
6216#if CONFIG_EXT_INTER
6217 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006218 have_ref &=
6219 ((mode_mv[this_mode][ref].as_int ==
6220 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6221 (bsi->ref_mv[ref]->as_int ==
6222 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006223 else
6224#endif // CONFIG_EXT_INTER
6225 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006226 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 }
6228
Urvang Joshi454280d2016-10-14 16:51:44 -07006229 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006230
6231 if (filter_idx > 1 && !subpelmv && !have_ref) {
6232 ref_bsi = bsi_buf + 1;
6233 have_ref = 1;
6234 for (ref = 0; ref < 1 + has_second_rf; ++ref)
6235#if CONFIG_EXT_INTER
6236 if (have_newmv_in_inter_mode(this_mode))
Urvang Joshi454280d2016-10-14 16:51:44 -07006237 have_ref &=
6238 ((mode_mv[this_mode][ref].as_int ==
6239 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
6240 (bsi->ref_mv[ref]->as_int ==
6241 ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006242 else
6243#endif // CONFIG_EXT_INTER
6244 have_ref &= mode_mv[this_mode][ref].as_int ==
Urvang Joshi454280d2016-10-14 16:51:44 -07006245 ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006246
Urvang Joshi454280d2016-10-14 16:51:44 -07006247 have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006248 }
6249
6250 if (!subpelmv && have_ref &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006251 ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006252 bsi->rdstat[index][mode_idx].byrate =
6253 ref_bsi->rdstat[index][mode_idx].byrate;
6254 bsi->rdstat[index][mode_idx].bdist =
6255 ref_bsi->rdstat[index][mode_idx].bdist;
6256 bsi->rdstat[index][mode_idx].bsse =
6257 ref_bsi->rdstat[index][mode_idx].bsse;
6258 bsi->rdstat[index][mode_idx].brate +=
6259 ref_bsi->rdstat[index][mode_idx].byrate;
6260 bsi->rdstat[index][mode_idx].eobs =
6261 ref_bsi->rdstat[index][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006262
Urvang Joshi454280d2016-10-14 16:51:44 -07006263 bsi->rdstat[index][mode_idx].brdcost =
6264 RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
6265 bsi->rdstat[index][mode_idx].bdist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006266
Urvang Joshi454280d2016-10-14 16:51:44 -07006267 memcpy(bsi->rdstat[index][mode_idx].ta,
6268 ref_bsi->rdstat[index][mode_idx].ta,
6269 sizeof(bsi->rdstat[index][mode_idx].ta));
6270 memcpy(bsi->rdstat[index][mode_idx].tl,
6271 ref_bsi->rdstat[index][mode_idx].tl,
6272 sizeof(bsi->rdstat[index][mode_idx].tl));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006274 bsi->rdstat[index + 1][mode_idx].eobs =
6275 ref_bsi->rdstat[index + 1][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006276 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006277 bsi->rdstat[index + 2][mode_idx].eobs =
6278 ref_bsi->rdstat[index + 2][mode_idx].eobs;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279
Urvang Joshi454280d2016-10-14 16:51:44 -07006280 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006281 // If the NEWMV mode is using the same motion vector as the
6282 // NEARESTMV mode, skip the rest rate-distortion calculations
6283 // and use the inferred motion vector modes.
6284 if (this_mode == NEWMV) {
6285 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006286 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006287 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006288 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006289 bsi->ref_mv[1]->as_int)
6290 continue;
6291 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006292 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293 bsi->ref_mv[0]->as_int)
6294 continue;
6295 }
6296 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006297 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006298 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006299#if CONFIG_PVQ
6300 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006301#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006302 }
6303 continue;
6304 }
6305 }
6306
Yushin Choab44fd12017-01-09 16:06:53 -08006307 bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
Urvang Joshi454280d2016-10-14 16:51:44 -07006308 cpi, x, bsi->segment_rd - this_segment_rd, index,
6309 &bsi->rdstat[index][mode_idx].byrate,
6310 &bsi->rdstat[index][mode_idx].bdist,
6311 &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
6312 bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313
Urvang Joshi454280d2016-10-14 16:51:44 -07006314 if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
6315 bsi->rdstat[index][mode_idx].brdcost += RDCOST(
6316 x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
6317 bsi->rdstat[index][mode_idx].brate +=
6318 bsi->rdstat[index][mode_idx].byrate;
6319 bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006320 if (num_4x4_blocks_wide > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006321 bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006322 if (num_4x4_blocks_high > 1)
Urvang Joshi454280d2016-10-14 16:51:44 -07006323 bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324 }
6325
Urvang Joshi454280d2016-10-14 16:51:44 -07006326 if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006327 // If the NEWMV mode is using the same motion vector as the
6328 // NEARESTMV mode, skip the rest rate-distortion calculations
6329 // and use the inferred motion vector modes.
6330 if (this_mode == NEWMV) {
6331 if (has_second_rf) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006332 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006333 bsi->ref_mv[0]->as_int &&
Urvang Joshi454280d2016-10-14 16:51:44 -07006334 bsi->rdstat[index][mode_idx].mvs[1].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006335 bsi->ref_mv[1]->as_int)
6336 continue;
6337 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07006338 if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07006339 bsi->ref_mv[0]->as_int)
6340 continue;
6341 }
6342 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006343 mode_selected = this_mode;
Urvang Joshi454280d2016-10-14 16:51:44 -07006344 new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006345
6346#if CONFIG_PVQ
6347 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006348#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006349 }
6350 } /*for each 4x4 mode*/
6351
Urvang Joshi454280d2016-10-14 16:51:44 -07006352 if (new_best_rd == INT64_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006353 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006354 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006355#if CONFIG_EXT_INTER
6356 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6357#else
6358 for (midx = 0; midx < INTER_MODES; ++midx)
6359#endif // CONFIG_EXT_INTER
6360 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6361 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006362#if CONFIG_PVQ
6363 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006364#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006365 return INT64_MAX;
6366 }
6367
6368 mode_idx = INTER_OFFSET(mode_selected);
Urvang Joshi454280d2016-10-14 16:51:44 -07006369 memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
6370 memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
Yushin Cho77bba8d2016-11-04 16:36:56 -07006371#if CONFIG_PVQ
6372 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006373#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006374
6375#if CONFIG_EXT_INTER
Urvang Joshi454280d2016-10-14 16:51:44 -07006376 bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006377 if (has_second_rf)
Urvang Joshi454280d2016-10-14 16:51:44 -07006378 bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006380 set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
6381 mode_mv[mode_selected], frame_mv, seg_mvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006382#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006383 compound_seg_newmvs[index],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006384#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006385 bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row,
6386 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006387
Urvang Joshi454280d2016-10-14 16:51:44 -07006388 br += bsi->rdstat[index][mode_idx].brate;
6389 bd += bsi->rdstat[index][mode_idx].bdist;
6390 block_sse += bsi->rdstat[index][mode_idx].bsse;
6391 segmentyrate += bsi->rdstat[index][mode_idx].byrate;
6392 this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006393
6394 if (this_segment_rd > bsi->segment_rd) {
6395 int iy, midx;
Urvang Joshi454280d2016-10-14 16:51:44 -07006396 for (iy = index + 1; iy < 4; ++iy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006397#if CONFIG_EXT_INTER
6398 for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
6399#else
6400 for (midx = 0; midx < INTER_MODES; ++midx)
6401#endif // CONFIG_EXT_INTER
6402 bsi->rdstat[iy][midx].brdcost = INT64_MAX;
6403 bsi->segment_rd = INT64_MAX;
Yushin Cho77bba8d2016-11-04 16:36:56 -07006404#if CONFIG_PVQ
6405 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006406#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006407 return INT64_MAX;
6408 }
6409 }
6410 } /* for each label */
Yushin Cho77bba8d2016-11-04 16:36:56 -07006411#if CONFIG_PVQ
6412 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08006413#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07006414
6415 bsi->r = br;
6416 bsi->d = bd;
6417 bsi->segment_yrate = segmentyrate;
6418 bsi->segment_rd = this_segment_rd;
6419 bsi->sse = block_sse;
6420
6421 // update the coding decisions
6422 for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
6423
Yushin Cho7a428ba2017-01-12 16:28:49 -08006424#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07006425 // Compute prediction (i.e. skip) and decoded distortion by daala-distortion.
Yushin Cho7a428ba2017-01-12 16:28:49 -08006426 {
6427 const int src_stride = p->src.stride;
6428 const int dst_stride = pd->dst.stride;
6429 uint8_t *src = p->src.buf;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006430 uint8_t *dst = pd->dst.buf;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006431 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006432 const int use_activity_masking = 0;
6433 const int qm = OD_HVS_QM;
6434 const int bsw = block_size_wide[plane_bsize];
6435 const int bsh = block_size_high[plane_bsize];
6436 int64_t rd1, rd2;
6437 int64_t daala_sse, daala_dist;
6438 TX_SIZE tx_size = mbmi->tx_size;
6439
6440#if CONFIG_HIGHBITDEPTH
6441 uint8_t *recon_8x8;
6442 DECLARE_ALIGNED(16, uint16_t, recon16[8 * 8]);
6443
6444 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6445 recon_8x8 = CONVERT_TO_BYTEPTR(recon16);
6446 else
6447 recon_8x8 = (uint8_t *)recon16;
6448#else
6449 DECLARE_ALIGNED(16, uint8_t, recon_8x8[8 * 8]);
6450#endif // CONFIG_HIGHBITDEPTH
6451
Yushin Cho7a428ba2017-01-12 16:28:49 -08006452#if CONFIG_PVQ
6453 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08006454#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08006455
Yushin Cho4483e3d2017-04-18 19:41:20 -07006456 // For each of sub8x8 prediction block in a 8x8 block
6457 for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08006458 for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
6459 int i = idy * 2 + idx;
Yushin Cho4483e3d2017-04-18 19:41:20 -07006460 const uint8_t *const src_sub8x8 =
6461 src + av1_raster_block_offset(BLOCK_8X8, i, p->src.stride);
6462 uint8_t *const dst_sub8x8 =
6463 dst + av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride);
6464 uint8_t *recon_sub8x8 = recon_8x8 + (idy * 8 + idx) * 4;
6465 const int txb_width = max_block_wide(xd, plane_bsize, 0);
6466 const int txb_height = max_block_high(xd, plane_bsize, 0);
6467 int idx_, idy_;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006468
6469 av1_build_inter_predictor_sub8x8(xd, 0, i, idy, idx, mi_row, mi_col);
Yushin Cho4483e3d2017-04-18 19:41:20 -07006470#if CONFIG_HIGHBITDEPTH
6471 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6472 aom_highbd_subtract_block(
6473 height, width,
6474 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6475 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride, xd->bd);
6476 } else {
6477 aom_subtract_block(
6478 height, width,
6479 av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
6480 src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6481 }
6482#else
6483 aom_subtract_block(
6484 bsh, bsw, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
6485 8, src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
6486#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006487
Yushin Cho4483e3d2017-04-18 19:41:20 -07006488#if CONFIG_HIGHBITDEPTH
6489 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6490 aom_highbd_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8,
6491 NULL, 0, NULL, 0, bsw, bsh, xd->bd);
6492 } else {
6493#endif // CONFIG_HIGHBITDEPTH
6494 aom_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8, NULL, 0,
6495 NULL, 0, bsw, bsh);
6496#if CONFIG_HIGHBITDEPTH
6497 }
6498#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08006499
Yushin Cho4483e3d2017-04-18 19:41:20 -07006500 // To get decoded pixels, do 4x4 xform and quant for each 4x4 block
6501 // in a sub8x8 prediction block. In case remaining parts of
6502 // sub8x8 inter mode rdo assume pd->dst stores predicted pixels,
6503 // use local buffer to store decoded pixels.
6504 for (idy_ = 0; idy_ < txb_height; idy_++) {
6505 for (idx_ = 0; idx_ < txb_width; idx_++) {
6506 int coeff_ctx = 0;
6507 const tran_low_t *dqcoeff;
6508 uint16_t eob;
6509 const PLANE_TYPE plane_type = PLANE_TYPE_Y;
6510 uint8_t *recon_4x4 = recon_sub8x8 + (idy_ * 8 + idx_) * 4;
6511 const int block_raster_idx = (idy + idy_) * 2 + (idx + idx_);
6512 const int block =
6513 av1_raster_order_to_block_index(tx_size, block_raster_idx);
6514 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006515
Yushin Cho4483e3d2017-04-18 19:41:20 -07006516 dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
6517 av1_xform_quant(cm, x, 0, block, idy + idy_, idx + idx_, BLOCK_8X8,
6518 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang7dec6c42017-05-03 17:58:17 -07006519 av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006520
Yushin Cho4483e3d2017-04-18 19:41:20 -07006521 eob = p->eobs[block];
6522 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size,
6523 recon_4x4, 8, eob);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006524 }
6525 }
6526 }
Yushin Cho4483e3d2017-04-18 19:41:20 -07006527 }
6528 // Compute daala-distortion for a 8x8 block
6529 daala_sse = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, 8, 8,
6530 qm, use_activity_masking, x->qindex)
6531 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006532
Yushin Cho4483e3d2017-04-18 19:41:20 -07006533 daala_dist = av1_daala_dist(src, src_stride, recon_8x8, 8, 8, 8, qm,
6534 use_activity_masking, x->qindex)
6535 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08006536
Yushin Cho4483e3d2017-04-18 19:41:20 -07006537 bsi->sse = daala_sse;
6538 bsi->d = daala_dist;
6539
6540 rd1 = RDCOST(x->rdmult, x->rddiv, bsi->r, bsi->d);
6541 rd2 = RDCOST(x->rdmult, x->rddiv, 0, bsi->sse);
6542 bsi->segment_rd = AOMMIN(rd1, rd2);
Yushin Cho7a428ba2017-01-12 16:28:49 -08006543 }
6544#endif // CONFIG_DAALA_DIST
6545
Yaowu Xuc27fc142016-08-22 16:08:15 -07006546 if (bsi->segment_rd > best_rd) return INT64_MAX;
6547 /* set it to the best */
6548 for (idx = 0; idx < 4; idx++) {
6549 mode_idx = INTER_OFFSET(bsi->modes[idx]);
6550 mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
6551 if (has_second_ref(mbmi))
6552 mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006553 mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006554 if (has_second_ref(mbmi))
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -07006555 mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006556#if CONFIG_EXT_INTER
6557 mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
6558 if (has_second_rf)
6559 mi->bmi[idx].ref_mv[1].as_int =
6560 bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
6561#endif // CONFIG_EXT_INTER
6562 x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
6563 mi->bmi[idx].as_mode = bsi->modes[idx];
6564 }
6565
6566 /*
6567 * used to set mbmi->mv.as_int
6568 */
6569 *returntotrate = bsi->r;
6570 *returndistortion = bsi->d;
6571 *returnyrate = bsi->segment_yrate;
Yaowu Xuf883b422016-08-30 14:01:10 -07006572 *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006573 *psse = bsi->sse;
6574 mbmi->mode = bsi->modes[3];
6575
6576 return bsi->segment_rd;
6577}
6578
Yaowu Xuf883b422016-08-30 14:01:10 -07006579static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006580 const MACROBLOCKD *xd, int segment_id,
6581 unsigned int *ref_costs_single,
6582 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07006583 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006584 int seg_ref_active =
6585 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6586 if (seg_ref_active) {
6587 memset(ref_costs_single, 0,
6588 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
6589 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
6590 *comp_mode_p = 128;
6591 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006592 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
6593 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006594
6595 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006596 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006597 *comp_mode_p = comp_inter_p;
6598 } else {
6599 *comp_mode_p = 128;
6600 }
6601
Yaowu Xuf883b422016-08-30 14:01:10 -07006602 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006603
6604 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006605 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
6606 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006607#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006608 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
6609 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
6610 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006611#endif // CONFIG_EXT_REFS
6612
Yaowu Xuf883b422016-08-30 14:01:10 -07006613 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006614
6615 ref_costs_single[LAST_FRAME] =
6616#if CONFIG_EXT_REFS
6617 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6618 ref_costs_single[BWDREF_FRAME] =
6619#endif // CONFIG_EXT_REFS
6620 ref_costs_single[GOLDEN_FRAME] =
6621 ref_costs_single[ALTREF_FRAME] = base_cost;
6622
6623#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006624 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6625 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6626 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6627 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6628 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6629 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006630
Yaowu Xuf883b422016-08-30 14:01:10 -07006631 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6632 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6633 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6634 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006635
Yaowu Xuf883b422016-08-30 14:01:10 -07006636 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6637 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006638
Yaowu Xuf883b422016-08-30 14:01:10 -07006639 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6640 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006641
Yaowu Xuf883b422016-08-30 14:01:10 -07006642 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6643 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006644#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006645 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6646 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6647 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006648
Yaowu Xuf883b422016-08-30 14:01:10 -07006649 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6650 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006651#endif // CONFIG_EXT_REFS
6652 } else {
6653 ref_costs_single[LAST_FRAME] = 512;
6654#if CONFIG_EXT_REFS
6655 ref_costs_single[LAST2_FRAME] = 512;
6656 ref_costs_single[LAST3_FRAME] = 512;
6657 ref_costs_single[BWDREF_FRAME] = 512;
6658#endif // CONFIG_EXT_REFS
6659 ref_costs_single[GOLDEN_FRAME] = 512;
6660 ref_costs_single[ALTREF_FRAME] = 512;
6661 }
6662
6663 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006664 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006665#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006666 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6667 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6668 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006669#endif // CONFIG_EXT_REFS
6670
Yaowu Xuf883b422016-08-30 14:01:10 -07006671 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006672
6673 ref_costs_comp[LAST_FRAME] =
6674#if CONFIG_EXT_REFS
6675 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6676#endif // CONFIG_EXT_REFS
6677 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6678
6679#if CONFIG_EXT_REFS
6680 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6681#endif // CONFIG_EXT_REFS
6682
6683#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006684 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6685 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6686 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6687 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006688
Yaowu Xuf883b422016-08-30 14:01:10 -07006689 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6690 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006691
Yaowu Xuf883b422016-08-30 14:01:10 -07006692 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6693 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006694
6695 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6696 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07006697 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6698 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006699#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006700 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6701 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006702#endif // CONFIG_EXT_REFS
6703 } else {
6704 ref_costs_comp[LAST_FRAME] = 512;
6705#if CONFIG_EXT_REFS
6706 ref_costs_comp[LAST2_FRAME] = 512;
6707 ref_costs_comp[LAST3_FRAME] = 512;
6708 ref_costs_comp[BWDREF_FRAME] = 512;
6709 ref_costs_comp[ALTREF_FRAME] = 512;
6710#endif // CONFIG_EXT_REFS
6711 ref_costs_comp[GOLDEN_FRAME] = 512;
6712 }
6713 }
6714}
6715
6716static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6717 int mode_index,
6718 int64_t comp_pred_diff[REFERENCE_MODES],
6719 int skippable) {
6720 MACROBLOCKD *const xd = &x->e_mbd;
6721
6722 // Take a snapshot of the coding context so it can be
6723 // restored if we decide to encode this way
6724 ctx->skip = x->skip;
6725 ctx->skippable = skippable;
6726 ctx->best_mode_index = mode_index;
6727 ctx->mic = *xd->mi[0];
6728 ctx->mbmi_ext = *x->mbmi_ext;
6729 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6730 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6731 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6732}
6733
clang-format55ce9e02017-02-15 22:27:12 -08006734static void setup_buffer_inter(
6735 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6736 BLOCK_SIZE block_size, int mi_row, int mi_col,
6737 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6738 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6739 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006740 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006741 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6742 MACROBLOCKD *const xd = &x->e_mbd;
6743 MODE_INFO *const mi = xd->mi[0];
6744 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6745 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6746 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6747
6748 assert(yv12 != NULL);
6749
6750 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6751 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006752 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753
6754 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006755 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
6756 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006757#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006758 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006759#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006760 candidates, mi_row, mi_col, NULL, NULL,
6761 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006762
6763 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006764 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6765 &frame_nearest_mv[ref_frame],
6766 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006767
Jingning Han271bb2c2016-12-14 12:34:46 -08006768// Further refinement that is encode side only to test the top few candidates
6769// in full and choose the best as the centre point for subsequent searches.
6770// The current implementation doesn't support scaling.
6771#if CONFIG_CB4X4
6772 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6773 block_size);
6774#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006775 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6776 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6777 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006778#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006779}
6780
Urvang Joshi52648442016-10-13 17:27:51 -07006781static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6782 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006783#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006784 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006785#endif // CONFIG_EXT_INTER
6786 int *rate_mv) {
6787 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006788 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006789 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6790 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6791 int bestsme = INT_MAX;
6792 int step_param;
6793 int sadpb = x->sadperbit16;
6794 MV mvp_full;
6795#if CONFIG_EXT_INTER
6796 int ref = mbmi->ref_frame[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006797#else
6798 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006799 int ref_idx = 0;
6800#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006801 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006802
Alex Converse0fa0f422017-04-24 12:51:14 -07006803 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006804 int cost_list[5];
6805
6806 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006807 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006808
6809 MV pred_mv[3];
6810 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6811 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6812 pred_mv[2] = x->pred_mv[ref];
6813
Yaowu Xuc27fc142016-08-22 16:08:15 -07006814 if (scaled_ref_frame) {
6815 int i;
6816 // Swap out the reference frame for a version that's been scaled to
6817 // match the resolution of the current frame, allowing the existing
6818 // motion search code to be used without additional modifications.
6819 for (i = 0; i < MAX_MB_PLANE; i++)
6820 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6821
Yaowu Xuf883b422016-08-30 14:01:10 -07006822 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006823 }
6824
Alex Converse0fa0f422017-04-24 12:51:14 -07006825 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006826
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006827 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006828
Yaowu Xuc27fc142016-08-22 16:08:15 -07006829 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006830 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006831 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6832 // Take wtd average of the step_params based on the last frame's
6833 // max mv magnitude and that based on the best ref mvs of the current
6834 // block for the given reference.
6835 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006836 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006837 2;
6838 } else {
6839 step_param = cpi->mv_step_param;
6840 }
6841
6842 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6843 int boffset =
6844 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006845 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6846 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006847 }
6848
6849 if (cpi->sf.adaptive_motion_search) {
6850 int bwl = b_width_log2_lookup[bsize];
6851 int bhl = b_height_log2_lookup[bsize];
6852 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6853
6854 if (tlevel < 5) step_param += 2;
6855
6856 // prev_mv_sad is not setup for dynamically scaled frames.
6857 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6858 int i;
6859 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6860 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6861 x->pred_mv[ref].row = 0;
6862 x->pred_mv[ref].col = 0;
6863 x->best_mv.as_int = INVALID_MV;
6864
6865 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006866 int j;
6867 for (j = 0; j < MAX_MB_PLANE; ++j)
6868 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006869 }
6870 return;
6871 }
6872 }
6873 }
6874 }
6875
Alex Converse0fa0f422017-04-24 12:51:14 -07006876 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006877
Yue Chene9638cc2016-10-10 12:37:54 -07006878#if CONFIG_MOTION_VAR
6879 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6880 mvp_full = mbmi->mv[0].as_mv;
6881 else
6882#endif // CONFIG_MOTION_VAR
6883 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006884
6885 mvp_full.col >>= 3;
6886 mvp_full.row >>= 3;
6887
6888 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6889
Yue Chene9638cc2016-10-10 12:37:54 -07006890#if CONFIG_MOTION_VAR
6891 switch (mbmi->motion_mode) {
6892 case SIMPLE_TRANSLATION:
6893#endif // CONFIG_MOTION_VAR
6894 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6895 sadpb, cond_cost_list(cpi, cost_list),
6896 &ref_mv, INT_MAX, 1);
6897#if CONFIG_MOTION_VAR
6898 break;
6899 case OBMC_CAUSAL:
6900 bestsme = av1_obmc_full_pixel_diamond(
6901 cpi, x, &mvp_full, step_param, sadpb,
6902 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6903 &(x->best_mv.as_mv), 0);
6904 break;
6905 default: assert("Invalid motion mode!\n");
6906 }
6907#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006908
Alex Converse0fa0f422017-04-24 12:51:14 -07006909 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006910
6911 if (bestsme < INT_MAX) {
6912 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006913#if CONFIG_MOTION_VAR
6914 switch (mbmi->motion_mode) {
6915 case SIMPLE_TRANSLATION:
6916#endif // CONFIG_MOTION_VAR
6917 if (cpi->sf.use_upsampled_references) {
6918 int best_mv_var;
6919 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6920 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006921 const int pw = block_size_wide[bsize];
6922 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07006923 // Use up-sampled reference frames.
6924 struct macroblockd_plane *const pd = &xd->plane[0];
6925 struct buf_2d backup_pred = pd->pre[ref_idx];
6926 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006927
Yue Chene9638cc2016-10-10 12:37:54 -07006928 // Set pred for Y plane
6929 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07006930 &pd->pre[ref_idx], bsize, upsampled_ref->y_buffer,
Yue Chene9638cc2016-10-10 12:37:54 -07006931 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
6932 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
6933 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006934
Yue Chene9638cc2016-10-10 12:37:54 -07006935 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006936 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6937 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6938 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6939 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
6940 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006941
Yue Chene9638cc2016-10-10 12:37:54 -07006942 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07006943 const int minc =
6944 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6945 const int maxc =
6946 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6947 const int minr =
6948 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6949 const int maxr =
6950 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07006951 int this_var;
6952 MV best_mv = x->best_mv.as_mv;
6953
6954 x->best_mv = x->second_best_mv;
6955 if (x->best_mv.as_mv.row * 8 <= maxr &&
6956 x->best_mv.as_mv.row * 8 >= minr &&
6957 x->best_mv.as_mv.col * 8 <= maxc &&
6958 x->best_mv.as_mv.col * 8 >= minc) {
6959 this_var = cpi->find_fractional_mv_step(
6960 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6961 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6962 cpi->sf.mv.subpel_iters_per_step,
6963 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
6964 &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
6965 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6966 x->best_mv.as_mv = best_mv;
6967 }
6968 }
6969
6970 // Restore the reference frames.
6971 pd->pre[ref_idx] = backup_pred;
6972 } else {
6973 cpi->find_fractional_mv_step(
6974 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6975 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6976 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
6977 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
6978 0);
6979 }
6980#if CONFIG_MOTION_VAR
6981 break;
6982 case OBMC_CAUSAL:
6983 av1_find_best_obmc_sub_pixel_tree_up(
6984 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
6985 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
6986 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
6987 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
6988 cpi->sf.use_upsampled_references);
6989 break;
6990 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006991 }
Yue Chene9638cc2016-10-10 12:37:54 -07006992#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006993 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006994 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6995 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006996
Yue Chene9638cc2016-10-10 12:37:54 -07006997#if CONFIG_MOTION_VAR
6998 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6999#else
7000 if (cpi->sf.adaptive_motion_search)
7001#endif // CONFIG_MOTION_VAR
7002 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007003
7004 if (scaled_ref_frame) {
7005 int i;
7006 for (i = 0; i < MAX_MB_PLANE; i++)
7007 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7008 }
7009}
7010
David Barkerac37fa32016-12-02 12:30:21 +00007011static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007012 int i;
7013 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007014 xd->plane[i].dst.buf = dst.plane[i];
7015 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007016 }
7017}
7018
Yaowu Xuc27fc142016-08-22 16:08:15 -07007019#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007020#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Urvang Joshi52648442016-10-13 17:27:51 -07007021static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007022 const uint8_t *mask, int mask_stride,
7023 BLOCK_SIZE bsize, int mi_row, int mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007024 int_mv *tmp_mv, int *rate_mv, int ref_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007025 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07007026 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007027 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7028 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
7029 int bestsme = INT_MAX;
7030 int step_param;
7031 int sadpb = x->sadperbit16;
7032 MV mvp_full;
7033 int ref = mbmi->ref_frame[ref_idx];
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007034 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007035
Alex Converse0fa0f422017-04-24 12:51:14 -07007036 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007037
7038 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07007039 av1_get_scaled_ref_frame(cpi, ref);
Urvang Joshi368fbc92016-10-17 16:31:34 -07007040 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007041
7042 MV pred_mv[3];
7043 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7044 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
7045 pred_mv[2] = x->pred_mv[ref];
7046
Yaowu Xu4306b6e2016-09-27 12:55:32 -07007047 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007048
7049 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007050 // Swap out the reference frame for a version that's been scaled to
7051 // match the resolution of the current frame, allowing the existing
7052 // motion search code to be used without additional modifications.
7053 for (i = 0; i < MAX_MB_PLANE; i++)
7054 backup_yv12[i] = xd->plane[i].pre[ref_idx];
7055
Yaowu Xuf883b422016-08-30 14:01:10 -07007056 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007057 }
7058
Alex Converse0fa0f422017-04-24 12:51:14 -07007059 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007060
7061 // Work out the size of the first step in the mv step search.
7062 // 0 here is maximum length first step. 1 is MAX >> 1 etc.
7063 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
7064 // Take wtd average of the step_params based on the last frame's
7065 // max mv magnitude and that based on the best ref mvs of the current
7066 // block for the given reference.
7067 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07007068 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07007069 2;
7070 } else {
7071 step_param = cpi->mv_step_param;
7072 }
7073
7074 // TODO(debargha): is show_frame needed here?
7075 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
7076 int boffset =
7077 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07007078 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
7079 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007080 }
7081
7082 if (cpi->sf.adaptive_motion_search) {
7083 int bwl = b_width_log2_lookup[bsize];
7084 int bhl = b_height_log2_lookup[bsize];
7085 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
7086
7087 if (tlevel < 5) step_param += 2;
7088
7089 // prev_mv_sad is not setup for dynamically scaled frames.
7090 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007091 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
7092 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
7093 x->pred_mv[ref].row = 0;
7094 x->pred_mv[ref].col = 0;
7095 tmp_mv->as_int = INVALID_MV;
7096
7097 if (scaled_ref_frame) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007098 int j;
7099 for (j = 0; j < MAX_MB_PLANE; ++j)
7100 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007101 }
7102 return;
7103 }
7104 }
7105 }
7106 }
7107
7108 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
7109
7110 mvp_full.col >>= 3;
7111 mvp_full.row >>= 3;
7112
Yaowu Xuf883b422016-08-30 14:01:10 -07007113 bestsme = av1_masked_full_pixel_diamond(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007114 cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
7115 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
7116 &tmp_mv->as_mv, ref_idx);
7117
Alex Converse0fa0f422017-04-24 12:51:14 -07007118 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007119
7120 if (bestsme < INT_MAX) {
7121 int dis; /* TODO: use dis in distortion calculation later. */
Yaowu Xuf883b422016-08-30 14:01:10 -07007122 av1_find_best_masked_sub_pixel_tree_up(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007123 cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
7124 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
7125 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
7126 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
7127 cpi->sf.use_upsampled_references);
7128 }
Yaowu Xuf883b422016-08-30 14:01:10 -07007129 *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
7130 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007131
7132 if (cpi->sf.adaptive_motion_search && cm->show_frame)
7133 x->pred_mv[ref] = tmp_mv->as_mv;
7134
7135 if (scaled_ref_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007136 for (i = 0; i < MAX_MB_PLANE; i++)
7137 xd->plane[i].pre[ref_idx] = backup_yv12[i];
7138 }
7139}
7140
Sarah Parker6fdc8532016-11-16 17:47:13 -08007141static void do_masked_motion_search_indexed(
7142 const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007143 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007144 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007145 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
7146 MACROBLOCKD *xd = &x->e_mbd;
7147 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7148 BLOCK_SIZE sb_type = mbmi->sb_type;
7149 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007150 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08007151
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007152 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007153
7154 if (which == 0 || which == 2)
7155 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007156 &tmp_mv[0], &rate_mv[0], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007157
7158 if (which == 1 || which == 2) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007159// get the negative mask
7160#if CONFIG_COMPOUND_SEGMENT
7161 uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
7162 const int h = block_size_high[bsize];
7163 mask = av1_get_compound_type_mask_inverse(
7164 comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
7165#else
7166 mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
Fergus Simpson4063a682017-02-28 16:52:22 -08007167#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007168 do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007169 &tmp_mv[1], &rate_mv[1], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007170 }
7171}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007172#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007173#endif // CONFIG_EXT_INTER
7174
7175// In some situations we want to discount tha pparent cost of a new motion
7176// vector. Where there is a subtle motion field and especially where there is
7177// low spatial complexity then it can be hard to cover the cost of a new motion
7178// vector in a single block, even if that motion vector reduces distortion.
7179// However, once established that vector may be usable through the nearest and
7180// near mv modes to reduce distortion in subsequent blocks and also improve
7181// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07007182static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007183 int_mv this_mv,
7184 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
7185 int ref_frame) {
7186 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
7187 (this_mv.as_int != 0) &&
7188 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
7189 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
7190 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
7191 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
7192}
7193
Yaowu Xu671f2bd2016-09-30 15:07:57 -07007194#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
7195#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007196
7197// TODO(jingning): this mv clamping function should be block size dependent.
7198static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
7199 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
7200 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
7201 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
7202 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
7203}
7204
7205#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007206#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007207static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007208 const BLOCK_SIZE bsize, const uint8_t *pred0,
7209 int stride0, const uint8_t *pred1, int stride1) {
7210 const struct macroblock_plane *const p = &x->plane[0];
7211 const uint8_t *src = p->src.buf;
7212 int src_stride = p->src.stride;
7213 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08007214 const int bw = block_size_wide[bsize];
7215 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007216 uint32_t esq[2][4], var;
7217 int64_t tl, br;
7218
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007219#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007220 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
7221 pred0 = CONVERT_TO_BYTEPTR(pred0);
7222 pred1 = CONVERT_TO_BYTEPTR(pred1);
7223 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007224#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007225
7226 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
7227 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
7228 stride0, &esq[0][1]);
7229 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7230 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
7231 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7232 pred0 + bh / 2 * stride0 + bw / 2, stride0,
7233 &esq[0][3]);
7234 var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
7235 var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
7236 stride1, &esq[1][1]);
7237 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
7238 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
7239 var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
7240 pred1 + bh / 2 * stride1 + bw / 2, stride0,
7241 &esq[1][3]);
7242 (void)var;
7243
7244 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
7245 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
7246 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
7247 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
7248 return (tl + br > 0);
7249}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007250#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007251#endif // CONFIG_EXT_INTER
7252
7253#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07007254static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07007255 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007256 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07007257 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
7258 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07007259 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007260 const MACROBLOCKD *xd = &x->e_mbd;
7261 int bsl = mi_width_log2_lookup[bsize];
7262 int pred_filter_search =
7263 cpi->sf.cb_pred_filter_search
7264 ? (((mi_row + mi_col) >> bsl) +
7265 get_chessboard_index(cm->current_video_frame)) &
7266 0x1
7267 : 0;
7268 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
7269 const int is_comp_pred = has_second_ref(mbmi);
7270 const int this_mode = mbmi->mode;
7271 int refs[2] = { mbmi->ref_frame[0],
7272 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07007273 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07007274 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007275 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
7276 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
7277
7278#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007279 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07007280#else
7281 if ((this_mode != NEWMV) || (af == lf))
7282#endif // CONFIG_EXT_INTER
7283 best_filter = af;
7284 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007285 if (is_comp_pred) {
7286 if (cpi->sf.adaptive_mode_search) {
7287#if CONFIG_EXT_INTER
7288 switch (this_mode) {
7289 case NEAREST_NEARESTMV:
7290 if (single_filter[NEARESTMV][refs[0]] ==
7291 single_filter[NEARESTMV][refs[1]])
7292 best_filter = single_filter[NEARESTMV][refs[0]];
7293 break;
7294 case NEAREST_NEARMV:
7295 if (single_filter[NEARESTMV][refs[0]] ==
7296 single_filter[NEARMV][refs[1]])
7297 best_filter = single_filter[NEARESTMV][refs[0]];
7298 break;
7299 case NEAR_NEARESTMV:
7300 if (single_filter[NEARMV][refs[0]] ==
7301 single_filter[NEARESTMV][refs[1]])
7302 best_filter = single_filter[NEARMV][refs[0]];
7303 break;
7304 case NEAR_NEARMV:
7305 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7306 best_filter = single_filter[NEARMV][refs[0]];
7307 break;
7308 case ZERO_ZEROMV:
7309 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7310 best_filter = single_filter[ZEROMV][refs[0]];
7311 break;
7312 case NEW_NEWMV:
7313 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7314 best_filter = single_filter[NEWMV][refs[0]];
7315 break;
7316 case NEAREST_NEWMV:
7317 if (single_filter[NEARESTMV][refs[0]] ==
7318 single_filter[NEWMV][refs[1]])
7319 best_filter = single_filter[NEARESTMV][refs[0]];
7320 break;
7321 case NEAR_NEWMV:
7322 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7323 best_filter = single_filter[NEARMV][refs[0]];
7324 break;
7325 case NEW_NEARESTMV:
7326 if (single_filter[NEWMV][refs[0]] ==
7327 single_filter[NEARESTMV][refs[1]])
7328 best_filter = single_filter[NEWMV][refs[0]];
7329 break;
7330 case NEW_NEARMV:
7331 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7332 best_filter = single_filter[NEWMV][refs[0]];
7333 break;
7334 default:
7335 if (single_filter[this_mode][refs[0]] ==
7336 single_filter[this_mode][refs[1]])
7337 best_filter = single_filter[this_mode][refs[0]];
7338 break;
7339 }
7340#else
7341 if (single_filter[this_mode][refs[0]] ==
7342 single_filter[this_mode][refs[1]])
7343 best_filter = single_filter[this_mode][refs[0]];
7344#endif // CONFIG_EXT_INTER
7345 }
7346 }
Angie Chiang75c22092016-10-25 12:19:16 -07007347 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7348 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007349 }
7350 return best_filter;
7351}
Fergus Simpson4063a682017-02-28 16:52:22 -08007352#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007353
7354#if CONFIG_EXT_INTER
7355// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007356#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007357static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007358 const BLOCK_SIZE bsize, const uint8_t *const p0,
7359 const uint8_t *const p1, int *const best_wedge_sign,
7360 int *const best_wedge_index) {
7361 const MACROBLOCKD *const xd = &x->e_mbd;
7362 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007363 const int bw = block_size_wide[bsize];
7364 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007365 const int N = bw * bh;
7366 int rate;
7367 int64_t dist;
7368 int64_t rd, best_rd = INT64_MAX;
7369 int wedge_index;
7370 int wedge_sign;
7371 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7372 const uint8_t *mask;
7373 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007374#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007375 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7376 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7377#else
7378 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007379#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007380
7381 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7382 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7383 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7384 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7385
7386 int64_t sign_limit;
7387
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007388#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007389 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007390 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007391 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007392 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007393 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007394 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007395 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7396 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007397#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007398 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007399 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7400 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7401 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007402 }
7403
Yaowu Xuf883b422016-08-30 14:01:10 -07007404 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7405 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007406 (1 << WEDGE_WEIGHT_BITS) / 2;
7407
Jingning Han61418bb2017-01-23 17:12:48 -08007408 if (N < 64)
7409 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7410 else
7411 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007412
7413 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007414 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007415
7416 // TODO(jingning): Make sse2 functions support N = 16 case
7417 if (N < 64)
7418 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7419 else
7420 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007421
Yaowu Xuf883b422016-08-30 14:01:10 -07007422 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007423 if (N < 64)
7424 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7425 else
7426 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007427 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7428
7429 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7430 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7431
7432 if (rd < best_rd) {
7433 *best_wedge_index = wedge_index;
7434 *best_wedge_sign = wedge_sign;
7435 best_rd = rd;
7436 }
7437 }
7438
7439 return best_rd;
7440}
7441
7442// Choose the best wedge index the specified sign
7443static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007444 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007445 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7446 const int wedge_sign, int *const best_wedge_index) {
7447 const MACROBLOCKD *const xd = &x->e_mbd;
7448 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007449 const int bw = block_size_wide[bsize];
7450 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007451 const int N = bw * bh;
7452 int rate;
7453 int64_t dist;
7454 int64_t rd, best_rd = INT64_MAX;
7455 int wedge_index;
7456 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7457 const uint8_t *mask;
7458 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007459#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007460 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7461 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7462#else
7463 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007464#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007465
7466 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7467 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7468
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007469#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007470 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007471 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007472 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007473 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007474 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7475 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007476#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007477 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007478 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7479 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007480 }
7481
7482 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007483 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007484 if (N < 64)
7485 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7486 else
7487 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007488 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7489
7490 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7491 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
7492
7493 if (rd < best_rd) {
7494 *best_wedge_index = wedge_index;
7495 best_rd = rd;
7496 }
7497 }
7498
7499 return best_rd;
7500}
7501
Yaowu Xuf883b422016-08-30 14:01:10 -07007502static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007503 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007504 const BLOCK_SIZE bsize,
7505 const uint8_t *const p0,
7506 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007507 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007508 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007509 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007510
7511 int64_t rd;
7512 int wedge_index = -1;
7513 int wedge_sign = 0;
7514
Sarah Parker42d96102017-01-31 21:05:27 -08007515 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007516
7517 if (cpi->sf.fast_wedge_sign_estimate) {
7518 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7519 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7520 } else {
7521 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7522 }
7523
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007524 mbmi->wedge_sign = wedge_sign;
7525 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007526 return rd;
7527}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007528#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007529
Sarah Parker569edda2016-12-14 14:57:38 -08007530#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07007531static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007532 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07007533 const uint8_t *const p0,
7534 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007535 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08007536 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7537 const struct buf_2d *const src = &x->plane[0].src;
7538 const int bw = block_size_wide[bsize];
7539 const int bh = block_size_high[bsize];
7540 const int N = bw * bh;
7541 int rate;
7542 uint64_t sse;
7543 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07007544 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007545 SEG_MASK_TYPE cur_mask_type;
7546 int64_t best_rd = INT64_MAX;
7547 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007548#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007549 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7550 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7551#else
7552 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007553#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007554 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7555 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7556 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7557
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007558#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007559 if (hbd) {
7560 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7561 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7562 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7563 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7564 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7565 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7566 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007567#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007568 {
7569 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7570 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7571 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7572 }
7573
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007574 // try each mask type and its inverse
7575 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007576// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007577#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007578 if (hbd)
7579 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007580 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007581 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7582 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007583#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007584 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
7585 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007586
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007587 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007588 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007589 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007590
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007591 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
7592 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007593
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007594 if (rd0 < best_rd) {
7595 best_mask_type = cur_mask_type;
7596 best_rd = rd0;
7597 }
7598 }
Sarah Parker569edda2016-12-14 14:57:38 -08007599
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007600 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007601 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007602#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007603 if (hbd)
7604 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007605 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007606 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7607 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007608#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007609 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
7610 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007611
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007612 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007613}
7614#endif // CONFIG_COMPOUND_SEGMENT
7615
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007616#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07007617static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007618 const MACROBLOCK *const x,
7619 const BLOCK_SIZE bsize,
7620 const uint8_t *const p0,
7621 const uint8_t *const p1) {
7622 const MACROBLOCKD *const xd = &x->e_mbd;
7623 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7624
7625 int64_t rd;
7626 int wedge_index = -1;
7627
7628 assert(is_interintra_wedge_used(bsize));
7629
7630 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7631
7632 mbmi->interintra_wedge_sign = 0;
7633 mbmi->interintra_wedge_index = wedge_index;
7634 return rd;
7635}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007636#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08007637
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007638#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007639static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07007640 const BLOCK_SIZE bsize,
7641 const uint8_t *const p0,
7642 const uint8_t *const p1) {
7643 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007644 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07007645 switch (compound_type) {
7646#if CONFIG_WEDGE
7647 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
7648#endif // CONFIG_WEDGE
7649#if CONFIG_COMPOUND_SEGMENT
7650 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
7651#endif // CONFIG_COMPOUND_SEGMENT
7652 default: assert(0); return 0;
7653 }
7654}
7655
Sarah Parker6fdc8532016-11-16 17:47:13 -08007656static int interinter_compound_motion_search(const AV1_COMP *const cpi,
7657 MACROBLOCK *x,
7658 const BLOCK_SIZE bsize,
7659 const int this_mode, int mi_row,
7660 int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007661 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007662 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7663 int_mv tmp_mv[2];
7664 int rate_mvs[2], tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007665 const INTERINTER_COMPOUND_DATA compound_data = {
7666#if CONFIG_WEDGE
7667 mbmi->wedge_index,
7668 mbmi->wedge_sign,
7669#endif // CONFIG_WEDGE
7670#if CONFIG_COMPOUND_SEGMENT
7671 mbmi->mask_type,
7672 xd->seg_mask,
7673#endif // CONFIG_COMPOUND_SEGMENT
7674 mbmi->interinter_compound_type
7675 };
Sarah Parker6fdc8532016-11-16 17:47:13 -08007676 if (this_mode == NEW_NEWMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007677 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7678 mi_col, tmp_mv, rate_mvs, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007679 tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
7680 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7681 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7682 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007683 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7684 mi_col, tmp_mv, rate_mvs, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007685 tmp_rate_mv = rate_mvs[0];
7686 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7687 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007688 do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
7689 mi_col, tmp_mv, rate_mvs, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007690 tmp_rate_mv = rate_mvs[1];
7691 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7692 }
7693 return tmp_rate_mv;
7694}
7695
Sarah Parkerddcea392017-04-25 15:57:22 -07007696static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007697 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7698 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7699 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7700 int *strides, int mi_row, int mi_col) {
7701 MACROBLOCKD *xd = &x->e_mbd;
7702 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7703 int rate_sum;
7704 int64_t dist_sum;
7705 int64_t best_rd_cur = INT64_MAX;
7706 int64_t rd = INT64_MAX;
7707 int tmp_skip_txfm_sb;
7708 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007709 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08007710
Sarah Parkerddcea392017-04-25 15:57:22 -07007711 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Sarah Parker569edda2016-12-14 14:57:38 -08007712 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
7713
Sarah Parker2e604882017-01-17 17:31:25 -08007714 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07007715 use_masked_motion_search(compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007716 *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
7717 mi_row, mi_col);
David Barkerac37fa32016-12-02 12:30:21 +00007718 av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007719 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7720 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7721 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007722 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007723 mbmi->mv[0].as_int = cur_mv[0].as_int;
7724 mbmi->mv[1].as_int = cur_mv[1].as_int;
7725 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007726 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7727#if CONFIG_SUPERTX
7728 0, 0,
7729#endif // CONFIG_SUPERTX
7730 preds0, strides, preds1,
7731 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007732 }
7733 av1_subtract_plane(x, bsize, 0);
7734 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7735 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7736 if (rd != INT64_MAX)
7737 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
7738 best_rd_cur = rd;
7739
7740 } else {
David Barker426a9972017-01-27 11:03:11 +00007741 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7742#if CONFIG_SUPERTX
7743 0, 0,
7744#endif // CONFIG_SUPERTX
7745 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007746 av1_subtract_plane(x, bsize, 0);
7747 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7748 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7749 if (rd != INT64_MAX)
7750 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
7751 best_rd_cur = rd;
7752 }
7753 return best_rd_cur;
7754}
Sarah Parkerddcea392017-04-25 15:57:22 -07007755#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007756#endif // CONFIG_EXT_INTER
7757
Fergus Simpson073c6f32017-02-17 12:13:48 -08007758typedef struct {
7759#if CONFIG_MOTION_VAR
7760 // Inter prediction buffers and respective strides
7761 uint8_t *above_pred_buf[MAX_MB_PLANE];
7762 int above_pred_stride[MAX_MB_PLANE];
7763 uint8_t *left_pred_buf[MAX_MB_PLANE];
7764 int left_pred_stride[MAX_MB_PLANE];
7765#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007766 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007767#if CONFIG_EXT_INTER
7768 // Pointer to array of motion vectors to use for each ref and their rates
7769 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007770 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007771 // Pointers costs of compound inter-intra and inter-inter predictions
7772 int *compmode_interintra_cost;
7773 int *compmode_interinter_cost;
7774 // Pointer to array of predicted rate-distortion
7775 // Should point to first of 2 arrays in 2D array
7776 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007777#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007778 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007779} HandleInterModeArgs;
7780
Fergus Simpson45509632017-02-22 15:30:50 -08007781static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7782 const BLOCK_SIZE bsize,
7783 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
7784 const int mi_row, const int mi_col,
7785 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007786 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007787 const MACROBLOCKD *const xd = &x->e_mbd;
7788 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7789 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7790 const int is_comp_pred = has_second_ref(mbmi);
7791 const PREDICTION_MODE this_mode = mbmi->mode;
7792#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007793 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7794#endif // CONFIG_EXT_INTER
7795 int_mv *const frame_mv = mode_mv[this_mode];
7796 const int refs[2] = { mbmi->ref_frame[0],
7797 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7798 int i;
7799
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007800 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007801
7802 if (is_comp_pred) {
7803#if CONFIG_EXT_INTER
7804 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007805 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007806 }
7807
7808 if (this_mode == NEW_NEWMV) {
7809 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7810 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7811
7812 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7813 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
Zoe Liu122f3942017-04-25 11:18:38 -07007814 rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007815 } else {
7816 *rate_mv = 0;
7817 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007818 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007819 *rate_mv += av1_mv_bit_cost(
7820 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7821 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7822 }
7823 }
7824 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7825 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007826 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007827 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
7828 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
7829 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7830 } else {
David Barkercb03dc32017-04-07 13:05:09 +01007831 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08007832 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
Zoe Liu122f3942017-04-25 11:18:38 -07007833 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007834 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7835 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7836 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7837 }
7838#else
7839 // Initialize mv using single prediction mode result.
7840 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7841 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7842
7843 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07007844 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007845 } else {
7846 *rate_mv = 0;
7847 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007848 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007849 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
7850 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7851 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7852 }
7853 }
7854#endif // CONFIG_EXT_INTER
7855 } else {
7856#if CONFIG_EXT_INTER
7857 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007858 x->best_mv = args->single_newmv[refs[0]];
7859 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08007860 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007861 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
7862 args->single_newmv[refs[0]] = x->best_mv;
7863 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08007864 }
7865#else
7866 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
7867 single_newmv[refs[0]] = x->best_mv;
7868#endif // CONFIG_EXT_INTER
7869
7870 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7871
7872 frame_mv[refs[0]] = x->best_mv;
7873 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7874
7875 // Estimate the rate implications of a new mv but discount this
7876 // under certain circumstances where we want to help initiate a weak
7877 // motion field, where the distortion gain for a single block may not
7878 // be enough to overcome the cost of a new mv.
7879 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
7880 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
7881 }
7882 }
7883
7884 return 0;
7885}
7886
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007887int64_t interpolation_filter_search(
7888 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
7889 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
7890 BUFFER_SET *const orig_dst,
7891 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
7892 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
7893 int64_t *const skip_sse_sb) {
7894 const AV1_COMMON *cm = &cpi->common;
7895 MACROBLOCKD *const xd = &x->e_mbd;
7896 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7897 int i;
7898 int tmp_rate;
7899 int64_t tmp_dist;
7900
7901 (void)single_filter;
7902
7903 InterpFilter assign_filter = SWITCHABLE;
7904
7905 if (cm->interp_filter == SWITCHABLE) {
7906#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007907 assign_filter = av1_is_interp_needed(xd)
7908 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
7909 single_filter)
7910 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007911#endif // !CONFIG_DUAL_FILTER
7912 } else {
7913 assign_filter = cm->interp_filter;
7914 }
7915
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007916 set_default_interp_filters(mbmi, assign_filter);
7917
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007918 *switchable_rate = av1_get_switchable_rate(cpi, xd);
7919 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
7920 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
7921 skip_txfm_sb, skip_sse_sb);
7922 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
7923
7924 if (assign_filter == SWITCHABLE) {
7925 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007926 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007927#if CONFIG_DUAL_FILTER
7928 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7929#else
7930 const int filter_set_size = SWITCHABLE_FILTERS;
7931#endif // CONFIG_DUAL_FILTER
7932 int best_in_temp = 0;
7933#if CONFIG_DUAL_FILTER
7934 InterpFilter best_filter[4];
7935 av1_copy(best_filter, mbmi->interp_filter);
7936#else
7937 InterpFilter best_filter = mbmi->interp_filter;
7938#endif // CONFIG_DUAL_FILTER
7939 restore_dst_buf(xd, *tmp_dst);
7940 // EIGHTTAP_REGULAR mode is calculated beforehand
7941 for (i = 1; i < filter_set_size; ++i) {
7942 int tmp_skip_sb = 0;
7943 int64_t tmp_skip_sse = INT64_MAX;
7944 int tmp_rs;
7945 int64_t tmp_rd;
7946#if CONFIG_DUAL_FILTER
7947 mbmi->interp_filter[0] = filter_sets[i][0];
7948 mbmi->interp_filter[1] = filter_sets[i][1];
7949 mbmi->interp_filter[2] = filter_sets[i][0];
7950 mbmi->interp_filter[3] = filter_sets[i][1];
7951#else
7952 mbmi->interp_filter = (InterpFilter)i;
7953#endif // CONFIG_DUAL_FILTER
7954 tmp_rs = av1_get_switchable_rate(cpi, xd);
7955 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
7956 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7957 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
7958 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
7959
7960 if (tmp_rd < *rd) {
7961 *rd = tmp_rd;
7962 *switchable_rate = av1_get_switchable_rate(cpi, xd);
7963#if CONFIG_DUAL_FILTER
7964 av1_copy(best_filter, mbmi->interp_filter);
7965#else
7966 best_filter = mbmi->interp_filter;
7967#endif // CONFIG_DUAL_FILTER
7968 *skip_txfm_sb = tmp_skip_sb;
7969 *skip_sse_sb = tmp_skip_sse;
7970 best_in_temp = !best_in_temp;
7971 if (best_in_temp) {
7972 restore_dst_buf(xd, *orig_dst);
7973 } else {
7974 restore_dst_buf(xd, *tmp_dst);
7975 }
7976 }
7977 }
7978 if (best_in_temp) {
7979 restore_dst_buf(xd, *tmp_dst);
7980 } else {
7981 restore_dst_buf(xd, *orig_dst);
7982 }
7983#if CONFIG_DUAL_FILTER
7984 av1_copy(mbmi->interp_filter, best_filter);
7985#else
7986 mbmi->interp_filter = best_filter;
7987#endif // CONFIG_DUAL_FILTER
7988 } else {
7989#if CONFIG_DUAL_FILTER
7990 for (i = 0; i < 4; ++i)
7991 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
7992#else
7993 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
7994#endif // CONFIG_DUAL_FILTER
7995 }
7996 }
7997
7998 return 0;
7999}
8000
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008001// TODO(afergs): Refactor the MBMI references in here - there's four
8002// TODO(afergs): Refactor optional args - add them to a struct or remove
8003static int64_t motion_mode_rd(
8004 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
8005 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8006 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
8007 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
8008 const int *refs, int rate_mv,
8009#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8010#if CONFIG_EXT_INTER
8011 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
8012#if CONFIG_MOTION_VAR
8013 int rate_mv_bmc,
8014#endif // CONFIG_MOTION_VAR
8015#endif // CONFIG_EXT_INTER
8016#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8017 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
8018 const AV1_COMMON *const cm = &cpi->common;
8019 MACROBLOCKD *xd = &x->e_mbd;
8020 MODE_INFO *mi = xd->mi[0];
8021 MB_MODE_INFO *mbmi = &mi->mbmi;
8022 const int is_comp_pred = has_second_ref(mbmi);
8023 const PREDICTION_MODE this_mode = mbmi->mode;
8024
8025 (void)mode_mv;
8026 (void)mi_row;
8027 (void)mi_col;
8028 (void)args;
8029 (void)refs;
8030 (void)rate_mv;
8031 (void)is_comp_pred;
8032 (void)this_mode;
8033
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008034#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8035 MOTION_MODE motion_mode, last_motion_mode_allowed;
8036 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
8037 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
8038 MB_MODE_INFO base_mbmi, best_mbmi;
8039#if CONFIG_VAR_TX
8040 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
8041#endif // CONFIG_VAR_TX
8042#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8043
8044#if CONFIG_WARPED_MOTION
8045 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
8046#endif // CONFIG_WARPED_MOTION
8047
8048#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8049 av1_invalid_rd_stats(&best_rd_stats);
8050#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8051
8052 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
8053#if CONFIG_WARPED_MOTION
8054 aom_clear_system_state();
8055 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
8056#if CONFIG_EXT_INTER
8057 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
8058#endif // CONFIG_EXT_INTER
8059#endif // CONFIG_WARPED_MOTION
8060#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8061 rate2_nocoeff = rd_stats->rate;
8062 last_motion_mode_allowed = motion_mode_allowed(
8063#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8064 0, xd->global_motion,
8065#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
8066 mi);
8067 base_mbmi = *mbmi;
8068#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8069
8070#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8071 int64_t best_rd = INT64_MAX;
8072 for (motion_mode = SIMPLE_TRANSLATION;
8073 motion_mode <= last_motion_mode_allowed; motion_mode++) {
8074 int64_t tmp_rd = INT64_MAX;
8075 int tmp_rate;
8076 int64_t tmp_dist;
8077#if CONFIG_EXT_INTER
8078 int tmp_rate2 =
8079 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
8080#else
8081 int tmp_rate2 = rate2_nocoeff;
8082#endif // CONFIG_EXT_INTER
8083
8084 *mbmi = base_mbmi;
8085 mbmi->motion_mode = motion_mode;
8086#if CONFIG_MOTION_VAR
8087 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008088#if CONFIG_EXT_INTER
8089 *mbmi = *best_bmc_mbmi;
8090 mbmi->motion_mode = OBMC_CAUSAL;
8091#endif // CONFIG_EXT_INTER
8092 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
8093 int tmp_rate_mv = 0;
8094
8095 single_motion_search(cpi, x, bsize, mi_row, mi_col,
8096#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07008097 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008098#endif // CONFIG_EXT_INTER
8099 &tmp_rate_mv);
8100 mbmi->mv[0].as_int = x->best_mv.as_int;
8101 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
8102 refs[0])) {
8103 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
8104 }
8105#if CONFIG_EXT_INTER
8106 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
8107#else
8108 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
8109#endif // CONFIG_EXT_INTER
8110#if CONFIG_DUAL_FILTER
8111 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
8112 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
8113 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
8114 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
8115#endif // CONFIG_DUAL_FILTER
8116 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8117#if CONFIG_EXT_INTER
8118 } else {
8119 av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
8120#endif // CONFIG_EXT_INTER
8121 }
8122 av1_build_obmc_inter_prediction(
8123 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
8124 args->left_pred_buf, args->left_pred_stride);
8125 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8126 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8127 }
8128#endif // CONFIG_MOTION_VAR
8129
8130#if CONFIG_WARPED_MOTION
8131 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008132#if CONFIG_EXT_INTER
8133 *mbmi = *best_bmc_mbmi;
8134 mbmi->motion_mode = WARPED_CAUSAL;
8135#endif // CONFIG_EXT_INTER
8136 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
8137#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07008138 for (int dir = 0; dir < 4; ++dir)
8139 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
8140 ? EIGHTTAP_REGULAR
8141 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008142#else
8143 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
8144 : cm->interp_filter;
8145#endif // CONFIG_DUAL_FILTER
8146
Debargha Mukherjeee8e6cad2017-03-22 17:38:38 -07008147 if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
8148 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008149 &mbmi->wm_params[0], mi_row, mi_col) == 0) {
Sarah Parker4c10a3c2017-04-10 19:37:59 -07008150 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008151 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8152 &tmp_dist, skip_txfm_sb, skip_sse_sb);
8153 } else {
8154 continue;
8155 }
8156 }
8157#endif // CONFIG_WARPED_MOTION
8158 x->skip = 0;
8159
8160 rd_stats->dist = 0;
8161 rd_stats->sse = 0;
8162 rd_stats->skip = 1;
8163 rd_stats->rate = tmp_rate2;
8164 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
8165#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8166 if (last_motion_mode_allowed == WARPED_CAUSAL)
8167#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8168 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
8169#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8170 else
8171 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
8172#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
8173 }
8174#if CONFIG_WARPED_MOTION
8175 if (mbmi->motion_mode == WARPED_CAUSAL) {
8176 rd_stats->rate -= rs;
8177 }
8178#endif // CONFIG_WARPED_MOTION
8179#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8180 if (!*skip_txfm_sb) {
8181 int64_t rdcosty = INT64_MAX;
8182 int is_cost_valid_uv = 0;
8183
8184 // cost and distortion
8185 av1_subtract_plane(x, bsize, 0);
8186#if CONFIG_VAR_TX
8187 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8188 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8189 } else {
8190 int idx, idy;
8191 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8192 for (idy = 0; idy < xd->n8_h; ++idy)
8193 for (idx = 0; idx < xd->n8_w; ++idx)
8194 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8195 memset(x->blk_skip[0], rd_stats_y->skip,
8196 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8197 }
8198#else
8199 /* clang-format off */
8200 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8201/* clang-format on */
8202#endif // CONFIG_VAR_TX
8203
8204 if (rd_stats_y->rate == INT_MAX) {
8205 av1_invalid_rd_stats(rd_stats);
8206#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8207 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8208 continue;
8209 } else {
8210#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8211 restore_dst_buf(xd, *orig_dst);
8212 return INT64_MAX;
8213#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8214 }
8215#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8216 }
8217
8218 av1_merge_rd_stats(rd_stats, rd_stats_y);
8219
8220 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8221 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
8222/* clang-format off */
8223#if CONFIG_VAR_TX
8224 is_cost_valid_uv =
8225 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8226#else
8227 is_cost_valid_uv =
8228 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8229#endif // CONFIG_VAR_TX
8230 if (!is_cost_valid_uv) {
8231#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8232 continue;
8233#else
8234 restore_dst_buf(xd, *orig_dst);
8235 return INT64_MAX;
8236#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8237 }
8238 /* clang-format on */
8239 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8240#if CONFIG_RD_DEBUG
8241 // record transform block coefficient cost
8242 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8243 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8244 // here because we already collect the coefficient cost. Move this part to
8245 // other place when we need to compare non-coefficient cost.
8246 mbmi->rd_stats = *rd_stats;
8247#endif // CONFIG_RD_DEBUG
8248#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8249 if (rd_stats->skip) {
8250 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8251 rd_stats_y->rate = 0;
8252 rd_stats_uv->rate = 0;
8253 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8254 mbmi->skip = 0;
8255 // here mbmi->skip temporarily plays a role as what this_skip2 does
8256 } else if (!xd->lossless[mbmi->segment_id] &&
8257 (RDCOST(x->rdmult, x->rddiv,
8258 rd_stats_y->rate + rd_stats_uv->rate +
8259 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8260 rd_stats->dist) >=
8261 RDCOST(x->rdmult, x->rddiv,
8262 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
8263 rd_stats->sse))) {
8264 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8265 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8266 rd_stats->dist = rd_stats->sse;
8267 rd_stats_y->rate = 0;
8268 rd_stats_uv->rate = 0;
8269 mbmi->skip = 1;
8270 } else {
8271 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8272 mbmi->skip = 0;
8273 }
8274 *disable_skip = 0;
8275#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8276 } else {
8277 x->skip = 1;
8278 *disable_skip = 1;
8279 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8280
8281// The cost of skip bit needs to be added.
8282#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8283 mbmi->skip = 0;
8284#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8285 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8286
8287 rd_stats->dist = *skip_sse_sb;
8288 rd_stats->sse = *skip_sse_sb;
8289 rd_stats_y->rate = 0;
8290 rd_stats_uv->rate = 0;
8291 rd_stats->skip = 1;
8292 }
8293
8294#if CONFIG_GLOBAL_MOTION
8295 if (this_mode == ZEROMV
8296#if CONFIG_EXT_INTER
8297 || this_mode == ZERO_ZEROMV
8298#endif // CONFIG_EXT_INTER
8299 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008300 if (is_nontrans_global_motion(xd)) {
8301 rd_stats->rate -= rs;
8302#if CONFIG_DUAL_FILTER
8303 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8304 ? EIGHTTAP_REGULAR
8305 : cm->interp_filter;
8306 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8307 ? EIGHTTAP_REGULAR
8308 : cm->interp_filter;
8309#else
8310 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8311 ? EIGHTTAP_REGULAR
8312 : cm->interp_filter;
8313#endif // CONFIG_DUAL_FILTER
8314 }
8315 }
8316#endif // CONFIG_GLOBAL_MOTION
8317
8318#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8319 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
8320 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8321 best_mbmi = *mbmi;
8322 best_rd = tmp_rd;
8323 best_rd_stats = *rd_stats;
8324 best_rd_stats_y = *rd_stats_y;
8325 best_rd_stats_uv = *rd_stats_uv;
8326#if CONFIG_VAR_TX
8327 for (int i = 0; i < MAX_MB_PLANE; ++i)
8328 memcpy(best_blk_skip[i], x->blk_skip[i],
8329 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8330#endif // CONFIG_VAR_TX
8331 best_xskip = x->skip;
8332 best_disable_skip = *disable_skip;
8333 }
8334 }
8335
8336 if (best_rd == INT64_MAX) {
8337 av1_invalid_rd_stats(rd_stats);
8338 restore_dst_buf(xd, *orig_dst);
8339 return INT64_MAX;
8340 }
8341 *mbmi = best_mbmi;
8342 *rd_stats = best_rd_stats;
8343 *rd_stats_y = best_rd_stats_y;
8344 *rd_stats_uv = best_rd_stats_uv;
8345#if CONFIG_VAR_TX
8346 for (int i = 0; i < MAX_MB_PLANE; ++i)
8347 memcpy(x->blk_skip[i], best_blk_skip[i],
8348 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8349#endif // CONFIG_VAR_TX
8350 x->skip = best_xskip;
8351 *disable_skip = best_disable_skip;
8352#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8353
8354 restore_dst_buf(xd, *orig_dst);
8355 return 0;
8356}
8357
Yaowu Xuc27fc142016-08-22 16:08:15 -07008358static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08008359 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
8360 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008361 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008362 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008363 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008364 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008365 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008366 MODE_INFO *mi = xd->mi[0];
8367 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008368 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8369 const int is_comp_pred = has_second_ref(mbmi);
8370 const int this_mode = mbmi->mode;
8371 int_mv *frame_mv = mode_mv[this_mode];
8372 int i;
8373 int refs[2] = { mbmi->ref_frame[0],
8374 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8375 int_mv cur_mv[2];
8376 int rate_mv = 0;
8377#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008378 int pred_exists = 1;
Jingning Hanae5cfde2016-11-30 12:01:44 -08008379 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008381#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008382 const unsigned int *const interintra_mode_cost =
8383 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008384#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008385 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07008386 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008387#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008388 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008389#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008390#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008391 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8392#else
8393 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008394#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008395 uint8_t *tmp_buf;
8396
Yue Chencb60b182016-10-13 15:18:22 -07008397#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008398#if CONFIG_EXT_INTER
8399 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008400 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008401#if CONFIG_MOTION_VAR
8402 int rate_mv_bmc;
8403#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008404#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008405#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008406 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008407 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008408 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008409
8410 int skip_txfm_sb = 0;
8411 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008412 int16_t mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008413
8414#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008415 *args->compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008416 mbmi->use_wedge_interintra = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008417 *args->compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008418 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008419
8420 // is_comp_interintra_pred implies !is_comp_pred
8421 assert(!is_comp_interintra_pred || (!is_comp_pred));
8422 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8423 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8424#endif // CONFIG_EXT_INTER
8425
Yaowu Xuc27fc142016-08-22 16:08:15 -07008426#if CONFIG_EXT_INTER
8427 if (is_comp_pred)
8428 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8429 else
8430#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008431 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8432 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008433
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008434#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008435 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8436 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8437 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008438#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008439 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008440 // Make sure that we didn't leave the plane destination buffers set
8441 // to tmp_buf at the end of the last iteration
8442 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008443
Yue Chen69f18e12016-09-08 14:48:15 -07008444#if CONFIG_WARPED_MOTION
8445 mbmi->num_proj_ref[0] = 0;
8446 mbmi->num_proj_ref[1] = 0;
8447#endif // CONFIG_WARPED_MOTION
8448
Yaowu Xuc27fc142016-08-22 16:08:15 -07008449 if (is_comp_pred) {
8450 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8451 frame_mv[refs[1]].as_int == INVALID_MV)
8452 return INT64_MAX;
8453 }
8454
Yue Chene9638cc2016-10-10 12:37:54 -07008455 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008456 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08008457 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008458 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008459 if (ret_val != 0)
8460 return ret_val;
8461 else
8462 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008463 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008464 for (i = 0; i < is_comp_pred + 1; ++i) {
8465 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07008466 // Clip "next_nearest" so that it does not extend to far out of image
8467 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008468 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008469 mbmi->mv[i].as_int = cur_mv[i].as_int;
8470 }
8471
Yaowu Xuc27fc142016-08-22 16:08:15 -07008472#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008473 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008474#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008475 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008477 {
8478#if !CONFIG_EXT_INTER
8479 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008480#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008481 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8482 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8483 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8484
8485 for (i = 0; i < 2; ++i) {
8486 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008487 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008488 mbmi->mv[i].as_int = cur_mv[i].as_int;
8489 }
8490 }
8491 }
8492
8493#if CONFIG_EXT_INTER
8494 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8495 if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
8496 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8497
8498 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8499 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008500 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008501 mbmi->mv[0].as_int = cur_mv[0].as_int;
8502 }
8503
8504 if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
8505 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8506
8507 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8508 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008509 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008510 mbmi->mv[1].as_int = cur_mv[1].as_int;
8511 }
8512 }
8513
8514 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01008515 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008516 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
8517 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008518 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008519
8520 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8521 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008522 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008523 mbmi->mv[0].as_int = cur_mv[0].as_int;
8524 }
8525
8526 if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
8527 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008528 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008529
8530 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8531 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008532 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008533 mbmi->mv[1].as_int = cur_mv[1].as_int;
8534 }
8535 }
8536#else
8537 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008538 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008539 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8540 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8541 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8542 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8543
8544 for (i = 0; i < 2; ++i) {
8545 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008546 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008547 mbmi->mv[i].as_int = cur_mv[i].as_int;
8548 }
8549 }
8550 }
8551#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008552
8553 // do first prediction into the destination buffer. Do the next
8554 // prediction into a temporary buffer. Then keep track of which one
8555 // of these currently holds the best predictor, and use the other
8556 // one for future predictions. In the end, copy from tmp_buf to
8557 // dst if necessary.
8558 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008559 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8560 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008561 }
8562 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008563 orig_dst.plane[i] = xd->plane[i].dst.buf;
8564 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008565 }
8566
8567 // We don't include the cost of the second reference here, because there
8568 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8569 // words if you present them in that order, the second one is always known
8570 // if the first is known.
8571 //
8572 // Under some circumstances we discount the cost of new mv mode to encourage
8573 // initiation of a motion field.
8574 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8575 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01008576#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008577 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01008578 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8579 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
8580 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008581#else
Angie Chiang76159122016-11-09 12:13:22 -08008582 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8583 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008584#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008585 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008586 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008587 }
8588
Angie Chiang76159122016-11-09 12:13:22 -08008589 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008590#if CONFIG_EXT_INTER
8591 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8592#else
8593 mbmi->mode != NEARESTMV
8594#endif // CONFIG_EXT_INTER
8595 )
8596 return INT64_MAX;
8597
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008598 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008599 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8600 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008601 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008602
Yaowu Xuc27fc142016-08-22 16:08:15 -07008603#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008604#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008605 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008606 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008607 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008608#if CONFIG_MOTION_VAR
8609 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07008610#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008611#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008612
Sarah Parker6fdc8532016-11-16 17:47:13 -08008613 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07008614 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008615 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008616 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8617 INTERINTER_COMPOUND_DATA best_compound_data;
8618 int_mv best_mv[2];
8619 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008620 int tmp_skip_txfm_sb;
8621 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07008622 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08008623 uint8_t pred0[2 * MAX_SB_SQUARE];
8624 uint8_t pred1[2 * MAX_SB_SQUARE];
8625 uint8_t *preds0[1] = { pred0 };
8626 uint8_t *preds1[1] = { pred1 };
8627 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008628 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008629 int masked_compound_used = is_any_masked_compound_used(bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008630 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008631
Sarah Parker6fdc8532016-11-16 17:47:13 -08008632 best_mv[0].as_int = cur_mv[0].as_int;
8633 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008634 memset(&best_compound_data, 0, sizeof(best_compound_data));
8635#if CONFIG_COMPOUND_SEGMENT
8636 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
8637 best_compound_data.seg_mask = tmp_mask_buf;
8638#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008639
Sarah Parker42d96102017-01-31 21:05:27 -08008640 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07008641 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8642 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008643 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008644 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008645 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008646 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008647 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008648 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008649
Sarah Parker6fdc8532016-11-16 17:47:13 -08008650 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Sarah Parker42d96102017-01-31 21:05:27 -08008651 if (!is_interinter_compound_used(cur_type, bsize)) break;
Sarah Parker2e604882017-01-17 17:31:25 -08008652 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008653 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008654 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008655 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008656 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008657 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008658 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08008659 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660
Sarah Parker6fdc8532016-11-16 17:47:13 -08008661 switch (cur_type) {
8662 case COMPOUND_AVERAGE:
David Barkerac37fa32016-12-02 12:30:21 +00008663 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008664 av1_subtract_plane(x, bsize, 0);
8665 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8666 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8667 INT64_MAX);
8668 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08008669 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008670 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008671 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008672 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008673#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008674 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008675 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8676 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008677 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00008678 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8679 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008680 }
8681 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008682#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08008683#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008684 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008685 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8686 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008687 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08008688 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8689 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008690 }
8691 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008692#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008693 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008694 }
Sarah Parker2e604882017-01-17 17:31:25 -08008695
8696 if (best_rd_cur < best_rd_compound) {
8697 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008698#if CONFIG_WEDGE
8699 best_compound_data.wedge_index = mbmi->wedge_index;
8700 best_compound_data.wedge_sign = mbmi->wedge_sign;
8701#endif // CONFIG_WEDGE
8702#if CONFIG_COMPOUND_SEGMENT
8703 best_compound_data.mask_type = mbmi->mask_type;
8704 memcpy(best_compound_data.seg_mask, xd->seg_mask,
8705 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8706#endif // CONFIG_COMPOUND_SEGMENT
8707 best_compound_data.interinter_compound_type =
8708 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08008709 if (have_newmv_in_inter_mode(this_mode)) {
8710 if (use_masked_motion_search(cur_type)) {
8711 best_tmp_rate_mv = tmp_rate_mv;
8712 best_mv[0].as_int = mbmi->mv[0].as_int;
8713 best_mv[1].as_int = mbmi->mv[1].as_int;
8714 } else {
8715 best_mv[0].as_int = cur_mv[0].as_int;
8716 best_mv[1].as_int = cur_mv[1].as_int;
8717 }
8718 }
8719 }
8720 // reset to original mvs for next iteration
8721 mbmi->mv[0].as_int = cur_mv[0].as_int;
8722 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008723 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008724#if CONFIG_WEDGE
8725 mbmi->wedge_index = best_compound_data.wedge_index;
8726 mbmi->wedge_sign = best_compound_data.wedge_sign;
8727#endif // CONFIG_WEDGE
8728#if CONFIG_COMPOUND_SEGMENT
8729 mbmi->mask_type = best_compound_data.mask_type;
8730 memcpy(xd->seg_mask, best_compound_data.seg_mask,
8731 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8732#endif // CONFIG_COMPOUND_SEGMENT
8733 mbmi->interinter_compound_type =
8734 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008735 if (have_newmv_in_inter_mode(this_mode)) {
8736 mbmi->mv[0].as_int = best_mv[0].as_int;
8737 mbmi->mv[1].as_int = best_mv[1].as_int;
8738 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8739 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008740 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008741 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8742 rate_mv = best_tmp_rate_mv;
8743 }
8744 }
8745
8746 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008747 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008748 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008749 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008750
8751 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008752
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008753 *args->compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008754 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008755 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01008756 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008757 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01008758 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008759 }
8760
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008761#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008762 if (is_comp_interintra_pred) {
8763 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8764 int64_t best_interintra_rd = INT64_MAX;
8765 int rmode, rate_sum;
8766 int64_t dist_sum;
8767 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008768 int tmp_rate_mv = 0;
8769 int tmp_skip_txfm_sb;
8770 int64_t tmp_skip_sse_sb;
8771 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8772 uint8_t *intrapred;
8773
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008774#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008775 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8776 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8777 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008778#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008779 intrapred = intrapred_;
8780
Emil Keyder01770b32017-01-20 18:03:11 -05008781 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008782 for (j = 0; j < MAX_MB_PLANE; j++) {
8783 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8784 xd->plane[j].dst.stride = bw;
8785 }
David Barkerac37fa32016-12-02 12:30:21 +00008786 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
8787 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008788 mbmi->ref_frame[1] = INTRA_FRAME;
8789 mbmi->use_wedge_interintra = 0;
8790
8791 for (j = 0; j < INTERINTRA_MODES; ++j) {
8792 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8793 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008794 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8795 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008796 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008797 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8798 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8799 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
8800 if (rd < best_interintra_rd) {
8801 best_interintra_rd = rd;
8802 best_interintra_mode = mbmi->interintra_mode;
8803 }
8804 }
8805 mbmi->interintra_mode = best_interintra_mode;
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);
8810 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008811 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8812 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8813 if (rd != INT64_MAX)
8814 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
8815 best_interintra_rd = rd;
8816
8817 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008818 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008819 return INT64_MAX;
8820 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008821#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008822 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008823 int64_t best_interintra_rd_nowedge = INT64_MAX;
8824 int64_t best_interintra_rd_wedge = INT64_MAX;
8825 int_mv tmp_mv;
8826 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008827 if (rd != INT64_MAX)
8828 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
8829 dist_sum);
8830 best_interintra_rd_nowedge = rd;
8831
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008832 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07008833 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8834 mbmi->use_wedge_interintra = 1;
8835
Yaowu Xuf883b422016-08-30 14:01:10 -07008836 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8837 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008838
8839 best_interintra_rd_wedge =
8840 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8841
8842 best_interintra_rd_wedge +=
8843 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
8844 // Refine motion vector.
8845 if (have_newmv_in_inter_mode(this_mode)) {
8846 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008847 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008848 mbmi->interintra_wedge_index, 1, bsize);
8849 do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07008850 &tmp_mv, &tmp_rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008851 mbmi->mv[0].as_int = tmp_mv.as_int;
David Barkerac37fa32016-12-02 12:30:21 +00008852 av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008853 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8854 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
8855 rd = RDCOST(x->rdmult, x->rddiv,
8856 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8857 if (rd < best_interintra_rd_wedge) {
8858 best_interintra_rd_wedge = rd;
8859 } else {
8860 tmp_mv.as_int = cur_mv[0].as_int;
8861 tmp_rate_mv = rate_mv;
8862 }
8863 } else {
8864 tmp_mv.as_int = cur_mv[0].as_int;
8865 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008866 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008867 }
8868 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008869 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008870 rd =
8871 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8872 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8873 if (rd != INT64_MAX)
8874 rd = RDCOST(x->rdmult, x->rddiv,
8875 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
8876 best_interintra_rd_wedge = rd;
8877 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8878 mbmi->use_wedge_interintra = 1;
8879 best_interintra_rd = best_interintra_rd_wedge;
8880 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008881 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008882 rate_mv = tmp_rate_mv;
8883 } else {
8884 mbmi->use_wedge_interintra = 0;
8885 best_interintra_rd = best_interintra_rd_nowedge;
8886 mbmi->mv[0].as_int = cur_mv[0].as_int;
8887 }
8888 } else {
8889 mbmi->use_wedge_interintra = 0;
8890 best_interintra_rd = best_interintra_rd_nowedge;
8891 }
8892 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008893#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008894
8895 pred_exists = 0;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008896 *args->compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008897 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008898 *args->compmode_interintra_cost +=
Fergus Simpson073c6f32017-02-17 12:13:48 -08008899 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008900 if (is_interintra_wedge_used(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008901 *args->compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008902 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8903 if (mbmi->use_wedge_interintra) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008904 *args->compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008905 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008906 }
8907 }
8908 } else if (is_interintra_allowed(mbmi)) {
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]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008911 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008912#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008913
Angie Chiang75c22092016-10-25 12:19:16 -07008914 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008915 int tmp_rate;
8916 int64_t tmp_dist;
David Barkerac37fa32016-12-02 12:30:21 +00008917 av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008918 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8919 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
8920 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
8921 }
Angie Chiang75c22092016-10-25 12:19:16 -07008922#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008923
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008924 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008925#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008926 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008927#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008928 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008929#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008930
8931#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008932 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008933 if (is_comp_pred) {
8934 const int mode0 = compound_ref0_mode(this_mode);
8935 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008936 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8937 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008938 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008939 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008940 return INT64_MAX;
8941 }
8942 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008943 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008944 }
8945 }
8946#endif // CONFIG_EXT_INTER
8947
8948 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8949 // if current pred_error modeled rd is substantially more than the best
8950 // so far, do not bother doing full rd
8951 if (rd / 2 > ref_best_rd) {
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 }
8956
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008957 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
8958 disable_skip, mode_mv, mi_row, mi_col, args,
8959 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07008960#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008961#if CONFIG_EXT_INTER
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008962 rate2_bmc_nocoeff, &best_bmc_mbmi,
Yue Chencb60b182016-10-13 15:18:22 -07008963#if CONFIG_MOTION_VAR
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008964 rate_mv_bmc,
Yue Chencb60b182016-10-13 15:18:22 -07008965#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008966#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008967#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008968 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
8969 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08008970
Yaowu Xuc27fc142016-08-22 16:08:15 -07008971 return 0; // The rate-distortion cost will be re-calculated by caller.
8972}
8973
Alex Converse28744302017-04-13 14:46:22 -07008974#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07008975static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008976 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07008977 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07008978 const AV1_COMMON *const cm = &cpi->common;
8979 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
8980
Alex Converse28744302017-04-13 14:46:22 -07008981 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07008982 const TileInfo *tile = &xd->tile;
8983 MODE_INFO *const mi = xd->mi[0];
8984 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
8985 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
8986 const int w = block_size_wide[bsize];
8987 const int h = block_size_high[bsize];
8988 const int sb_row = mi_row / MAX_MIB_SIZE;
8989
8990 int_mv dv_ref;
8991 av1_find_ref_dv(&dv_ref, mi_row, mi_col);
8992
8993 const MvLimits tmp_mv_limits = x->mv_limits;
8994
8995 // TODO(aconverse@google.com): Handle same row DV.
8996 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8997 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
8998 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8999 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
9000 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
9001 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
9002 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
9003 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
9004 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
9005
9006 if (x->mv_limits.col_max < x->mv_limits.col_min ||
9007 x->mv_limits.row_max < x->mv_limits.row_min) {
9008 x->mv_limits = tmp_mv_limits;
9009 return INT64_MAX;
Alex Converse28744302017-04-13 14:46:22 -07009010 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009011
9012 struct buf_2d yv12_mb[MAX_MB_PLANE];
9013 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
9014 for (int i = 0; i < MAX_MB_PLANE; ++i) {
9015 xd->plane[i].pre[0] = yv12_mb[i];
9016 }
9017
9018 int step_param = cpi->mv_step_param;
9019 MV mvp_full = dv_ref.as_mv;
9020 mvp_full.col >>= 3;
9021 mvp_full.row >>= 3;
9022 int sadpb = x->sadperbit16;
9023 int cost_list[5];
9024 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
9025 sadpb, cond_cost_list(cpi, cost_list),
9026 &dv_ref.as_mv, INT_MAX, 1);
9027
9028 x->mv_limits = tmp_mv_limits;
9029 if (bestsme == INT_MAX) return INT64_MAX;
9030 mvp_full = x->best_mv.as_mv;
9031 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
9032 if (mv_check_bounds(&x->mv_limits, &dv)) return INT64_MAX;
9033 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) return INT64_MAX;
9034 MB_MODE_INFO *mbmi = &mi->mbmi;
9035 MB_MODE_INFO best_mbmi = *mbmi;
9036 RD_STATS best_rdcost = *rd_cost;
9037 int best_skip = x->skip;
9038#if CONFIG_PALETTE
9039 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
9040#endif
9041 mbmi->use_intrabc = 1;
9042 mbmi->mode = DC_PRED;
9043 mbmi->uv_mode = DC_PRED;
9044 mbmi->mv[0].as_mv = dv;
9045#if CONFIG_DUAL_FILTER
9046 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
9047#else
9048 mbmi->interp_filter = BILINEAR;
9049#endif
9050 mbmi->skip = 0;
9051 x->skip = 0;
9052 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
9053
9054 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost, x->mvcost,
9055 MV_COST_WEIGHT);
9056 const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
9057 const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
9058 const int rate_mode =
9059 cpi->y_mode_costs[A][L][DC_PRED] + av1_cost_bit(INTRABC_PROB, 1);
9060
9061 RD_STATS rd_stats, rd_stats_uv;
9062 av1_subtract_plane(x, bsize, 0);
9063 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
9064 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
9065 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
9066#if CONFIG_RD_DEBUG
9067 mbmi->rd_stats = rd_stats;
9068#endif
9069
9070 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
9071
9072 RD_STATS rdc_noskip;
9073 av1_init_rd_stats(&rdc_noskip);
9074 rdc_noskip.rate =
9075 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
9076 rdc_noskip.dist = rd_stats.dist;
9077 rdc_noskip.rdcost =
9078 RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
9079 if (rdc_noskip.rdcost < best_rd) {
9080 best_rd = rdc_noskip.rdcost;
9081 best_mbmi = *mbmi;
9082 best_skip = x->skip;
9083 best_rdcost = rdc_noskip;
9084 }
9085
9086 x->skip = 1;
9087 mbmi->skip = 1;
9088 RD_STATS rdc_skip;
9089 av1_init_rd_stats(&rdc_skip);
9090 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
9091 rdc_skip.dist = rd_stats.sse;
9092 rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
9093 if (rdc_skip.rdcost < best_rd) {
9094 best_rd = rdc_skip.rdcost;
9095 best_mbmi = *mbmi;
9096 best_skip = x->skip;
9097 best_rdcost = rdc_skip;
9098 }
9099 *mbmi = best_mbmi;
9100 *rd_cost = best_rdcost;
9101 x->skip = best_skip;
9102 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07009103}
9104#endif // CONFIG_INTRABC
9105
Urvang Joshi52648442016-10-13 17:27:51 -07009106void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009107 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07009108 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9109 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009110 MACROBLOCKD *const xd = &x->e_mbd;
9111 struct macroblockd_plane *const pd = xd->plane;
9112 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9113 int y_skip = 0, uv_skip = 0;
9114 int64_t dist_y = 0, dist_uv = 0;
9115 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009116 const int unify_bsize = CONFIG_CB4X4;
9117
Yaowu Xuc27fc142016-08-22 16:08:15 -07009118 ctx->skip = 0;
9119 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009120 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07009121#if CONFIG_INTRABC
9122 xd->mi[0]->mbmi.use_intrabc = 0;
9123#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07009124
Alex Conversed1b6fad2017-04-26 15:39:37 -07009125 const int64_t intra_yrd =
9126 (bsize >= BLOCK_8X8 || unify_bsize)
9127 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9128 &y_skip, bsize, best_rd)
9129 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
9130 &dist_y, &y_skip, best_rd);
9131
9132 if (intra_yrd < best_rd) {
9133 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
9134 [pd[1].subsampling_x][pd[1].subsampling_y];
Jingning Han271bb2c2016-12-14 12:34:46 -08009135
9136#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08009137#if !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009138 max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08009139#endif // !CONFIG_CHROMA_2X2
Alex Conversed1b6fad2017-04-26 15:39:37 -07009140 if (!x->skip_chroma_rd)
9141 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9142 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009143#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07009144 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9145 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009146#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009147
Alex Conversed1b6fad2017-04-26 15:39:37 -07009148 if (y_skip && uv_skip) {
9149 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
9150 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9151 rd_cost->dist = dist_y + dist_uv;
9152 } else {
9153 rd_cost->rate =
9154 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9155 rd_cost->dist = dist_y + dist_uv;
9156 }
9157 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009158 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07009159 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009160 }
9161
Alex Converse28744302017-04-13 14:46:22 -07009162#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07009163 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
9164 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07009165 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
9166 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07009167 assert(rd_cost->rate != INT_MAX);
9168 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07009169 }
9170#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07009171 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07009172
Yaowu Xuc27fc142016-08-22 16:08:15 -07009173 ctx->mic = *xd->mi[0];
9174 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009175}
9176
Yaowu Xuc27fc142016-08-22 16:08:15 -07009177// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009178int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009179 return (cpi->oxcf.pass == 2) &&
9180 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9181 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9182}
9183
9184// Checks to see if a super block is on a horizontal image edge.
9185// In most cases this is the "real" edge unless there are formatting
9186// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009187int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009188 int top_edge = 0;
9189 int bottom_edge = cpi->common.mi_rows;
9190 int is_active_h_edge = 0;
9191
9192 // For two pass account for any formatting bars detected.
9193 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009194 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009195
9196 // The inactive region is specified in MBs not mi units.
9197 // The image edge is in the following MB row.
9198 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9199
9200 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009201 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009202 }
9203
9204 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9205 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9206 is_active_h_edge = 1;
9207 }
9208 return is_active_h_edge;
9209}
9210
9211// Checks to see if a super block is on a vertical image edge.
9212// In most cases this is the "real" edge unless there are formatting
9213// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009214int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009215 int left_edge = 0;
9216 int right_edge = cpi->common.mi_cols;
9217 int is_active_v_edge = 0;
9218
9219 // For two pass account for any formatting bars detected.
9220 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009221 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009222
9223 // The inactive region is specified in MBs not mi units.
9224 // The image edge is in the following MB row.
9225 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9226
9227 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009228 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009229 }
9230
9231 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9232 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9233 is_active_v_edge = 1;
9234 }
9235 return is_active_v_edge;
9236}
9237
9238// Checks to see if a super block is at the edge of the active image.
9239// In most cases this is the "real" edge unless there are formatting
9240// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009241int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009242 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9243 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009244}
9245
Urvang Joshib100db72016-10-12 16:28:56 -07009246#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009247static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009248 MACROBLOCKD *const xd = &x->e_mbd;
9249 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9250 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9251 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009252 int src_stride = x->plane[1].src.stride;
9253 const uint8_t *const src_u = x->plane[1].src.buf;
9254 const uint8_t *const src_v = x->plane[2].src.buf;
9255 float *const data = x->palette_buffer->kmeans_data_buf;
9256 float centroids[2 * PALETTE_MAX_SIZE];
9257 uint8_t *const color_map = xd->plane[1].color_index_map;
9258 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009259#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009260 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9261 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009262#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009263 int plane_block_width, plane_block_height, rows, cols;
9264 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9265 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009266 (void)cpi;
9267
9268 for (r = 0; r < rows; ++r) {
9269 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009270#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009271 if (cpi->common.use_highbitdepth) {
9272 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9273 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9274 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009275#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009276 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9277 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009278#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009279 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009280#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009281 }
9282 }
9283
9284 for (r = 1; r < 3; ++r) {
9285 for (c = 0; c < pmi->palette_size[1]; ++c) {
9286 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9287 }
9288 }
9289
Yaowu Xuf883b422016-08-30 14:01:10 -07009290 av1_calc_indices(data, centroids, color_map, rows * cols,
9291 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009292 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9293 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009294}
Urvang Joshib100db72016-10-12 16:28:56 -07009295#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009296
hui su5db97432016-10-14 16:10:14 -07009297#if CONFIG_FILTER_INTRA
9298static void pick_filter_intra_interframe(
9299 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009300 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9301 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9302 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009303#if CONFIG_EXT_INTRA
9304 int8_t *uv_angle_delta,
9305#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009306#if CONFIG_PALETTE
9307 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9308#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009309 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9310 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9311 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9312#if CONFIG_SUPERTX
9313 int *returnrate_nocoef,
9314#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009315 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009316 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009317 MACROBLOCKD *const xd = &x->e_mbd;
9318 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009319#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009320 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009321#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009322 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9323 int dc_mode_index;
9324 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009325 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9326 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009327 TX_SIZE uv_tx;
9328
9329 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009330 if (av1_mode_order[i].mode == DC_PRED &&
9331 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009332 break;
9333 dc_mode_index = i;
9334 assert(i < MAX_MODES);
9335
9336 // TODO(huisu): use skip_mask for further speedup.
9337 (void)skip_mask;
9338 mbmi->mode = DC_PRED;
9339 mbmi->uv_mode = DC_PRED;
9340 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009341 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009342 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9343 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009344 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009345 return;
hui su5db97432016-10-14 16:10:14 -07009346 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009347 if (rate_y == INT_MAX) return;
9348
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009349 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9350 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009351 if (rate_uv_intra[uv_tx] == INT_MAX) {
9352 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9353 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9354 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009355#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009356 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009357#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009358 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9359#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009360 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009361#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009362 }
9363
9364 rate_uv = rate_uv_tokenonly[uv_tx];
9365 distortion_uv = dist_uv[uv_tx];
9366 skippable = skippable && skip_uv[uv_tx];
9367 mbmi->uv_mode = 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) {
9370 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9371 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9372 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9373 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9374 }
Urvang Joshib100db72016-10-12 16:28:56 -07009375#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009376#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009377 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009378#endif // CONFIG_EXT_INTRA
9379 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9380 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9381 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9382 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9383 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009384 }
9385
9386 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9387 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009388#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07009389 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
9390 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07009391 rate2 += av1_cost_bit(
9392 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009393#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009394
9395 if (!xd->lossless[mbmi->segment_id]) {
9396 // super_block_yrd above includes the cost of the tx_size in the
9397 // tokenonly rate, but for intra blocks, tx_size is always coded
9398 // (prediction granularity), so we account for it in the full rate,
9399 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009400 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009401 }
9402
hui su5db97432016-10-14 16:10:14 -07009403 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9404 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9405 rate2 += write_uniform_cost(
9406 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9407#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009408 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07009409 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9410 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009411 }
hui su5db97432016-10-14 16:10:14 -07009412#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009413 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009414 rate2 +=
9415 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9416 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9417 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9418 rate2 +=
9419 write_uniform_cost(FILTER_INTRA_MODES,
9420 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009421 }
9422 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009423 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9424 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009425
9426 rate2 += ref_costs_single[INTRA_FRAME];
9427
9428 if (skippable) {
9429 rate2 -= (rate_y + rate_uv);
9430 rate_y = 0;
9431 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009432 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009433 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009434 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009435 }
9436 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009437
9438 if (this_rd < *best_intra_rd) {
9439 *best_intra_rd = this_rd;
9440 *best_intra_mode = mbmi->mode;
9441 }
9442 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009443 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009444
9445 if (this_rd < *best_rd) {
9446 *best_mode_index = dc_mode_index;
9447 mbmi->mv[0].as_int = 0;
9448 rd_cost->rate = rate2;
9449#if CONFIG_SUPERTX
9450 if (x->skip)
9451 *returnrate_nocoef = rate2;
9452 else
9453 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009454 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9455 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9456 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009457#endif // CONFIG_SUPERTX
9458 rd_cost->dist = distortion2;
9459 rd_cost->rdcost = this_rd;
9460 *best_rd = this_rd;
9461 *best_mbmode = *mbmi;
9462 *best_skip2 = 0;
9463 *best_mode_skippable = skippable;
9464 }
9465}
hui su5db97432016-10-14 16:10:14 -07009466#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009467
Yue Chencb60b182016-10-13 15:18:22 -07009468#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009469static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9470 const MACROBLOCKD *xd, int mi_row,
9471 int mi_col, const uint8_t *above,
9472 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009473 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009474#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009475
Urvang Joshi52648442016-10-13 17:27:51 -07009476void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009477 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009478 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009479#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009480 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009481#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009482 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9483 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009484 const AV1_COMMON *const cm = &cpi->common;
9485 const RD_OPT *const rd_opt = &cpi->rd;
9486 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009487 MACROBLOCKD *const xd = &x->e_mbd;
9488 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009489#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009490 const int try_palette =
9491 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009492 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009493#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009494 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9495 const struct segmentation *const seg = &cm->seg;
9496 PREDICTION_MODE this_mode;
9497 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9498 unsigned char segment_id = mbmi->segment_id;
9499 int comp_pred, i, k;
9500 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9501 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009502 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009503#if CONFIG_EXT_INTER
9504 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
9505 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009506#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009507 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9508 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009509 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009510#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009511 AOM_LAST2_FLAG,
9512 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009514 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009515#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009516 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009517#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009518 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009519 };
9520 int64_t best_rd = best_rd_so_far;
9521 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9522 int64_t best_pred_diff[REFERENCE_MODES];
9523 int64_t best_pred_rd[REFERENCE_MODES];
9524 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009525 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9526 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009527 int best_mode_skippable = 0;
9528 int midx, best_mode_index = -1;
9529 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
9530 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07009531 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009532 int64_t best_intra_rd = INT64_MAX;
9533 unsigned int best_pred_sse = UINT_MAX;
9534 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009535 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9536 int64_t dist_uvs[TX_SIZES_ALL];
9537 int skip_uvs[TX_SIZES_ALL];
9538 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009539#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009540 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009541#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009542#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009543 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009544 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009545 uint8_t directional_mode_skip_mask[INTRA_MODES];
9546#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009547#if CONFIG_FILTER_INTRA
9548 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009549 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009550#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009551 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009552 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9553 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9554 int best_skip2 = 0;
9555 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009556 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Urvang Joshie6ca8e82017-03-15 14:57:41 -07009557#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009558 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9559 int64_t best_single_inter_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009560#endif // CONFIG_EXT_INTER
9561 int mode_skip_start = sf->mode_skip_start + 1;
9562 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9563 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9564 int64_t mode_threshold[MAX_MODES];
9565 int *mode_map = tile_data->mode_map[bsize];
9566 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009567#if CONFIG_PVQ
9568 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009569#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009570
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009571 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009572#if CONFIG_MOTION_VAR
9573 { NULL },
9574 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9575 { NULL },
9576 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9577#endif // CONFIG_MOTION_VAR
9578#if CONFIG_EXT_INTER
9579 NULL,
9580 NULL,
9581 NULL,
9582 NULL,
9583 NULL,
9584#else // CONFIG_EXT_INTER
9585 NULL,
9586#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009587 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009588 };
9589
Urvang Joshib100db72016-10-12 16:28:56 -07009590#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009591 const int rows = block_size_high[bsize];
9592 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009593#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9594#if CONFIG_PALETTE
9595 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009596 const MODE_INFO *above_mi = xd->above_mi;
9597 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009598#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009599#if CONFIG_MOTION_VAR
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009600#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009601 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9602 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
9603#else
9604 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
9605 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009606#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009607 DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
9608 DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009609 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9610 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9611 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9612 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009613
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009614#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009615 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9616 int len = sizeof(uint16_t);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009617 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
9618 args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
9619 args.above_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009620 CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009621 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
9622 args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
9623 args.left_pred_buf[2] =
Fergus Simpson073c6f32017-02-17 12:13:48 -08009624 CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009625 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009626#endif // CONFIG_HIGHBITDEPTH
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009627 args.above_pred_buf[0] = tmp_buf1;
9628 args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
9629 args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
9630 args.left_pred_buf[0] = tmp_buf2;
9631 args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
9632 args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009633#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009634 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009635#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009636#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009637
Yaowu Xuf883b422016-08-30 14:01:10 -07009638 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009639
Urvang Joshib100db72016-10-12 16:28:56 -07009640#if CONFIG_PALETTE
9641 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07009642 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009643 if (above_mi)
9644 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9645 if (left_mi)
9646 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9647 }
Urvang Joshib100db72016-10-12 16:28:56 -07009648#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009649
Yaowu Xuc27fc142016-08-22 16:08:15 -07009650 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9651 &comp_mode_p);
9652
9653 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009654 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009655 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9656 for (i = 0; i < MB_MODE_COUNT; ++i) {
9657 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009658 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009659 }
9660 }
9661
9662 rd_cost->rate = INT_MAX;
9663#if CONFIG_SUPERTX
9664 *returnrate_nocoef = INT_MAX;
9665#endif // CONFIG_SUPERTX
9666
9667 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9668 x->pred_mv_sad[ref_frame] = INT_MAX;
9669 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009670#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009671 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009672#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009673 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9674 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9675 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9676 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9677 }
9678 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009679#if CONFIG_GLOBAL_MOTION
9680 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009681 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009682 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9683 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009684 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009685#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009686 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009687#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009688#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009689 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009690#if CONFIG_GLOBAL_MOTION
9691 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009692 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009693 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9694 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009695 .as_int;
9696#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009697 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009698#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009699#endif // CONFIG_EXT_INTER
9700 }
9701
Yaowu Xuc27fc142016-08-22 16:08:15 -07009702 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9703 MODE_INFO *const mi = xd->mi[0];
9704 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9705 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009706 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9707 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009708#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009709 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009710#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009711 candidates, mi_row, mi_col, NULL, NULL,
9712 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009713 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9714 MV_REFERENCE_FRAME rf[2];
9715 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009716 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9717 frame_mv[ZEROMV][rf[0]].as_int ||
9718 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9719 frame_mv[ZEROMV][rf[0]].as_int ||
9720 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9721 frame_mv[ZEROMV][rf[1]].as_int ||
9722 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009723 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9724 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009725 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009726
Yue Chencb60b182016-10-13 15:18:22 -07009727#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009728 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Yue Chenf7ba6472017-04-19 11:08:58 -07009729 if (check_num_overlappable_neighbors(mbmi) &&
9730 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009731 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9732 args.above_pred_buf, dst_width1,
9733 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009734 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009735 args.left_pred_buf, dst_width2,
9736 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07009737 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
9738 mi_col);
Yue Chen5329a2b2017-02-28 17:33:00 +08009739 x->mask_buf = mask2d_buf;
9740 x->wsrc_buf = weighted_src_buf;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009741 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9742 args.above_pred_stride[0], args.left_pred_buf[0],
9743 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009744 }
Yue Chencb60b182016-10-13 15:18:22 -07009745#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009746
9747 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9748 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9749// Skip checking missing references in both single and compound reference
9750// modes. Note that a mode will be skipped iff both reference frames
9751// are masked out.
9752#if CONFIG_EXT_REFS
9753 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9754 ref_frame_skip_mask[0] |= (1 << ref_frame);
9755 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9756 } else {
9757#endif // CONFIG_EXT_REFS
9758 ref_frame_skip_mask[0] |= (1 << ref_frame);
9759 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9760#if CONFIG_EXT_REFS
9761 }
9762#endif // CONFIG_EXT_REFS
9763 } else {
9764 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9765 // Skip fixed mv modes for poor references
9766 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9767 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9768 break;
9769 }
9770 }
9771 }
9772 // If the segment reference frame feature is enabled....
9773 // then do nothing if the current ref frame is not allowed..
9774 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9775 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9776 ref_frame_skip_mask[0] |= (1 << ref_frame);
9777 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9778 }
9779 }
9780
9781 // Disable this drop out case if the ref frame
9782 // segment level feature is enabled for this segment. This is to
9783 // prevent the possibility that we end up unable to pick any mode.
9784 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9785 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9786 // unless ARNR filtering is enabled in which case we want
9787 // an unfiltered alternative. We allow near/nearest as well
9788 // because they may result in zero-zero MVs but be cheaper.
9789 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009790 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009791 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9792#if CONFIG_EXT_REFS
9793 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9794 (1 << BWDREF_FRAME) |
9795#endif // CONFIG_EXT_REFS
9796 (1 << GOLDEN_FRAME);
9797 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9798 // TODO(zoeliu): To further explore whether following needs to be done for
9799 // BWDREF_FRAME as well.
9800 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009801#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009802 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009803 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009804 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009805 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009806#else
9807 zeromv.as_int = 0;
9808#endif // CONFIG_GLOBAL_MOTION
9809 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009810 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009811 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009812 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9813#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009814 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009815 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009816 if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009817 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009818 if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009819 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009820 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009821 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
9822#endif // CONFIG_EXT_INTER
9823 }
9824 }
9825
9826 if (cpi->rc.is_src_frame_alt_ref) {
9827 if (sf->alt_ref_search_fp) {
9828 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9829 mode_skip_mask[ALTREF_FRAME] = 0;
9830 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9831 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9832 }
9833 }
9834
9835 if (sf->alt_ref_search_fp)
9836 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9837 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9838 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9839
9840 if (sf->adaptive_mode_search) {
9841 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9842 cpi->rc.frames_since_golden >= 3)
9843 if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
9844 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9845 }
9846
9847 if (bsize > sf->max_intra_bsize) {
9848 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9849 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9850 }
9851
9852 mode_skip_mask[INTRA_FRAME] |=
9853 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9854
9855 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9856 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9857 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9858
9859 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9860 while (midx > 4) {
9861 uint8_t end_pos = 0;
9862 for (i = 5; i < midx; ++i) {
9863 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9864 uint8_t tmp = mode_map[i];
9865 mode_map[i] = mode_map[i - 1];
9866 mode_map[i - 1] = tmp;
9867 end_pos = i;
9868 }
9869 }
9870 midx = end_pos;
9871 }
9872
9873 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9874 x->use_default_intra_tx_type = 1;
9875 else
9876 x->use_default_intra_tx_type = 0;
9877
9878 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9879 x->use_default_inter_tx_type = 1;
9880 else
9881 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009882#if CONFIG_PVQ
9883 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009884#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009885#if CONFIG_EXT_INTER
9886 for (i = 0; i < MB_MODE_COUNT; ++i)
9887 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9888 modelled_rd[i][ref_frame] = INT64_MAX;
9889#endif // CONFIG_EXT_INTER
9890
9891 for (midx = 0; midx < MAX_MODES; ++midx) {
9892 int mode_index;
9893 int mode_excluded = 0;
9894 int64_t this_rd = INT64_MAX;
9895 int disable_skip = 0;
9896 int compmode_cost = 0;
9897#if CONFIG_EXT_INTER
9898 int compmode_interintra_cost = 0;
Sarah Parker6fdc8532016-11-16 17:47:13 -08009899 int compmode_interinter_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009900#endif // CONFIG_EXT_INTER
9901 int rate2 = 0, rate_y = 0, rate_uv = 0;
9902 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
9903 int skippable = 0;
9904 int this_skip2 = 0;
9905 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009906 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009907#if CONFIG_PVQ
9908 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009909#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009910 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009911 this_mode = av1_mode_order[mode_index].mode;
9912 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9913 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009914 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009915
9916#if CONFIG_EXT_INTER
9917 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9918 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -08009919 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009920 if (!is_interintra_allowed_bsize(bsize)) continue;
9921 }
9922
9923 if (is_inter_compound_mode(this_mode)) {
9924 frame_mv[this_mode][ref_frame].as_int =
9925 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9926 frame_mv[this_mode][second_ref_frame].as_int =
9927 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
9928 }
9929#endif // CONFIG_EXT_INTER
9930
9931 // Look at the reference frame of the best mode so far and set the
9932 // skip mask to look at a subset of the remaining modes.
9933 if (midx == mode_skip_start && best_mode_index >= 0) {
9934 switch (best_mbmode.ref_frame[0]) {
9935 case INTRA_FRAME: break;
9936 case LAST_FRAME:
9937 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9938 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9939 break;
9940#if CONFIG_EXT_REFS
9941 case LAST2_FRAME:
9942 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9943 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9944 break;
9945 case LAST3_FRAME:
9946 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9947 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9948 break;
9949#endif // CONFIG_EXT_REFS
9950 case GOLDEN_FRAME:
9951 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9952 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9953 break;
9954#if CONFIG_EXT_REFS
9955 case BWDREF_FRAME:
9956 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9957 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9958 break;
9959#endif // CONFIG_EXT_REFS
9960 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9961#if CONFIG_EXT_REFS
9962 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9963#endif // CONFIG_EXT_REFS
9964 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009965 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009966 case TOTAL_REFS_PER_FRAME:
9967 assert(0 && "Invalid Reference frame");
9968 break;
9969 }
9970 }
9971
9972 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009973 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009974 continue;
9975
9976 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
9977
9978 // Test best rd so far against threshold for trying this mode.
9979 if (best_mode_skippable && sf->schedule_mode_search)
9980 mode_threshold[mode_index] <<= 1;
9981
9982 if (best_rd < mode_threshold[mode_index]) continue;
9983
Yunqing Wangff4fa062017-04-21 10:56:08 -07009984 // This is only used in motion vector unit test.
9985 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
9986
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +02009987#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
9988#if CONFIG_EXT_REFS
9989 if (cpi->oxcf.pass == 0) {
9990 // Complexity-compression trade-offs
9991 // if (ref_frame == ALTREF_FRAME) continue;
9992 // if (ref_frame == BWDREF_FRAME) continue;
9993 if (second_ref_frame == ALTREF_FRAME) continue;
9994 // if (second_ref_frame == BWDREF_FRAME) continue;
9995 }
9996#endif
9997#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009998 comp_pred = second_ref_frame > INTRA_FRAME;
9999 if (comp_pred) {
10000 if (!cpi->allow_comp_inter_inter) continue;
10001
10002 // Skip compound inter modes if ARF is not available.
10003 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10004
10005 // Do not allow compound prediction if the segment level reference frame
10006 // feature is in use as in this case there can only be one reference.
10007 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10008
10009 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10010 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10011 continue;
10012
10013 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10014 } else {
10015 if (ref_frame != INTRA_FRAME)
10016 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10017 }
10018
10019 if (ref_frame == INTRA_FRAME) {
10020 if (sf->adaptive_mode_search)
10021 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10022 continue;
10023
10024 if (this_mode != DC_PRED) {
10025 // Disable intra modes other than DC_PRED for blocks with low variance
10026 // Threshold for intra skipping based on source variance
10027 // TODO(debargha): Specialize the threshold for super block sizes
10028 const unsigned int skip_intra_var_thresh = 64;
10029 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10030 x->source_variance < skip_intra_var_thresh)
10031 continue;
10032 // Only search the oblique modes if the best so far is
10033 // one of the neighboring directional modes
10034 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10035 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10036 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10037 continue;
10038 }
10039 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10040 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10041 }
10042 }
Sarah Parkere5299862016-08-16 14:57:37 -070010043#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010044 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010045 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010046 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010047#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010048 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010049#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010050 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10051 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010052#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010053 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010054#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010055 frame_mv, this_mode, ref_frames, bsize, -1,
10056 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010057 continue;
10058 }
10059
10060 mbmi->mode = this_mode;
10061 mbmi->uv_mode = DC_PRED;
10062 mbmi->ref_frame[0] = ref_frame;
10063 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010064#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010065 pmi->palette_size[0] = 0;
10066 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010067#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010068#if CONFIG_FILTER_INTRA
10069 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10070 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10071#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010072 // Evaluate all sub-pel filters irrespective of whether we can use
10073 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010074
10075 set_default_interp_filters(mbmi, cm->interp_filter);
10076
Yaowu Xuc27fc142016-08-22 16:08:15 -070010077 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010078 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010079
10080 x->skip = 0;
10081 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10082
10083 // Select prediction reference frames.
10084 for (i = 0; i < MAX_MB_PLANE; i++) {
10085 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10086 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10087 }
10088
10089#if CONFIG_EXT_INTER
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010090 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010091#endif // CONFIG_EXT_INTER
10092
10093 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010094 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010095 TX_SIZE uv_tx;
10096 struct macroblockd_plane *const pd = &xd->plane[1];
10097#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010098 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010099 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -080010100 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010101 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010102 if (!angle_stats_ready) {
10103 const int src_stride = x->plane[0].src.stride;
10104 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010105#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010106 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -070010107 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010108 directional_mode_skip_mask);
10109 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010110#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -070010111 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010112 directional_mode_skip_mask);
10113 angle_stats_ready = 1;
10114 }
10115 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010116 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -070010117 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
10118 intra_mode_cost[mbmi->mode], best_rd,
10119 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010120 } else {
10121 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010122 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010123 }
10124#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010125 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010126#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010127 rate_y = rd_stats_y.rate;
10128 distortion_y = rd_stats_y.dist;
10129 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010130
10131 if (rate_y == INT_MAX) continue;
10132
hui su5db97432016-10-14 16:10:14 -070010133#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010134 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010135#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010136
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010137 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10138 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010139 if (rate_uv_intra[uv_tx] == INT_MAX) {
10140 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010141 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10142 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010143#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010144 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010145#endif // CONFIG_PALETTE
10146
Yaowu Xuc27fc142016-08-22 16:08:15 -070010147#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010148 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10149#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010150#if CONFIG_FILTER_INTRA
10151 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10152#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010153 }
10154
10155 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010156 distortion_uv = dist_uvs[uv_tx];
10157 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010158 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010159#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010160 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010161 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10162 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10163 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10164 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10165 }
Urvang Joshib100db72016-10-12 16:28:56 -070010166#endif // CONFIG_PALETTE
10167
Yaowu Xuc27fc142016-08-22 16:08:15 -070010168#if CONFIG_EXT_INTRA
10169 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010170#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010171#if CONFIG_FILTER_INTRA
10172 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10173 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10174 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10175 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10176 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10177 }
10178#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010179
Jingning Han36fe3202017-02-20 22:31:49 -080010180#if CONFIG_CB4X4
10181 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10182 if (!x->skip_chroma_rd)
10183 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10184#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010185 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10186 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010187#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010188
Urvang Joshib100db72016-10-12 16:28:56 -070010189#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010190 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010191 rate2 += av1_cost_bit(
10192 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -070010193 }
Urvang Joshib100db72016-10-12 16:28:56 -070010194#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010195
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010196 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010197 // super_block_yrd above includes the cost of the tx_size in the
10198 // tokenonly rate, but for intra blocks, tx_size is always coded
10199 // (prediction granularity), so we account for it in the full rate,
10200 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010201 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010202 }
10203#if CONFIG_EXT_INTRA
10204 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -080010205#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010206 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -070010207 const int p_angle =
10208 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -070010209 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010210 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010211#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -070010212 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10213 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010214 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010215 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su0a6731f2017-04-26 15:23:47 -070010216 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10217 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010218 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010219#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010220#if CONFIG_FILTER_INTRA
10221 if (mbmi->mode == DC_PRED) {
10222 rate2 +=
10223 av1_cost_bit(cm->fc->filter_intra_probs[0],
10224 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10225 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10226 rate2 += write_uniform_cost(
10227 FILTER_INTRA_MODES,
10228 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10229 }
10230 }
10231 if (mbmi->uv_mode == DC_PRED) {
10232 rate2 +=
10233 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10234 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10235 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10236 rate2 += write_uniform_cost(
10237 FILTER_INTRA_MODES,
10238 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10239 }
10240#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -070010241 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010242 rate2 += intra_cost_penalty;
10243 distortion2 = distortion_y + distortion_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010244 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010245 int_mv backup_ref_mv[2];
10246
Jingning Hanc41a5492017-02-24 11:18:52 -080010247#if !SUB8X8_COMP_REF
10248 if (bsize < BLOCK_8X8 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010249#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010250
Yaowu Xuc27fc142016-08-22 16:08:15 -070010251 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10252 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010253#if CONFIG_EXT_INTER
10254 if (second_ref_frame == INTRA_FRAME) {
10255 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010256 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010257// TODO(debargha|geza.lore):
10258// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010259#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010260 mbmi->angle_delta[0] = 0;
10261 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010262#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010263 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010264#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010265#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010266#if CONFIG_FILTER_INTRA
10267 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10268 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10269#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010270 }
10271#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010272 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010273 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010274
David Barker404b2e82017-03-27 13:07:47 +010010275#if CONFIG_EXT_INTER
10276 if (comp_pred) {
10277 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +010010278 int ref_mv_idx = 0;
10279 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10280 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10281 // mbmi->ref_mv_idx (like NEWMV)
10282 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10283 ref_mv_idx = 1;
10284
10285 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10286 int_mv this_mv =
10287 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +010010288 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10289 xd->n8_h << MI_SIZE_LOG2, xd);
10290 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10291 }
David Barker3dfba992017-04-03 16:10:09 +010010292 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10293 int_mv this_mv =
10294 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +010010295 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10296 xd->n8_h << MI_SIZE_LOG2, xd);
10297 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10298 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010299 }
David Barker404b2e82017-03-27 13:07:47 +010010300 } else {
10301#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -070010302 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +010010303 int ref;
10304 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10305 int_mv this_mv =
10306 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10307 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10308 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[ref]][0] = this_mv;
10311 }
10312 }
10313#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010314 }
David Barker404b2e82017-03-27 13:07:47 +010010315#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010316 {
10317 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10318 av1_init_rd_stats(&rd_stats);
10319 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010320
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010321 // Point to variables that are maintained between loop iterations
10322 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010323#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010324 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010325 args.compmode_interintra_cost = &compmode_interintra_cost;
10326 args.compmode_interinter_cost = &compmode_interinter_cost;
10327 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010328#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010329 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10330 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010331 mi_row, mi_col, &args, best_rd);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010332// Prevent pointers from escaping local scope
Yaowu Xuc27fc142016-08-22 16:08:15 -070010333#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010334 args.compmode_interintra_cost = NULL;
10335 args.compmode_interinter_cost = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010336#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010337
10338 rate2 = rd_stats.rate;
10339 skippable = rd_stats.skip;
10340 distortion2 = rd_stats.dist;
10341 total_sse = rd_stats.sse;
10342 rate_y = rd_stats_y.rate;
10343 rate_uv = rd_stats_uv.rate;
10344 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010345
David Barker404b2e82017-03-27 13:07:47 +010010346// TODO(jingning): This needs some refactoring to improve code quality
10347// and reduce redundant steps.
10348#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010349 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +010010350 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10351 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10352 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10353#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010354 if ((mbmi->mode == NEARMV &&
10355 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10356 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
David Barker404b2e82017-03-27 13:07:47 +010010357#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010358 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10359 MB_MODE_INFO backup_mbmi = *mbmi;
10360 int backup_skip = x->skip;
10361 int64_t tmp_ref_rd = this_rd;
10362 int ref_idx;
10363
Yue Chen6e601e92016-12-05 18:19:00 -080010364// TODO(jingning): This should be deprecated shortly.
10365#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010366 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010367#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010368 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010369#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010370 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010371 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010372
10373 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010374 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010375 // Dummy
10376 int_mv backup_fmv[2];
10377 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10378 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10379
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010380 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010381
10382 if (this_rd < INT64_MAX) {
10383 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
10384 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
10385 tmp_ref_rd =
10386 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010387 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010388 distortion2);
10389 else
10390 tmp_ref_rd =
10391 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -070010392 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010393 rate_y - rate_uv,
10394 total_sse);
10395 }
10396#if CONFIG_VAR_TX
10397 for (i = 0; i < MAX_MB_PLANE; ++i)
10398 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10399 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010400#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010401
10402 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10403 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010404 int dummy_disable_skip = 0;
10405 int ref;
10406 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010407 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yue Chen6e601e92016-12-05 18:19:00 -080010408#if CONFIG_EXT_INTER
10409 int tmp_compmode_interintra_cost = 0;
10410 int tmp_compmode_interinter_cost = 0;
10411#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010412
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010413 av1_invalid_rd_stats(&tmp_rd_stats);
Jingning Han52617b22017-04-11 12:50:08 -070010414 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010415
Yaowu Xuc27fc142016-08-22 16:08:15 -070010416 mbmi->ref_mv_idx = 1 + ref_idx;
10417
David Barker3dfba992017-04-03 16:10:09 +010010418#if CONFIG_EXT_INTER
10419 if (comp_pred) {
10420 int ref_mv_idx = mbmi->ref_mv_idx;
10421 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10422 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10423 // mbmi->ref_mv_idx (like NEWMV)
10424 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10425 ref_mv_idx = 1 + mbmi->ref_mv_idx;
10426
10427 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10428 int_mv this_mv =
10429 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10430 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10431 xd->n8_h << MI_SIZE_LOG2, xd);
10432 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10433 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
10434 int_mv this_mv =
10435 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10436 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10437 xd->n8_h << MI_SIZE_LOG2, xd);
10438 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10439 }
10440
10441 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10442 int_mv this_mv =
10443 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
10444 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10445 xd->n8_h << MI_SIZE_LOG2, xd);
10446 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10447 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10448 int_mv this_mv =
10449 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10450 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10451 xd->n8_h << MI_SIZE_LOG2, xd);
10452 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10453 }
10454 } else {
10455#endif // CONFIG_EXT_INTER
10456 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10457 int_mv this_mv =
10458 (ref == 0)
10459 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10460 .this_mv
10461 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10462 .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[ref]][0] = this_mv;
10466 }
10467#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010468 }
David Barker3dfba992017-04-03 16:10:09 +010010469#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010470
10471 cur_mv =
10472 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10473 .this_mv;
10474 clamp_mv2(&cur_mv.as_mv, xd);
10475
Alex Converse0fa0f422017-04-24 12:51:14 -070010476 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010477 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010478#if CONFIG_EXT_INTER
10479 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -080010480#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010481
10482 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010483 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -080010484
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010485 // Point to variables that are not maintained between iterations
10486 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010487#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010488 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010489 args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
10490 args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
10491 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010492#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010493 tmp_alt_rd = handle_inter_mode(
10494 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
10495 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010496 // Prevent pointers from escaping local scope
10497 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010498#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010499 args.single_newmv_rate = NULL;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010500 args.compmode_interintra_cost = NULL;
10501 args.compmode_interinter_cost = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010502#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010503 }
10504
10505 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10506 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010507 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10508 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010509 tmp_rd_stats.rate +=
10510 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10511 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010512 }
10513
10514 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10515 mbmi->ref_mv_idx + idx_offset + 1 &&
10516 ref_idx < ref_set - 1) {
10517 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010518 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10519 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010520 tmp_rd_stats.rate +=
10521 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10522 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010523 }
10524
10525 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010526#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -080010527 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
10528 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010529#else
Angie Chiang76159122016-11-09 12:13:22 -080010530 if (RDCOST(x->rdmult, x->rddiv,
10531 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
10532 tmp_rd_stats.dist) <
10533 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -070010534 tmp_alt_rd =
10535 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010536 tmp_rd_stats.rate +
10537 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10538 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010539 else
Yaowu Xuf883b422016-08-30 14:01:10 -070010540 tmp_alt_rd =
10541 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -080010542 tmp_rd_stats.rate +
10543 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10544 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10545 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010546#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010547 }
10548
10549 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010550 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010551 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010552 distortion2 = tmp_rd_stats.dist;
10553 skippable = tmp_rd_stats.skip;
10554 rate_y = tmp_rd_stats_y.rate;
10555 rate_uv = tmp_rd_stats_uv.rate;
10556 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010557 this_rd = tmp_alt_rd;
10558 tmp_ref_rd = tmp_alt_rd;
10559 backup_mbmi = *mbmi;
10560 backup_skip = x->skip;
10561#if CONFIG_VAR_TX
10562 for (i = 0; i < MAX_MB_PLANE; ++i)
10563 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10564 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010565#endif // CONFIG_VAR_TX
Yue Chen6e601e92016-12-05 18:19:00 -080010566#if CONFIG_EXT_INTER
10567 compmode_interintra_cost = tmp_compmode_interintra_cost;
10568 compmode_interinter_cost = tmp_compmode_interinter_cost;
Fergus Simpson4063a682017-02-28 16:52:22 -080010569#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010570 } else {
10571 *mbmi = backup_mbmi;
10572 x->skip = backup_skip;
10573 }
10574 }
10575
10576 frame_mv[NEARMV][ref_frame] = backup_mv;
10577 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10578 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10579#if CONFIG_VAR_TX
10580 for (i = 0; i < MAX_MB_PLANE; ++i)
10581 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10582 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010583#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010584 }
10585 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10586 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010587
10588 if (this_rd == INT64_MAX) continue;
10589
Jingning Hanc41a5492017-02-24 11:18:52 -080010590#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010591 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010592#else
10593 if (mbmi->sb_type >= BLOCK_8X8)
10594 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010595#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010596
10597 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10598 }
10599
10600#if CONFIG_EXT_INTER
10601 rate2 += compmode_interintra_cost;
10602 if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
Yue Chencb60b182016-10-13 15:18:22 -070010603#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
10604 if (mbmi->motion_mode == SIMPLE_TRANSLATION)
10605#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -080010606 rate2 += compmode_interinter_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010607#endif // CONFIG_EXT_INTER
10608
10609 // Estimate the reference frame signaling cost and add it
10610 // to the rolling cost variable.
10611 if (comp_pred) {
10612 rate2 += ref_costs_comp[ref_frame];
10613#if CONFIG_EXT_REFS
10614 rate2 += ref_costs_comp[second_ref_frame];
10615#endif // CONFIG_EXT_REFS
10616 } else {
10617 rate2 += ref_costs_single[ref_frame];
10618 }
10619
Yue Chen69f18e12016-09-08 14:48:15 -070010620#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010621 if (ref_frame == INTRA_FRAME) {
10622#else
10623 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010624#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010625 if (skippable) {
10626 // Back out the coefficient coding costs
10627 rate2 -= (rate_y + rate_uv);
10628 rate_y = 0;
10629 rate_uv = 0;
10630 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010631 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010632 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -070010633 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
10634 distortion2) <
10635 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010636 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010637 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010638 } else {
10639 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010640 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010641 distortion2 = total_sse;
10642 assert(total_sse >= 0);
10643 rate2 -= (rate_y + rate_uv);
10644 this_skip2 = 1;
10645 rate_y = 0;
10646 rate_uv = 0;
10647 }
10648 } else {
10649 // 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 }
10652
10653 // Calculate the final RD estimate for this mode.
10654 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010655#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010656 } else {
10657 this_skip2 = mbmi->skip;
10658 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10659 if (this_skip2) {
10660 rate_y = 0;
10661 rate_uv = 0;
10662 }
Yue Chen69f18e12016-09-08 14:48:15 -070010663#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010664 }
10665
Yaowu Xuc27fc142016-08-22 16:08:15 -070010666 if (ref_frame == INTRA_FRAME) {
10667 // Keep record of best intra rd
10668 if (this_rd < best_intra_rd) {
10669 best_intra_rd = this_rd;
10670 best_intra_mode = mbmi->mode;
10671 }
10672#if CONFIG_EXT_INTER
Emil Keyder01770b32017-01-20 18:03:11 -050010673 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 if (this_rd < best_single_inter_rd) {
10675 best_single_inter_rd = this_rd;
10676 best_single_inter_ref = mbmi->ref_frame[0];
10677 }
10678#endif // CONFIG_EXT_INTER
10679 }
10680
10681 if (!disable_skip && ref_frame == INTRA_FRAME) {
10682 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010683 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010684 }
10685
10686 // Did this mode help.. i.e. is it the new best mode
10687 if (this_rd < best_rd || x->skip) {
10688 if (!mode_excluded) {
10689 // Note index of best mode so far
10690 best_mode_index = mode_index;
10691
10692 if (ref_frame == INTRA_FRAME) {
10693 /* required for left and above block mv */
10694 mbmi->mv[0].as_int = 0;
10695 } else {
10696 best_pred_sse = x->pred_sse[ref_frame];
10697 }
10698
10699 rd_cost->rate = rate2;
10700#if CONFIG_SUPERTX
10701 if (x->skip)
10702 *returnrate_nocoef = rate2;
10703 else
10704 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010705 *returnrate_nocoef -= av1_cost_bit(
10706 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10707 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10708 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010709#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -070010710#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10711 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -080010712 const MOTION_MODE motion_allowed = motion_mode_allowed(
10713#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10714 0, xd->global_motion,
10715#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10716 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -080010717 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -070010718 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -080010719 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010720 *returnrate_nocoef -=
10721 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -070010722#else
10723 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010724#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010725#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010726#endif // CONFIG_SUPERTX
10727 rd_cost->dist = distortion2;
10728 rd_cost->rdcost = this_rd;
10729 best_rd = this_rd;
10730 best_mbmode = *mbmi;
10731 best_skip2 = this_skip2;
10732 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010733 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10734 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010735 best_rate_uv = rate_uv;
10736
10737#if CONFIG_VAR_TX
10738 for (i = 0; i < MAX_MB_PLANE; ++i)
10739 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10740 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010741#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010742 }
10743 }
10744
10745 /* keep record of best compound/single-only prediction */
10746 if (!disable_skip && ref_frame != INTRA_FRAME) {
10747 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10748
10749 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10750 single_rate = rate2 - compmode_cost;
10751 hybrid_rate = rate2;
10752 } else {
10753 single_rate = rate2;
10754 hybrid_rate = rate2 + compmode_cost;
10755 }
10756
10757 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
10758 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
10759
10760 if (!comp_pred) {
10761 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10762 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10763 } else {
10764 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10765 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10766 }
10767 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10768 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10769 }
10770
Yaowu Xuc27fc142016-08-22 16:08:15 -070010771 if (x->skip && !comp_pred) break;
10772 }
10773
10774 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10775 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10776 is_inter_mode(best_mbmode.mode)) ||
10777 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10778 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010779 int skip_blk = 0;
10780 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010781
10782 x->use_default_inter_tx_type = 0;
10783 x->use_default_intra_tx_type = 0;
10784
10785 *mbmi = best_mbmode;
10786
10787 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10788
10789 // Select prediction reference frames.
10790 for (i = 0; i < MAX_MB_PLANE; i++) {
10791 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10792 if (has_second_ref(mbmi))
10793 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10794 }
10795
10796 if (is_inter_mode(mbmi->mode)) {
Sarah Parker4c10a3c2017-04-10 19:37:59 -070010797 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -070010798#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010799 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -080010800 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010801 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10802 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010803 }
Yue Chencb60b182016-10-13 15:18:22 -070010804#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010805 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010806#if CONFIG_VAR_TX
10807 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010808 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010809 } else {
10810 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010811 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010812 for (idy = 0; idy < xd->n8_h; ++idy)
10813 for (idx = 0; idx < xd->n8_w; ++idx)
10814 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010815 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010816 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10817 }
10818
Angie Chiangb5dda482016-11-02 16:19:58 -070010819 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010820#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010821 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010822 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010823#endif // CONFIG_VAR_TX
10824 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010825 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010826 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010827 }
10828
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010829 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10830 (rd_stats_y.dist + rd_stats_uv.dist)) >
10831 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010832 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010833 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10834 rd_stats_uv.rate = 0;
10835 rd_stats_y.dist = rd_stats_y.sse;
10836 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010837 } else {
10838 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010839 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010840 }
10841
10842 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010843 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
10844 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010845#if CONFIG_VAR_TX
10846 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080010847#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010848 best_mbmode.tx_type = mbmi->tx_type;
10849 best_mbmode.tx_size = mbmi->tx_size;
10850#if CONFIG_VAR_TX
10851 for (idy = 0; idy < xd->n8_h; ++idy)
10852 for (idx = 0; idx < xd->n8_w; ++idx)
10853 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
10854
10855 for (i = 0; i < MAX_MB_PLANE; ++i)
10856 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10857 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070010858
10859 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080010860#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010861 rd_cost->rate +=
10862 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
10863 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010864 rd_cost->rdcost =
10865 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
10866 best_skip2 = skip_blk;
10867 }
10868 }
10869
Urvang Joshib100db72016-10-12 16:28:56 -070010870#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010871 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -070010872 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010873 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010874#if CONFIG_SUPERTX
10875 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010876#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080010877 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10878 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010879 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010880 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010881 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010882 uint8_t *const best_palette_color_map =
10883 x->palette_buffer->best_palette_color_map;
10884 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010885 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010886
10887 mbmi->mode = DC_PRED;
10888 mbmi->uv_mode = DC_PRED;
10889 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010890 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010891 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010892 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10893 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10894 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010895 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10896 memcpy(color_map, best_palette_color_map,
10897 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010898 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10899 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010900 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10901 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010902 if (rate_uv_intra[uv_tx] == INT_MAX) {
10903 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010904 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10905 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010906 pmi_uv[uv_tx] = *pmi;
10907#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010908 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10909#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010910#if CONFIG_FILTER_INTRA
10911 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10912#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010913 }
10914 mbmi->uv_mode = mode_uv[uv_tx];
10915 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080010916 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010917 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10918 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10919 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080010920 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010921#if CONFIG_EXT_INTRA
10922 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010923#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010924#if CONFIG_FILTER_INTRA
10925 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10926 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10927 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10928 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10929 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10930 }
10931#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010932 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
10933 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
10934 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010935 rate2 += ref_costs_single[INTRA_FRAME];
10936
10937 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010938 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010939#if CONFIG_SUPERTX
10940 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080010941#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010942 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010943 } else {
10944#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010945 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080010946#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010947 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010948 }
10949 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10950 if (this_rd < best_rd) {
10951 best_mode_index = 3;
10952 mbmi->mv[0].as_int = 0;
10953 rd_cost->rate = rate2;
10954#if CONFIG_SUPERTX
10955 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010956#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010957 rd_cost->dist = distortion2;
10958 rd_cost->rdcost = this_rd;
10959 best_rd = this_rd;
10960 best_mbmode = *mbmi;
10961 best_skip2 = 0;
10962 best_mode_skippable = skippable;
10963 }
10964 }
10965PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070010966#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010967
hui su5db97432016-10-14 16:10:14 -070010968#if CONFIG_FILTER_INTRA
10969 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070010970 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070010971 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070010972#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080010973 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070010974#endif // CONFIG_PALETTE
10975 !dc_skipped && best_mode_index >= 0 &&
10976 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070010977 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080010978 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
10979 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070010980#if CONFIG_EXT_INTRA
10981 uv_angle_delta,
10982#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070010983#if CONFIG_PALETTE
10984 pmi_uv, palette_ctx,
10985#endif // CONFIG_PALETTE
10986 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010987 &best_mode_index, &best_skip2, &best_mode_skippable,
10988#if CONFIG_SUPERTX
10989 returnrate_nocoef,
10990#endif // CONFIG_SUPERTX
10991 best_pred_rd, &best_mbmode, rd_cost);
10992 }
hui su5db97432016-10-14 16:10:14 -070010993#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010994
10995 // The inter modes' rate costs are not calculated precisely in some cases.
10996 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
10997 // ZEROMV. Here, checks are added for those cases, and the mode decisions
10998 // are corrected.
10999 if (best_mbmode.mode == NEWMV
11000#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070011001 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011002#endif // CONFIG_EXT_INTER
11003 ) {
11004 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11005 best_mbmode.ref_frame[1] };
11006 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011007 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070011008 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011009#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011010 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11011 cm->allow_high_precision_mv, bsize,
11012 mi_col, mi_row, 0)
11013 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011014 zeromv[1].as_int = comp_pred_mode
11015 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11016 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011017 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011018 .as_int
11019 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011020#else
11021 zeromv[0].as_int = 0;
11022 zeromv[1].as_int = 0;
11023#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011024 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011025 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011026 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011027 : INT_MAX;
11028
11029 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11030 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11031 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11032 best_mbmode.mode = NEARMV;
11033 best_mbmode.ref_mv_idx = i;
11034 }
11035 }
11036
11037 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11038 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011039 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011040 best_mbmode.mode = ZEROMV;
11041 } else {
11042 int_mv nearestmv[2];
11043 int_mv nearmv[2];
11044
11045#if CONFIG_EXT_INTER
11046 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11047 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11048 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11049 } else {
11050 nearmv[0] = frame_mv[NEARMV][refs[0]];
11051 nearmv[1] = frame_mv[NEARMV][refs[1]];
11052 }
11053#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011054 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011055 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011056 : INT_MAX;
11057
11058 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11059 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11060 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11061
11062 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11063 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11064 best_mbmode.mode = NEARMV;
11065 best_mbmode.ref_mv_idx = i;
11066 }
11067 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011068#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011069 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11070 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11071 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11072 } else {
11073 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11074 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11075 }
11076
11077 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011078 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011079#if CONFIG_EXT_INTER
11080 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011081 } else {
11082 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
11083 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
11084 : INT_MAX;
11085
11086 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11087 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11088 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11089
David Barker3dfba992017-04-03 16:10:09 +010011090 // Try switching to the NEAR_NEAREST type modes first
11091 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011092 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
David Barker3dfba992017-04-03 16:10:09 +010011093 best_mbmode.mode = NEAREST_NEARMV;
11094 best_mbmode.ref_mv_idx = i;
11095 } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11096 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
11097 best_mbmode.mode = NEAR_NEARESTMV;
11098 best_mbmode.ref_mv_idx = i;
11099 } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11100 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
David Barker404b2e82017-03-27 13:07:47 +010011101 best_mbmode.mode = NEAR_NEARMV;
11102 best_mbmode.ref_mv_idx = i;
11103 }
11104 }
11105
David Barker3dfba992017-04-03 16:10:09 +010011106 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010011107 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11108 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11109 best_mbmode.mode = ZERO_ZEROMV;
11110 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011111#else
11112 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011113 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11114 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011115 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010011116 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011117#endif // CONFIG_EXT_INTER
11118 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011119 }
11120
David Barker9620bcd2017-03-22 14:46:42 +000011121 // Make sure that the ref_mv_idx is only nonzero when we're
11122 // using a mode which can support ref_mv_idx
11123 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010011124#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010011125 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
11126 have_nearmv_in_inter_mode(best_mbmode.mode))) {
David Barker404b2e82017-03-27 13:07:47 +010011127#else
David Barker9620bcd2017-03-22 14:46:42 +000011128 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
David Barker404b2e82017-03-27 13:07:47 +010011129#endif
David Barker9620bcd2017-03-22 14:46:42 +000011130 best_mbmode.ref_mv_idx = 0;
11131 }
11132
David Barkercdcac6d2016-12-01 17:04:16 +000011133 {
Jingning Han731af492016-11-17 11:53:23 -080011134 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11135 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011136 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011137 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011138#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011139 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11140 best_mbmode.ref_frame[1] };
11141 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011142 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011143 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011144 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070011145 zeromv[1].as_int = (refs[1] != NONE_FRAME)
11146 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11147 cm->allow_high_precision_mv,
11148 bsize, mi_col, mi_row, 0)
11149 .as_int
11150 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000011151 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11152 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11153#else
11154 zeromv[0].as_int = zeromv[1].as_int = 0;
11155#endif // CONFIG_GLOBAL_MOTION
11156 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11157 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11158#if CONFIG_EXT_INTER
11159 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11160#else
Emil Keyder01770b32017-01-20 18:03:11 -050011161 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011162 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11163#endif // CONFIG_EXT_INTER
11164 ) {
11165 best_mbmode.mode = ZEROMV;
11166 }
David Barker68e6e862016-11-24 15:10:15 +000011167 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011168 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011169
11170 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11171 rd_cost->rate = INT_MAX;
11172 rd_cost->rdcost = INT64_MAX;
11173 return;
11174 }
11175
Yaowu Xuc27fc142016-08-22 16:08:15 -070011176#if CONFIG_DUAL_FILTER
11177 assert((cm->interp_filter == SWITCHABLE) ||
11178 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11179 !is_inter_block(&best_mbmode));
11180 assert((cm->interp_filter == SWITCHABLE) ||
11181 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11182 !is_inter_block(&best_mbmode));
11183 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11184 assert((cm->interp_filter == SWITCHABLE) ||
11185 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11186 !is_inter_block(&best_mbmode));
11187 assert((cm->interp_filter == SWITCHABLE) ||
11188 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11189 !is_inter_block(&best_mbmode));
11190 }
11191#else
11192 assert((cm->interp_filter == SWITCHABLE) ||
11193 (cm->interp_filter == best_mbmode.interp_filter) ||
11194 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011195#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011196
11197 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011198 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11199 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011200
11201 // macroblock modes
11202 *mbmi = best_mbmode;
11203 x->skip |= best_skip2;
11204
Yue Chen19e7aa82016-11-30 14:05:39 -080011205// Note: this section is needed since the mode may have been forced to
11206// ZEROMV by the all-zero mode handling of ref-mv.
11207#if CONFIG_GLOBAL_MOTION
11208 if (mbmi->mode == ZEROMV
11209#if CONFIG_EXT_INTER
11210 || mbmi->mode == ZERO_ZEROMV
11211#endif // CONFIG_EXT_INTER
11212 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011213#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11214 // Correct the motion mode for ZEROMV
11215 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11216#if SEPARATE_GLOBAL_MOTION
11217 0, xd->global_motion,
11218#endif // SEPARATE_GLOBAL_MOTION
11219 xd->mi[0]);
11220 if (mbmi->motion_mode > last_motion_mode_allowed)
11221 mbmi->motion_mode = last_motion_mode_allowed;
11222#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11223
11224 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011225 if (is_nontrans_global_motion(xd)) {
11226#if CONFIG_DUAL_FILTER
11227 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11228 ? EIGHTTAP_REGULAR
11229 : cm->interp_filter;
11230 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11231 ? EIGHTTAP_REGULAR
11232 : cm->interp_filter;
11233#else
11234 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11235 : cm->interp_filter;
11236#endif // CONFIG_DUAL_FILTER
11237 }
11238 }
11239#endif // CONFIG_GLOBAL_MOTION
11240
Yaowu Xuc27fc142016-08-22 16:08:15 -070011241 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11242 if (mbmi->mode != NEWMV)
11243 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11244 else
11245 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11246 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011247
11248 for (i = 0; i < REFERENCE_MODES; ++i) {
11249 if (best_pred_rd[i] == INT64_MAX)
11250 best_pred_diff[i] = INT_MIN;
11251 else
11252 best_pred_diff[i] = best_rd - best_pred_rd[i];
11253 }
11254
11255 x->skip |= best_mode_skippable;
11256
11257 assert(best_mode_index >= 0);
11258
11259 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11260 best_mode_skippable);
11261
Urvang Joshib100db72016-10-12 16:28:56 -070011262#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011263 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11264 restore_uv_color_map(cpi, x);
11265 }
Urvang Joshib100db72016-10-12 16:28:56 -070011266#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011267}
11268
Urvang Joshi52648442016-10-13 17:27:51 -070011269void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11270 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011271 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011272 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011273 PICK_MODE_CONTEXT *ctx,
11274 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011275 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011276 MACROBLOCKD *const xd = &x->e_mbd;
11277 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11278 unsigned char segment_id = mbmi->segment_id;
11279 const int comp_pred = 0;
11280 int i;
11281 int64_t best_pred_diff[REFERENCE_MODES];
11282 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11283 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011284 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011285 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011286 int64_t this_rd = INT64_MAX;
11287 int rate2 = 0;
11288 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011289 (void)mi_row;
11290 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011291
11292 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11293 &comp_mode_p);
11294
11295 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11296 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11297 x->pred_mv_sad[i] = INT_MAX;
11298
11299 rd_cost->rate = INT_MAX;
11300
11301 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11302
Urvang Joshib100db72016-10-12 16:28:56 -070011303#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011304 mbmi->palette_mode_info.palette_size[0] = 0;
11305 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011306#endif // CONFIG_PALETTE
11307
hui su5db97432016-10-14 16:10:14 -070011308#if CONFIG_FILTER_INTRA
11309 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11310 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11311#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011312 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011313 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011314 mbmi->uv_mode = DC_PRED;
11315 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011316 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011317#if CONFIG_GLOBAL_MOTION
11318 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011319 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011320 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11321 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011322 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011323#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011324 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011325#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011326 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011327 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011328
Yaowu Xuc27fc142016-08-22 16:08:15 -070011329 mbmi->ref_mv_idx = 0;
11330 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011331
Yue Chendead17d2017-04-20 16:19:39 -070011332 mbmi->motion_mode = SIMPLE_TRANSLATION;
11333#if CONFIG_MOTION_VAR
11334 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
11335#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070011336#if CONFIG_WARPED_MOTION
11337 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
11338 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
11339 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
11340 }
11341#endif
Yue Chendead17d2017-04-20 16:19:39 -070011342
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011343 set_default_interp_filters(mbmi, cm->interp_filter);
11344
11345 if (cm->interp_filter != SWITCHABLE) {
11346 best_filter = cm->interp_filter;
11347 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011348 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011349 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011350 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11351 int rs;
11352 int best_rs = INT_MAX;
11353 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11354#if CONFIG_DUAL_FILTER
11355 int k;
11356 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11357#else
11358 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011359#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011360 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011361 if (rs < best_rs) {
11362 best_rs = rs;
11363#if CONFIG_DUAL_FILTER
11364 best_filter = mbmi->interp_filter[0];
11365#else
11366 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011367#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011368 }
11369 }
11370 }
11371 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011372// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070011373#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011374 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011375#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011376 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011377#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011378 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011379
11380 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011381 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011382
11383 // Estimate the reference frame signaling cost and add it
11384 // to the rolling cost variable.
11385 rate2 += ref_costs_single[LAST_FRAME];
11386 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
11387
11388 rd_cost->rate = rate2;
11389 rd_cost->dist = distortion2;
11390 rd_cost->rdcost = this_rd;
11391
11392 if (this_rd >= best_rd_so_far) {
11393 rd_cost->rate = INT_MAX;
11394 rd_cost->rdcost = INT64_MAX;
11395 return;
11396 }
11397
11398#if CONFIG_DUAL_FILTER
11399 assert((cm->interp_filter == SWITCHABLE) ||
11400 (cm->interp_filter == mbmi->interp_filter[0]));
11401#else
11402 assert((cm->interp_filter == SWITCHABLE) ||
11403 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011404#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011405
Yaowu Xuf883b422016-08-30 14:01:10 -070011406 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11407 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011408
Yaowu Xuf883b422016-08-30 14:01:10 -070011409 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011410
11411 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11412}
11413
Urvang Joshi52648442016-10-13 17:27:51 -070011414void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
11415 TileDataEnc *tile_data, struct macroblock *x,
11416 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011417 struct RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011418#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011419 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011420#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011421 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
11422 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011423 const AV1_COMMON *const cm = &cpi->common;
11424 const RD_OPT *const rd_opt = &cpi->rd;
11425 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011426 MACROBLOCKD *const xd = &x->e_mbd;
11427 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11428 const struct segmentation *const seg = &cm->seg;
11429 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
11430 unsigned char segment_id = mbmi->segment_id;
11431 int comp_pred, i;
11432 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
11433 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
11434 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
11435 0,
Yaowu Xuf883b422016-08-30 14:01:10 -070011436 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011437#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011438 AOM_LAST2_FLAG,
11439 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011440#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011441 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011442#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011443 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011444#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011445 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -070011446 };
11447 int64_t best_rd = best_rd_so_far;
11448 int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
11449 int64_t best_pred_diff[REFERENCE_MODES];
11450 int64_t best_pred_rd[REFERENCE_MODES];
11451 MB_MODE_INFO best_mbmode;
11452 int ref_index, best_ref_index = 0;
11453 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
11454 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070011455 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011456#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070011457 InterpFilter tmp_best_filter[4] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -070011458#else
James Zern7b9407a2016-05-18 23:48:05 -070011459 InterpFilter tmp_best_filter = SWITCHABLE;
Fergus Simpson4063a682017-02-28 16:52:22 -080011460#endif // CONFIG_DUAL_FILTER
Jingning Han3f167252016-06-07 16:11:42 -070011461 int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
11462 int64_t dist_uv = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011463 int skip_uv;
11464 PREDICTION_MODE mode_uv = DC_PRED;
Yaowu Xuf883b422016-08-30 14:01:10 -070011465 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011466 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011467 int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011468 b_mode_info best_bmodes[4];
11469 int best_skip2 = 0;
11470 int ref_frame_skip_mask[2] = { 0 };
11471 int internal_active_edge =
Yaowu Xuf883b422016-08-30 14:01:10 -070011472 av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
Yushin Cho77bba8d2016-11-04 16:36:56 -070011473#if CONFIG_PVQ
11474 od_rollback_buffer pre_buf;
11475
11476 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011477#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -070011478
11479#if CONFIG_SUPERTX
11480 best_rd_so_far = INT64_MAX;
11481 best_rd = best_rd_so_far;
11482 best_yrd = best_rd_so_far;
11483#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011484 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011485
hui su5db97432016-10-14 16:10:14 -070011486#if CONFIG_FILTER_INTRA
11487 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11488 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11489#endif // CONFIG_FILTER_INTRA
Yue Chencb60b182016-10-13 15:18:22 -070011490 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011491#if CONFIG_EXT_INTER
Sarah Parker2d0e9b72017-05-04 01:34:16 +000011492 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011493 mbmi->use_wedge_interintra = 0;
11494#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -070011495#if CONFIG_WARPED_MOTION
11496 mbmi->num_proj_ref[0] = 0;
11497 mbmi->num_proj_ref[1] = 0;
11498#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011499
11500 for (i = 0; i < 4; i++) {
11501 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011502 for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
11503 seg_mvs[i][j].as_int = INVALID_MV;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011504 }
11505
11506 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11507 &comp_mode_p);
11508
11509 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
11510 rate_uv_intra = INT_MAX;
11511
11512 rd_cost->rate = INT_MAX;
11513#if CONFIG_SUPERTX
11514 *returnrate_nocoef = INT_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -080011515#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011516
11517 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
11518 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011519#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011520 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +020011521#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011522 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
11523 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
11524 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
11525 } else {
11526 ref_frame_skip_mask[0] |= (1 << ref_frame);
11527 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11528 }
11529 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
11530#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011531#endif // CONFIG_EXT_INTER
11532 frame_mv[ZEROMV][ref_frame].as_int = 0;
11533 }
11534
Urvang Joshib100db72016-10-12 16:28:56 -070011535#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011536 mbmi->palette_mode_info.palette_size[0] = 0;
11537 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011538#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011539
11540 for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
11541 int mode_excluded = 0;
11542 int64_t this_rd = INT64_MAX;
11543 int disable_skip = 0;
11544 int compmode_cost = 0;
11545 int rate2 = 0, rate_y = 0, rate_uv = 0;
11546 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
11547 int skippable = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011548 int this_skip2 = 0;
11549 int64_t total_sse = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011550
Yushin Cho77bba8d2016-11-04 16:36:56 -070011551#if CONFIG_PVQ
11552 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -080011553#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -070011554
Yaowu Xuf883b422016-08-30 14:01:10 -070011555 ref_frame = av1_ref_order[ref_index].ref_frame[0];
11556 second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011557
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011558 mbmi->ref_mv_idx = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070011559
Yaowu Xuc27fc142016-08-22 16:08:15 -070011560 // Look at the reference frame of the best mode so far and set the
11561 // skip mask to look at a subset of the remaining modes.
11562 if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
11563 if (ref_index == 3) {
11564 switch (best_mbmode.ref_frame[0]) {
11565 case INTRA_FRAME: break;
11566 case LAST_FRAME:
11567 ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
11568#if CONFIG_EXT_REFS
11569 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11570 (1 << BWDREF_FRAME) |
11571#endif // CONFIG_EXT_REFS
11572 (1 << ALTREF_FRAME);
11573 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11574 break;
11575#if CONFIG_EXT_REFS
11576 case LAST2_FRAME:
11577 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
11578 (1 << GOLDEN_FRAME) |
11579 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11580 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11581 break;
11582 case LAST3_FRAME:
11583 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11584 (1 << GOLDEN_FRAME) |
11585 (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
11586 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11587 break;
11588#endif // CONFIG_EXT_REFS
11589 case GOLDEN_FRAME:
11590 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11591#if CONFIG_EXT_REFS
11592 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11593 (1 << BWDREF_FRAME) |
11594#endif // CONFIG_EXT_REFS
11595 (1 << ALTREF_FRAME);
11596 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
11597 break;
11598#if CONFIG_EXT_REFS
11599 case BWDREF_FRAME:
11600 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
11601 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
11602 (1 << ALTREF_FRAME);
11603 ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
11604 break;
11605#endif // CONFIG_EXT_REFS
11606 case ALTREF_FRAME:
11607 ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
11608#if CONFIG_EXT_REFS
11609 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
11610 (1 << BWDREF_FRAME) |
11611#endif // CONFIG_EXT_REFS
11612 (1 << GOLDEN_FRAME);
11613#if CONFIG_EXT_REFS
11614 ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
11615#endif // CONFIG_EXT_REFS
11616 break;
Emil Keyder01770b32017-01-20 18:03:11 -050011617 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -070011618 case TOTAL_REFS_PER_FRAME:
11619 assert(0 && "Invalid Reference frame");
11620 break;
11621 }
11622 }
11623 }
11624
11625 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011626 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011627 continue;
11628
11629 // Test best rd so far against threshold for trying this mode.
11630 if (!internal_active_edge &&
11631 rd_less_than_thresh(best_rd,
11632 rd_opt->threshes[segment_id][bsize][ref_index],
11633 tile_data->thresh_freq_fact[bsize][ref_index]))
11634 continue;
11635
Yunqing Wangff4fa062017-04-21 10:56:08 -070011636 // This is only used in motion vector unit test.
11637 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
11638
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020011639#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
11640#if CONFIG_EXT_REFS
11641 if (cpi->oxcf.pass == 0) {
11642 // Complexity-compression trade-offs
11643 // if (ref_frame == ALTREF_FRAME) continue;
11644 // if (ref_frame == BWDREF_FRAME) continue;
11645 if (second_ref_frame == ALTREF_FRAME) continue;
11646 // if (second_ref_frame == BWDREF_FRAME) continue;
11647 }
11648#endif
11649#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011650 comp_pred = second_ref_frame > INTRA_FRAME;
11651 if (comp_pred) {
11652 if (!cpi->allow_comp_inter_inter) continue;
11653 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
11654 // Do not allow compound prediction if the segment level reference frame
11655 // feature is in use as in this case there can only be one reference.
11656 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
11657
11658 if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
11659 best_mbmode.ref_frame[0] == INTRA_FRAME)
11660 continue;
11661 }
11662
11663 // TODO(jingning, jkoleszar): scaling reference frame not supported for
11664 // sub8x8 blocks.
11665 if (ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011666 av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011667 continue;
11668
11669 if (second_ref_frame > INTRA_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -070011670 av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
Yaowu Xuc27fc142016-08-22 16:08:15 -070011671 continue;
11672
11673 if (comp_pred)
11674 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
11675 else if (ref_frame != INTRA_FRAME)
11676 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
11677
11678 // If the segment reference frame feature is enabled....
11679 // then do nothing if the current ref frame is not allowed..
11680 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
11681 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
11682 continue;
11683 // Disable this drop out case if the ref frame
11684 // segment level feature is enabled for this segment. This is to
11685 // prevent the possibility that we end up unable to pick any mode.
11686 } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
11687 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
11688 // unless ARNR filtering is enabled in which case we want
11689 // an unfiltered alternative. We allow near/nearest as well
11690 // because they may result in zero-zero MVs but be cheaper.
11691 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
11692 continue;
11693 }
11694
11695 mbmi->tx_size = TX_4X4;
11696 mbmi->uv_mode = DC_PRED;
11697 mbmi->ref_frame[0] = ref_frame;
11698 mbmi->ref_frame[1] = second_ref_frame;
11699// Evaluate all sub-pel filters irrespective of whether we can use
11700// them for this frame.
11701#if CONFIG_DUAL_FILTER
11702 for (i = 0; i < 4; ++i)
11703 mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
11704 ? EIGHTTAP_REGULAR
11705 : cm->interp_filter;
11706#else
11707 mbmi->interp_filter =
11708 cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011709#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011710 x->skip = 0;
11711 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
11712
11713 // Select prediction reference frames.
11714 for (i = 0; i < MAX_MB_PLANE; i++) {
11715 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
11716 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
11717 }
11718
11719#if CONFIG_VAR_TX
11720 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -070011721 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -080011722#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011723
11724 if (ref_frame == INTRA_FRAME) {
11725 int rate;
11726 if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -070011727 NULL, best_rd) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011728 continue;
11729 rate2 += rate;
11730 rate2 += intra_cost_penalty;
11731 distortion2 += distortion_y;
11732
11733 if (rate_uv_intra == INT_MAX) {
11734 choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
11735 &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
11736 }
11737 rate2 += rate_uv_intra;
11738 rate_uv = rate_uv_tokenonly;
11739 distortion2 += dist_uv;
11740 distortion_uv = dist_uv;
11741 mbmi->uv_mode = mode_uv;
11742 } else {
11743 int rate;
11744 int64_t distortion;
11745 int64_t this_rd_thresh;
11746 int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
11747 int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
11748 int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
11749 int tmp_best_skippable = 0;
11750 int switchable_filter_index;
11751 int_mv *second_ref =
11752 comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
11753 b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
11754 MB_MODE_INFO tmp_best_mbmode;
11755#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011756 BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011757#else
11758 BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
Fergus Simpson4063a682017-02-28 16:52:22 -080011759#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011760 int pred_exists = 0;
11761 int uv_skippable;
11762#if CONFIG_EXT_INTER
11763 int_mv compound_seg_newmvs[4][2];
11764 for (i = 0; i < 4; i++) {
11765 compound_seg_newmvs[i][0].as_int = INVALID_MV;
11766 compound_seg_newmvs[i][1].as_int = INVALID_MV;
11767 }
11768#endif // CONFIG_EXT_INTER
11769
11770 this_rd_thresh = (ref_frame == LAST_FRAME)
11771 ? rd_opt->threshes[segment_id][bsize][THR_LAST]
11772 : rd_opt->threshes[segment_id][bsize][THR_ALTR];
11773#if CONFIG_EXT_REFS
11774 this_rd_thresh = (ref_frame == LAST2_FRAME)
11775 ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
11776 : this_rd_thresh;
11777 this_rd_thresh = (ref_frame == LAST3_FRAME)
11778 ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
11779 : this_rd_thresh;
Zoe Liua6a6dd52016-10-18 13:03:12 -070011780 this_rd_thresh = (ref_frame == BWDREF_FRAME)
11781 ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
11782 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011783#endif // CONFIG_EXT_REFS
11784 this_rd_thresh = (ref_frame == GOLDEN_FRAME)
11785 ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
11786 : this_rd_thresh;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011787
11788 // TODO(any): Add search of the tx_type to improve rd performance at the
11789 // expense of speed.
11790 mbmi->tx_type = DCT_DCT;
11791
11792 if (cm->interp_filter != BILINEAR) {
11793#if CONFIG_DUAL_FILTER
11794 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11795 tmp_best_filter[1] = EIGHTTAP_REGULAR;
11796 tmp_best_filter[2] = EIGHTTAP_REGULAR;
11797 tmp_best_filter[3] = EIGHTTAP_REGULAR;
11798#else
11799 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011800#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011801 if (x->source_variance < sf->disable_filter_search_var_thresh) {
11802#if CONFIG_DUAL_FILTER
11803 tmp_best_filter[0] = EIGHTTAP_REGULAR;
11804#else
11805 tmp_best_filter = EIGHTTAP_REGULAR;
Fergus Simpson4063a682017-02-28 16:52:22 -080011806#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011807 } else if (sf->adaptive_pred_interp_filter == 1 &&
11808 ctx->pred_interp_filter < SWITCHABLE) {
11809#if CONFIG_DUAL_FILTER
11810 tmp_best_filter[0] = ctx->pred_interp_filter;
11811#else
11812 tmp_best_filter = ctx->pred_interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011813#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011814 } else if (sf->adaptive_pred_interp_filter == 2) {
11815#if CONFIG_DUAL_FILTER
11816 tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
11817 ? ctx->pred_interp_filter
11818 : 0;
11819#else
11820 tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
11821 ? ctx->pred_interp_filter
11822 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080011823#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011824 } else {
11825#if CONFIG_DUAL_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080011826 const int filter_set_size = DUAL_FILTER_SET_SIZE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011827#else
Angie Chiang5678ad92016-11-21 09:38:40 -080011828 const int filter_set_size = SWITCHABLE_FILTERS;
Fergus Simpson4063a682017-02-28 16:52:22 -080011829#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011830 for (switchable_filter_index = 0;
Angie Chiang5678ad92016-11-21 09:38:40 -080011831 switchable_filter_index < filter_set_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011832 ++switchable_filter_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011833 int newbest, rs;
11834 int64_t rs_rd;
11835 MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
11836#if CONFIG_DUAL_FILTER
11837 mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
11838 mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
11839 mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
11840 mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
11841#else
11842 mbmi->interp_filter = switchable_filter_index;
Fergus Simpson4063a682017-02-28 16:52:22 -080011843#endif // CONFIG_DUAL_FILTER
Yushin Cho482016d2017-01-06 14:06:13 -080011844 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011845 cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11846 &rate, &rate_y, &distortion, &skippable, &total_sse,
11847 (int)this_rd_thresh, seg_mvs,
11848#if CONFIG_EXT_INTER
11849 compound_seg_newmvs,
11850#endif // CONFIG_EXT_INTER
11851 bsi, switchable_filter_index, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011852 if (tmp_rd == INT64_MAX) continue;
Yaowu Xuf883b422016-08-30 14:01:10 -070011853 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011854 rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
11855 if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
11856
11857 newbest = (tmp_rd < tmp_best_rd);
11858 if (newbest) {
11859#if CONFIG_DUAL_FILTER
11860 tmp_best_filter[0] = mbmi->interp_filter[0];
11861 tmp_best_filter[1] = mbmi->interp_filter[1];
11862 tmp_best_filter[2] = mbmi->interp_filter[2];
11863 tmp_best_filter[3] = mbmi->interp_filter[3];
11864#else
11865 tmp_best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011866#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011867 tmp_best_rd = tmp_rd;
11868 }
11869 if ((newbest && cm->interp_filter == SWITCHABLE) ||
11870 (
11871#if CONFIG_DUAL_FILTER
11872 mbmi->interp_filter[0] == cm->interp_filter
11873#else
11874 mbmi->interp_filter == cm->interp_filter
Fergus Simpson4063a682017-02-28 16:52:22 -080011875#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011876 && cm->interp_filter != SWITCHABLE)) {
11877 tmp_best_rdu = tmp_rd;
11878 tmp_best_rate = rate;
11879 tmp_best_ratey = rate_y;
11880 tmp_best_distortion = distortion;
11881 tmp_best_sse = total_sse;
11882 tmp_best_skippable = skippable;
11883 tmp_best_mbmode = *mbmi;
11884 for (i = 0; i < 4; i++) {
11885 tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
11886 }
11887 pred_exists = 1;
11888 }
11889 } // switchable_filter_index loop
11890 }
11891 }
11892
11893 if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
11894
11895#if CONFIG_DUAL_FILTER
11896 mbmi->interp_filter[0] =
11897 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
11898 : cm->interp_filter);
11899 mbmi->interp_filter[1] =
11900 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
11901 : cm->interp_filter);
11902 mbmi->interp_filter[2] =
11903 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
11904 : cm->interp_filter);
11905 mbmi->interp_filter[3] =
11906 (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
11907 : cm->interp_filter);
11908#else
11909 mbmi->interp_filter =
11910 (cm->interp_filter == SWITCHABLE ? tmp_best_filter
11911 : cm->interp_filter);
Fergus Simpson4063a682017-02-28 16:52:22 -080011912#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011913
11914 if (!pred_exists) {
11915 // Handles the special case when a filter that is not in the
11916 // switchable list (bilinear) is indicated at the frame level
Yushin Cho482016d2017-01-06 14:06:13 -080011917 tmp_rd = rd_pick_inter_best_sub8x8_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -070011918 cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
11919 &rate, &rate_y, &distortion, &skippable, &total_sse,
11920 (int)this_rd_thresh, seg_mvs,
11921#if CONFIG_EXT_INTER
11922 compound_seg_newmvs,
11923#endif // CONFIG_EXT_INTER
11924 bsi, 0, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011925 if (tmp_rd == INT64_MAX) continue;
11926 } else {
11927 total_sse = tmp_best_sse;
11928 rate = tmp_best_rate;
11929 rate_y = tmp_best_ratey;
11930 distortion = tmp_best_distortion;
11931 skippable = tmp_best_skippable;
11932 *mbmi = tmp_best_mbmode;
11933 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
11934 }
11935 // Add in the cost of the transform type
11936 if (!xd->lossless[mbmi->segment_id]) {
11937 int rate_tx_type = 0;
11938#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -080011939 if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
11940 1) {
11941 const int eset =
11942 get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011943 rate_tx_type =
11944 cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
11945 }
11946#else
11947 if (mbmi->tx_size < TX_32X32) {
11948 rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
11949 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011950#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011951 rate += rate_tx_type;
11952 rate_y += rate_tx_type;
11953 }
11954
11955 rate2 += rate;
11956 distortion2 += distortion;
11957
11958 if (cm->interp_filter == SWITCHABLE)
Yaowu Xuf883b422016-08-30 14:01:10 -070011959 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011960
11961 if (!mode_excluded)
11962 mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
11963 : cm->reference_mode == COMPOUND_REFERENCE;
11964
Yaowu Xuf883b422016-08-30 14:01:10 -070011965 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011966
11967 tmp_best_rdu =
Yaowu Xuf883b422016-08-30 14:01:10 -070011968 best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011969 RDCOST(x->rdmult, x->rddiv, 0, total_sse));
11970
11971 if (tmp_best_rdu > 0) {
11972 // If even the 'Y' rd value of split is higher than best so far
11973 // then dont bother looking at UV
Angie Chiangb5dda482016-11-02 16:19:58 -070011974 int is_cost_valid_uv;
Angie Chiangb5dda482016-11-02 16:19:58 -070011975 RD_STATS rd_stats_uv;
David Barkerac37fa32016-12-02 12:30:21 +000011976 av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
11977 BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011978#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070011979 is_cost_valid_uv =
11980 inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Angie Chiang284d7772016-11-08 11:06:45 -080011981#else
11982 is_cost_valid_uv =
11983 super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
Fergus Simpson4063a682017-02-28 16:52:22 -080011984#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -070011985 rate_uv = rd_stats_uv.rate;
11986 distortion_uv = rd_stats_uv.dist;
11987 uv_skippable = rd_stats_uv.skip;
11988 uv_sse = rd_stats_uv.sse;
Angie Chiang284d7772016-11-08 11:06:45 -080011989
Angie Chiangb5dda482016-11-02 16:19:58 -070011990 if (!is_cost_valid_uv) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011991 rate2 += rate_uv;
11992 distortion2 += distortion_uv;
11993 skippable = skippable && uv_skippable;
11994 total_sse += uv_sse;
11995 } else {
11996 continue;
11997 }
11998 }
11999
12000 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
12001
12002 // Estimate the reference frame signaling cost and add it
12003 // to the rolling cost variable.
12004 if (second_ref_frame > INTRA_FRAME) {
12005 rate2 += ref_costs_comp[ref_frame];
12006#if CONFIG_EXT_REFS
12007 rate2 += ref_costs_comp[second_ref_frame];
12008#endif // CONFIG_EXT_REFS
12009 } else {
12010 rate2 += ref_costs_single[ref_frame];
12011 }
12012
12013 if (!disable_skip) {
12014 // Skip is never coded at the segment level for sub8x8 blocks and instead
12015 // always coded in the bitstream at the mode info level.
12016
12017 if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
12018 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
12019 RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
12020 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070012021 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012022 } else {
12023 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070012024 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012025 distortion2 = total_sse;
12026 assert(total_sse >= 0);
12027 rate2 -= (rate_y + rate_uv);
12028 rate_y = 0;
12029 rate_uv = 0;
12030 this_skip2 = 1;
12031 }
12032 } else {
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 }
12036
12037 // Calculate the final RD estimate for this mode.
12038 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
12039 }
12040
12041 if (!disable_skip && ref_frame == INTRA_FRAME) {
12042 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070012043 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012044 }
12045
12046 // Did this mode help.. i.e. is it the new best mode
12047 if (this_rd < best_rd || x->skip) {
12048 if (!mode_excluded) {
12049 // Note index of best mode so far
12050 best_ref_index = ref_index;
12051
12052 if (ref_frame == INTRA_FRAME) {
12053 /* required for left and above block mv */
12054 mbmi->mv[0].as_int = 0;
12055 }
12056
12057 rd_cost->rate = rate2;
12058#if CONFIG_SUPERTX
12059 *returnrate_nocoef = rate2 - rate_y - rate_uv;
12060 if (!disable_skip)
12061 *returnrate_nocoef -=
Yaowu Xuf883b422016-08-30 14:01:10 -070012062 av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
12063 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
12064 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012065 assert(*returnrate_nocoef > 0);
12066#endif // CONFIG_SUPERTX
12067 rd_cost->dist = distortion2;
12068 rd_cost->rdcost = this_rd;
12069 best_rd = this_rd;
12070 best_yrd =
12071 best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
12072 best_mbmode = *mbmi;
12073 best_skip2 = this_skip2;
12074
12075#if CONFIG_VAR_TX
12076 for (i = 0; i < MAX_MB_PLANE; ++i)
12077 memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080012078#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012079
12080 for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -070012081 }
12082 }
12083
12084 /* keep record of best compound/single-only prediction */
12085 if (!disable_skip && ref_frame != INTRA_FRAME) {
12086 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
12087
12088 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
12089 single_rate = rate2 - compmode_cost;
12090 hybrid_rate = rate2;
12091 } else {
12092 single_rate = rate2;
12093 hybrid_rate = rate2 + compmode_cost;
12094 }
12095
12096 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
12097 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
12098
12099 if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
12100 best_pred_rd[SINGLE_REFERENCE] = single_rd;
12101 else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
12102 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
12103
12104 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
12105 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
12106 }
12107
Yaowu Xuc27fc142016-08-22 16:08:15 -070012108 if (x->skip && !comp_pred) break;
12109 }
12110
12111 if (best_rd >= best_rd_so_far) {
12112 rd_cost->rate = INT_MAX;
12113 rd_cost->rdcost = INT64_MAX;
12114#if CONFIG_SUPERTX
12115 *returnrate_nocoef = INT_MAX;
12116#endif // CONFIG_SUPERTX
12117 return;
12118 }
12119
Yaowu Xuc27fc142016-08-22 16:08:15 -070012120 if (best_rd == INT64_MAX) {
12121 rd_cost->rate = INT_MAX;
12122 rd_cost->dist = INT64_MAX;
12123 rd_cost->rdcost = INT64_MAX;
12124#if CONFIG_SUPERTX
12125 *returnrate_nocoef = INT_MAX;
12126#endif // CONFIG_SUPERTX
12127 return;
12128 }
12129
12130#if CONFIG_DUAL_FILTER
12131 assert((cm->interp_filter == SWITCHABLE) ||
12132 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
12133 !is_inter_block(&best_mbmode));
12134#else
12135 assert((cm->interp_filter == SWITCHABLE) ||
12136 (cm->interp_filter == best_mbmode.interp_filter) ||
12137 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080012138#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070012139
Yaowu Xuf883b422016-08-30 14:01:10 -070012140 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
12141 sf->adaptive_rd_thresh, bsize, best_ref_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012142
12143 // macroblock modes
12144 *mbmi = best_mbmode;
Jingning Hanfe45b212016-11-22 10:30:23 -080012145#if CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012146 mbmi->inter_tx_size[0][0] = mbmi->tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080012147#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070012148
12149 x->skip |= best_skip2;
12150 if (!is_inter_block(&best_mbmode)) {
12151 for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
12152 } else {
12153 for (i = 0; i < 4; ++i)
12154 memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
12155
Yaowu Xuf5bbbfa2016-09-26 09:13:38 -070012156 mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
12157 mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
Yaowu Xu4306b6e2016-09-27 12:55:32 -070012158 mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
12159 mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012160 }
12161
Yue Chen19e7aa82016-11-30 14:05:39 -080012162// Note: this section is needed since the mode may have been forced to ZEROMV
12163#if CONFIG_GLOBAL_MOTION
12164 if (mbmi->mode == ZEROMV
12165#if CONFIG_EXT_INTER
12166 || mbmi->mode == ZERO_ZEROMV
12167#endif // CONFIG_EXT_INTER
12168 ) {
12169 if (is_nontrans_global_motion(xd)) {
12170#if CONFIG_DUAL_FILTER
12171 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
12172 ? EIGHTTAP_REGULAR
12173 : cm->interp_filter;
12174 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
12175 ? EIGHTTAP_REGULAR
12176 : cm->interp_filter;
12177#else
12178 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
12179 : cm->interp_filter;
12180#endif // CONFIG_DUAL_FILTER
12181 }
12182 }
12183#endif // CONFIG_GLOBAL_MOTION
12184
Yaowu Xuc27fc142016-08-22 16:08:15 -070012185 for (i = 0; i < REFERENCE_MODES; ++i) {
12186 if (best_pred_rd[i] == INT64_MAX)
12187 best_pred_diff[i] = INT_MIN;
12188 else
12189 best_pred_diff[i] = best_rd - best_pred_rd[i];
12190 }
12191
12192 store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
12193}
12194
Yue Chencb60b182016-10-13 15:18:22 -070012195#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070012196// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070012197//
12198// The OBMC predictor is computed as:
12199//
12200// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012201// AOM_BLEND_A64(Mh(x),
12202// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070012203// PLeft(x, y))
12204//
Yaowu Xuf883b422016-08-30 14:01:10 -070012205// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070012206// rounding, this can be written as:
12207//
Yaowu Xuf883b422016-08-30 14:01:10 -070012208// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070012209// Mh(x) * Mv(y) * P(x,y) +
12210// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012211// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012212//
12213// Where :
12214//
Yaowu Xuf883b422016-08-30 14:01:10 -070012215// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
12216// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012217//
12218// This function computes 'wsrc' and 'mask' as:
12219//
12220// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012221// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070012222// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070012223// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012224//
12225// mask(x, y) = Mh(x) * Mv(y)
12226//
12227// These can then be used to efficiently approximate the error for any
12228// predictor P in the context of the provided neighbouring predictors by
12229// computing:
12230//
12231// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070012232// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070012233//
Yaowu Xuf883b422016-08-30 14:01:10 -070012234static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070012235 const MACROBLOCKD *xd, int mi_row,
12236 int mi_col, const uint8_t *above,
12237 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070012238 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070012239 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
12240 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080012241 const int bw = xd->n8_w << MI_SIZE_LOG2;
12242 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070012243 int32_t *mask_buf = x->mask_buf;
12244 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012245 const int wsrc_stride = bw;
12246 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070012247 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012248#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012249 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
12250#else
12251 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012252#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012253
12254 // plane 0 should not be subsampled
12255 assert(xd->plane[0].subsampling_x == 0);
12256 assert(xd->plane[0].subsampling_y == 0);
12257
Yaowu Xuf883b422016-08-30 14:01:10 -070012258 av1_zero_array(wsrc_buf, bw * bh);
12259 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012260
12261 // handle above row
12262 if (xd->up_available) {
12263 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012264 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012265 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012266 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012267 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
12268 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012269
12270 assert(miw > 0);
12271
12272 i = 0;
12273 do { // for each mi in the above row
12274 const int mi_col_offset = i;
12275 const MB_MODE_INFO *const above_mbmi =
12276 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012277 const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012278 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012279 const int neighbor_bw = mi_step * MI_SIZE;
12280
12281 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012282 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
12283 neighbor_count += 2;
12284 else
12285 neighbor_count++;
12286 if (neighbor_count > neighbor_limit) break;
12287
Yaowu Xuc27fc142016-08-22 16:08:15 -070012288 const int tmp_stride = above_stride;
12289 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
12290 int32_t *mask = mask_buf + (i * MI_SIZE);
12291
12292 if (!is_hbd) {
12293 const uint8_t *tmp = above;
12294
12295 for (row = 0; row < overlap; ++row) {
12296 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012297 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012298 for (col = 0; col < neighbor_bw; ++col) {
12299 wsrc[col] = m1 * tmp[col];
12300 mask[col] = m0;
12301 }
12302 wsrc += wsrc_stride;
12303 mask += mask_stride;
12304 tmp += tmp_stride;
12305 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012306#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012307 } else {
12308 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
12309
12310 for (row = 0; row < overlap; ++row) {
12311 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070012312 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012313 for (col = 0; col < neighbor_bw; ++col) {
12314 wsrc[col] = m1 * tmp[col];
12315 mask[col] = m0;
12316 }
12317 wsrc += wsrc_stride;
12318 mask += mask_stride;
12319 tmp += tmp_stride;
12320 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012321#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012322 }
12323 }
12324
12325 above += neighbor_bw;
12326 i += mi_step;
12327 } while (i < miw);
12328 }
12329
12330 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070012331 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
12332 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012333 }
12334
12335 // handle left column
12336 if (xd->left_available) {
12337 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070012338 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012339 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070012340 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070012341 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
12342 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012343
12344 assert(mih > 0);
12345
12346 i = 0;
12347 do { // for each mi in the left column
12348 const int mi_row_offset = i;
12349 const MB_MODE_INFO *const left_mbmi =
12350 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -070012351 const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
Jingning Han47433992017-05-02 09:03:57 -070012352 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070012353 const int neighbor_bh = mi_step * MI_SIZE;
12354
12355 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070012356 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
12357 neighbor_count += 2;
12358 else
12359 neighbor_count++;
12360 if (neighbor_count > neighbor_limit) break;
12361
Yaowu Xuc27fc142016-08-22 16:08:15 -070012362 const int tmp_stride = left_stride;
12363 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
12364 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
12365
12366 if (!is_hbd) {
12367 const uint8_t *tmp = left;
12368
12369 for (row = 0; row < neighbor_bh; ++row) {
12370 for (col = 0; col < overlap; ++col) {
12371 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012372 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12373 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12374 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12375 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012376 }
12377 wsrc += wsrc_stride;
12378 mask += mask_stride;
12379 tmp += tmp_stride;
12380 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012381#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012382 } else {
12383 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
12384
12385 for (row = 0; row < neighbor_bh; ++row) {
12386 for (col = 0; col < overlap; ++col) {
12387 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070012388 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
12389 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
12390 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
12391 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070012392 }
12393 wsrc += wsrc_stride;
12394 mask += mask_stride;
12395 tmp += tmp_stride;
12396 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012397#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012398 }
12399 }
12400
12401 left += neighbor_bh * left_stride;
12402 i += mi_step;
12403 } while (i < mih);
12404 }
12405
12406 if (!is_hbd) {
12407 const uint8_t *src = x->plane[0].src.buf;
12408
12409 for (row = 0; row < bh; ++row) {
12410 for (col = 0; col < bw; ++col) {
12411 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12412 }
12413 wsrc_buf += wsrc_stride;
12414 src += x->plane[0].src.stride;
12415 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012416#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012417 } else {
12418 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
12419
12420 for (row = 0; row < bh; ++row) {
12421 for (col = 0; col < bw; ++col) {
12422 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
12423 }
12424 wsrc_buf += wsrc_stride;
12425 src += x->plane[0].src.stride;
12426 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020012427#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070012428 }
12429}
Yue Chenf27b1602017-01-13 11:11:43 -080012430
12431#if CONFIG_NCOBMC
12432void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
12433 int mi_row, int mi_col) {
12434 const AV1_COMMON *const cm = &cpi->common;
12435 MACROBLOCKD *const xd = &x->e_mbd;
12436 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
12437 MB_MODE_INFO backup_mbmi;
12438 BLOCK_SIZE bsize = mbmi->sb_type;
12439 int ref, skip_blk, backup_skip = x->skip;
12440 int64_t rd_causal;
12441 RD_STATS rd_stats_y, rd_stats_uv;
12442 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
12443 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
12444
12445 // Recompute the best causal predictor and rd
12446 mbmi->motion_mode = SIMPLE_TRANSLATION;
12447 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
12448 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
12449 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
12450 assert(cfg != NULL);
12451 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
12452 &xd->block_refs[ref]->sf);
12453 }
Jingning Han91d9a792017-04-18 12:01:52 -070012454 av1_setup_dst_planes(x->e_mbd.plane, bsize,
12455 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080012456
12457 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
12458
12459 av1_subtract_plane(x, bsize, 0);
12460 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12461 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12462 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12463 if (rd_stats_y.skip && rd_stats_uv.skip) {
12464 rd_stats_y.rate = rate_skip1;
12465 rd_stats_uv.rate = 0;
12466 rd_stats_y.dist = rd_stats_y.sse;
12467 rd_stats_uv.dist = rd_stats_uv.sse;
12468 skip_blk = 0;
12469 } else if (RDCOST(x->rdmult, x->rddiv,
12470 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12471 (rd_stats_y.dist + rd_stats_uv.dist)) >
12472 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12473 (rd_stats_y.sse + rd_stats_uv.sse))) {
12474 rd_stats_y.rate = rate_skip1;
12475 rd_stats_uv.rate = 0;
12476 rd_stats_y.dist = rd_stats_y.sse;
12477 rd_stats_uv.dist = rd_stats_uv.sse;
12478 skip_blk = 1;
12479 } else {
12480 rd_stats_y.rate += rate_skip0;
12481 skip_blk = 0;
12482 }
12483 backup_skip = skip_blk;
12484 backup_mbmi = *mbmi;
12485 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
12486 (rd_stats_y.dist + rd_stats_uv.dist));
12487 rd_causal += RDCOST(x->rdmult, x->rddiv,
12488 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
12489
12490 // Check non-causal mode
12491 mbmi->motion_mode = OBMC_CAUSAL;
12492 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
12493
12494 av1_subtract_plane(x, bsize, 0);
12495 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
12496 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
12497 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
12498 if (rd_stats_y.skip && rd_stats_uv.skip) {
12499 rd_stats_y.rate = rate_skip1;
12500 rd_stats_uv.rate = 0;
12501 rd_stats_y.dist = rd_stats_y.sse;
12502 rd_stats_uv.dist = rd_stats_uv.sse;
12503 skip_blk = 0;
12504 } else if (RDCOST(x->rdmult, x->rddiv,
12505 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
12506 (rd_stats_y.dist + rd_stats_uv.dist)) >
12507 RDCOST(x->rdmult, x->rddiv, rate_skip1,
12508 (rd_stats_y.sse + rd_stats_uv.sse))) {
12509 rd_stats_y.rate = rate_skip1;
12510 rd_stats_uv.rate = 0;
12511 rd_stats_y.dist = rd_stats_y.sse;
12512 rd_stats_uv.dist = rd_stats_uv.sse;
12513 skip_blk = 1;
12514 } else {
12515 rd_stats_y.rate += rate_skip0;
12516 skip_blk = 0;
12517 }
12518
12519 if (rd_causal >
12520 RDCOST(x->rdmult, x->rddiv,
12521 rd_stats_y.rate + rd_stats_uv.rate +
12522 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
12523 (rd_stats_y.dist + rd_stats_uv.dist))) {
12524 x->skip = skip_blk;
12525 } else {
12526 *mbmi = backup_mbmi;
12527 x->skip = backup_skip;
12528 }
12529}
Fergus Simpson4063a682017-02-28 16:52:22 -080012530#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070012531#endif // CONFIG_MOTION_VAR