blob: 7212709edeb7b429fac83e3cfa99a9e91994d55a [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 Chiangaadbb022017-06-01 16:08:03 -070069#if USE_EXTRA_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080070static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
Angie Chiangd91ab372016-11-21 18:16:49 -080071 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 0 }, { 1, 1 },
72 { 1, 2 }, { 1, 3 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
73 { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 },
Yaowu Xuc27fc142016-08-22 16:08:15 -070074};
Angie Chiangaadbb022017-06-01 16:08:03 -070075#else // USE_EXTRA_FILTER
76static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
77 { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 },
78 { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 },
79};
80#endif // USE_EXTRA_FILTER
Angie Chiang5678ad92016-11-21 09:38:40 -080081#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070082
83#if CONFIG_EXT_REFS
84
85#define LAST_FRAME_MODE_MASK \
86 ((1 << INTRA_FRAME) | (1 << LAST2_FRAME) | (1 << LAST3_FRAME) | \
87 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
88#define LAST2_FRAME_MODE_MASK \
89 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST3_FRAME) | \
90 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
91#define LAST3_FRAME_MODE_MASK \
92 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
93 (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
94#define GOLDEN_FRAME_MODE_MASK \
95 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
96 (1 << LAST3_FRAME) | (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME))
97#define BWDREF_FRAME_MODE_MASK \
98 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
99 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME))
100#define ALTREF_FRAME_MODE_MASK \
101 ((1 << INTRA_FRAME) | (1 << LAST_FRAME) | (1 << LAST2_FRAME) | \
102 (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) | (1 << BWDREF_FRAME))
103
104#else
105
106#define LAST_FRAME_MODE_MASK \
107 ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
108#define GOLDEN_FRAME_MODE_MASK \
109 ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | (1 << INTRA_FRAME))
110#define ALTREF_FRAME_MODE_MASK \
111 ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | (1 << INTRA_FRAME))
112
113#endif // CONFIG_EXT_REFS
114
115#if CONFIG_EXT_REFS
116#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
117#else
118#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
119#endif // CONFIG_EXT_REFS
120
121#define MIN_EARLY_TERM_INDEX 3
122#define NEW_MV_DISCOUNT_FACTOR 8
123
124#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700125#define ANGLE_SKIP_THRESH 10
126#define FILTER_FAST_SEARCH 1
127#endif // CONFIG_EXT_INTRA
128
129const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
130 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
131
132typedef struct {
133 PREDICTION_MODE mode;
134 MV_REFERENCE_FRAME ref_frame[2];
135} MODE_DEFINITION;
136
137typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
138
139struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700140 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700141 MACROBLOCK *x;
142 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
143 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800144 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700145 int64_t this_rd;
146 int64_t best_rd;
147 int exit_early;
148 int use_fast_coef_costing;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700149};
150
151#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700152static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500153 { NEARESTMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500155 { NEARESTMV, { LAST2_FRAME, NONE_FRAME } },
156 { NEARESTMV, { LAST3_FRAME, NONE_FRAME } },
157 { NEARESTMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700158#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500159 { NEARESTMV, { ALTREF_FRAME, NONE_FRAME } },
160 { NEARESTMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700161
Emil Keyder01770b32017-01-20 18:03:11 -0500162 { DC_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163
Emil Keyder01770b32017-01-20 18:03:11 -0500164 { NEWMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500166 { NEWMV, { LAST2_FRAME, NONE_FRAME } },
167 { NEWMV, { LAST3_FRAME, NONE_FRAME } },
168 { NEWMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500170 { NEWMV, { ALTREF_FRAME, NONE_FRAME } },
171 { NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172
Emil Keyder01770b32017-01-20 18:03:11 -0500173 { NEARMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700174#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500175 { NEARMV, { LAST2_FRAME, NONE_FRAME } },
176 { NEARMV, { LAST3_FRAME, NONE_FRAME } },
177 { NEARMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700178#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500179 { NEARMV, { ALTREF_FRAME, NONE_FRAME } },
180 { NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181
Emil Keyder01770b32017-01-20 18:03:11 -0500182 { ZEROMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500184 { ZEROMV, { LAST2_FRAME, NONE_FRAME } },
185 { ZEROMV, { LAST3_FRAME, NONE_FRAME } },
186 { ZEROMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700187#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500188 { ZEROMV, { GOLDEN_FRAME, NONE_FRAME } },
189 { ZEROMV, { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190
191// TODO(zoeliu): May need to reconsider the order on the modes to check
192
193#if CONFIG_EXT_INTER
194 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
195#if CONFIG_EXT_REFS
196 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
197 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
198#endif // CONFIG_EXT_REFS
199 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
200#if CONFIG_EXT_REFS
201 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
202 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
203 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
204 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
205#endif // CONFIG_EXT_REFS
206
207#else // CONFIG_EXT_INTER
208
209 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
210#if CONFIG_EXT_REFS
211 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
212 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
213#endif // CONFIG_EXT_REFS
214 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
215#if CONFIG_EXT_REFS
216 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
217 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
218 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
219 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
220#endif // CONFIG_EXT_REFS
221#endif // CONFIG_EXT_INTER
222
Emil Keyder01770b32017-01-20 18:03:11 -0500223 { TM_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700224
Urvang Joshi6be4a542016-11-03 15:24:05 -0700225#if CONFIG_ALT_INTRA
Emil Keyder01770b32017-01-20 18:03:11 -0500226 { SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
Urvang Joshie6ca8e82017-03-15 14:57:41 -0700227#if CONFIG_SMOOTH_HV
228 { SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
229 { SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
230#endif // CONFIG_SMOOTH_HV
Urvang Joshi6be4a542016-11-03 15:24:05 -0700231#endif // CONFIG_ALT_INTRA
232
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700234 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
235 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
236 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
237 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
238 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
239 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
240 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
241
242#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700243 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
244 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
245 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
246 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
247 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
248 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
249 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
250
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
252 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
253 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
254 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
255 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
256 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
257 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
258#endif // CONFIG_EXT_REFS
259
Yaowu Xuc27fc142016-08-22 16:08:15 -0700260 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
261 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
262 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
263 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
264 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
265 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
266 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
267
268#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700269 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
270 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
271 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
272 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
273 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
274 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
275 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
276
Yaowu Xuc27fc142016-08-22 16:08:15 -0700277 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
278 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
279 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
280 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
281 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
282 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
283 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
284
Yaowu Xuc27fc142016-08-22 16:08:15 -0700285 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
286 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
287 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
288 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
289 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
290 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
291 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
292
Yaowu Xuc27fc142016-08-22 16:08:15 -0700293 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
294 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
295 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
296 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
297 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
298 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
299 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
300#endif // CONFIG_EXT_REFS
301
302#else // CONFIG_EXT_INTER
303
304 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
305 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
306#if CONFIG_EXT_REFS
307 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
308 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
309 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
310 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
311#endif // CONFIG_EXT_REFS
312 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
313 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
314
315#if CONFIG_EXT_REFS
316 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
317 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
318 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
319 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
320 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
321 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
322 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
323 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
324#endif // CONFIG_EXT_REFS
325
326 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
327#if CONFIG_EXT_REFS
328 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
329 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
330#endif // CONFIG_EXT_REFS
331 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
332
333#if CONFIG_EXT_REFS
334 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
335 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
336 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
337 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
338#endif // CONFIG_EXT_REFS
339
340#endif // CONFIG_EXT_INTER
341
Emil Keyder01770b32017-01-20 18:03:11 -0500342 { H_PRED, { INTRA_FRAME, NONE_FRAME } },
343 { V_PRED, { INTRA_FRAME, NONE_FRAME } },
344 { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
345 { D207_PRED, { INTRA_FRAME, NONE_FRAME } },
346 { D153_PRED, { INTRA_FRAME, NONE_FRAME } },
347 { D63_PRED, { INTRA_FRAME, NONE_FRAME } },
348 { D117_PRED, { INTRA_FRAME, NONE_FRAME } },
349 { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350
351#if CONFIG_EXT_INTER
352 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
353 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
354 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
355 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
356
357#if CONFIG_EXT_REFS
358 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
359 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
360 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
361 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
362
363 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
364 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
365 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
366 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
367#endif // CONFIG_EXT_REFS
368
369 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
370 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
371 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
372 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
373
374#if CONFIG_EXT_REFS
375 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
376 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
377 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
378 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
379#endif // CONFIG_EXT_REFS
380
381 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
382 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
383 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
384 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
385#endif // CONFIG_EXT_INTER
386};
387
hui su5db97432016-10-14 16:10:14 -0700388#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700389static INLINE int write_uniform_cost(int n, int v) {
hui su37499292017-04-26 09:49:53 -0700390 const int l = get_unsigned_bits(n);
391 const int m = (1 << l) - n;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700392 if (l == 0) return 0;
393 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700394 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700395 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700396 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397}
hui su5db97432016-10-14 16:10:14 -0700398#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399
400// constants for prune 1 and prune 2 decision boundaries
401#define FAST_EXT_TX_CORR_MID 0.0
402#define FAST_EXT_TX_EDST_MID 0.1
403#define FAST_EXT_TX_CORR_MARGIN 0.5
404#define FAST_EXT_TX_EDST_MARGIN 0.3
405
Yushin Cho7a428ba2017-01-12 16:28:49 -0800406#if CONFIG_DAALA_DIST
407static int od_compute_var_4x4(od_coeff *x, int stride) {
408 int sum;
409 int s2;
410 int i;
411 sum = 0;
412 s2 = 0;
413 for (i = 0; i < 4; i++) {
414 int j;
415 for (j = 0; j < 4; j++) {
416 int t;
417
418 t = x[i * stride + j];
419 sum += t;
420 s2 += t * t;
421 }
422 }
423 // TODO(yushin) : Check wheter any changes are required for high bit depth.
424 return (s2 - (sum * sum >> 4)) >> 4;
425}
426
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500427/* OD_DIST_LP_MID controls the frequency weighting filter used for computing
428 the distortion. For a value X, the filter is [1 X 1]/(X + 2) and
429 is applied both horizontally and vertically. For X=5, the filter is
430 a good approximation for the OD_QM8_Q4_HVS quantization matrix. */
431#define OD_DIST_LP_MID (5)
432#define OD_DIST_LP_NORM (OD_DIST_LP_MID + 2)
433
Yushin Cho7a428ba2017-01-12 16:28:49 -0800434static double od_compute_dist_8x8(int qm, int use_activity_masking, od_coeff *x,
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500435 od_coeff *y, od_coeff *e_lp, int stride) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800436 double sum;
437 int min_var;
438 double mean_var;
439 double var_stat;
440 double activity;
441 double calibration;
442 int i;
443 int j;
444 double vardist;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800445
446 vardist = 0;
447 OD_ASSERT(qm != OD_FLAT_QM);
Alex Converse76b89632017-03-20 11:47:12 -0700448 (void)qm;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800449#if 1
450 min_var = INT_MAX;
451 mean_var = 0;
452 for (i = 0; i < 3; i++) {
453 for (j = 0; j < 3; j++) {
454 int varx;
455 int vary;
456 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
457 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
458 min_var = OD_MINI(min_var, varx);
459 mean_var += 1. / (1 + varx);
460 /* The cast to (double) is to avoid an overflow before the sqrt.*/
461 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
462 }
463 }
464 /* We use a different variance statistic depending on whether activity
465 masking is used, since the harmonic mean appeared slghtly worse with
466 masking off. The calibration constant just ensures that we preserve the
467 rate compared to activity=1. */
468 if (use_activity_masking) {
469 calibration = 1.95;
470 var_stat = 9. / mean_var;
471 } else {
472 calibration = 1.62;
473 var_stat = min_var;
474 }
475 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
476 activity masking constant. */
477 activity = calibration * pow(.25 + var_stat, -1. / 6);
478#else
479 activity = 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800480#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800481 sum = 0;
482 for (i = 0; i < 8; i++) {
483 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500484 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800485 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500486 /* Normalize the filter to unit DC response. */
487 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
488 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800489 return activity * activity * (sum + vardist);
490}
491
492// Note : Inputs x and y are in a pixel domain
493static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
494 od_coeff *y, int bsize_w, int bsize_h,
495 int qindex) {
496 int i;
497 double sum;
498 sum = 0;
499
Yushin Cho7a428ba2017-01-12 16:28:49 -0800500 assert(bsize_w >= 8 && bsize_h >= 8);
501
502 if (qm == OD_FLAT_QM) {
503 for (i = 0; i < bsize_w * bsize_h; i++) {
504 double tmp;
505 tmp = x[i] - y[i];
506 sum += tmp * tmp;
507 }
508 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500509 int j;
510 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
511 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
512 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
513 int mid = OD_DIST_LP_MID;
514 for (i = 0; i < bsize_h; i++) {
515 for (j = 0; j < bsize_w; j++) {
516 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
517 }
518 }
519 for (i = 0; i < bsize_h; i++) {
520 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
521 tmp[i * bsize_w + bsize_w - 1] =
522 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
523 for (j = 1; j < bsize_w - 1; j++) {
524 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
525 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
526 }
527 }
528 for (j = 0; j < bsize_w; j++) {
529 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
530 e_lp[(bsize_h - 1) * bsize_w + j] =
531 mid * tmp[(bsize_h - 1) * bsize_w + j] +
532 2 * tmp[(bsize_h - 2) * bsize_w + j];
533 }
534 for (i = 1; i < bsize_h - 1; i++) {
535 for (j = 0; j < bsize_w; j++) {
536 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
537 tmp[(i - 1) * bsize_w + j] +
538 tmp[(i + 1) * bsize_w + j];
539 }
540 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800541 for (i = 0; i < bsize_h; i += 8) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800542 for (j = 0; j < bsize_w; j += 8) {
543 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500544 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
545 bsize_w);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800546 }
547 }
David Michael Barrd091b802017-01-21 16:05:46 +0900548 /* Scale according to linear regression against SSE, for 8x8 blocks. */
549 if (activity_masking) {
550 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
551 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
552 } else {
553 sum *= qindex >= 128
554 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
555 : qindex <= 43
556 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
557 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
558 }
Yushin Cho7a428ba2017-01-12 16:28:49 -0800559 }
560 return sum;
561}
562
Yushin Cho63927c42017-05-23 15:41:05 -0700563int64_t av1_daala_dist(const uint8_t *src, int src_stride, const uint8_t *dst,
564 int dst_stride, int bsw, int bsh, int qm,
565 int use_activity_masking, int qindex) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800566 int i, j;
567 int64_t d;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800568 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
569 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
570
571 assert(qm == OD_HVS_QM);
572
573 for (j = 0; j < bsh; j++)
574 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
575
576 for (j = 0; j < bsh; j++)
577 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
578
579 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
580 qindex);
581 return d;
582}
Fergus Simpson4063a682017-02-28 16:52:22 -0800583#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800584
Yaowu Xuf883b422016-08-30 14:01:10 -0700585static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse9f217762017-04-20 15:34:54 -0700586 const uint8_t *src, int src_stride,
587 const uint8_t *dst, int dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700588 double *hordist, double *verdist) {
Alex Converse9f217762017-04-20 15:34:54 -0700589 const int bw = block_size_wide[bsize];
590 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700591 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 -0700592
593 const int f_index = bsize - BLOCK_16X16;
594 if (f_index < 0) {
Alex Converse9f217762017-04-20 15:34:54 -0700595 const int w_shift = bw == 8 ? 1 : 2;
596 const int h_shift = bh == 8 ? 1 : 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200597#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700598 if (cpi->common.use_highbitdepth) {
Alex Converse9f217762017-04-20 15:34:54 -0700599 const uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
600 const uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
601 for (int i = 0; i < bh; ++i)
602 for (int j = 0; j < bw; ++j) {
603 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700604 esq[index] +=
605 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
606 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
607 }
608 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200609#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700610
Alex Converse9f217762017-04-20 15:34:54 -0700611 for (int i = 0; i < bh; ++i)
612 for (int j = 0; j < bw; ++j) {
613 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700614 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
615 (src[j + i * src_stride] - dst[j + i * dst_stride]);
616 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200617#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200619#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700620 } else {
Alex Converse9f217762017-04-20 15:34:54 -0700621 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
622 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
623 &esq[1]);
624 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
625 &esq[2]);
626 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
627 dst_stride, &esq[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628 src += bh / 4 * src_stride;
629 dst += bh / 4 * dst_stride;
630
Alex Converse9f217762017-04-20 15:34:54 -0700631 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
632 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
633 &esq[5]);
634 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
635 &esq[6]);
636 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
637 dst_stride, &esq[7]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 src += bh / 4 * src_stride;
639 dst += bh / 4 * dst_stride;
640
Alex Converse9f217762017-04-20 15:34:54 -0700641 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
642 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
643 &esq[9]);
644 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
645 &esq[10]);
646 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
647 dst_stride, &esq[11]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648 src += bh / 4 * src_stride;
649 dst += bh / 4 * dst_stride;
650
Alex Converse9f217762017-04-20 15:34:54 -0700651 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
652 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
653 &esq[13]);
654 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
655 &esq[14]);
656 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
657 dst_stride, &esq[15]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700658 }
659
Alex Converse9f217762017-04-20 15:34:54 -0700660 double total = (double)esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] +
661 esq[6] + esq[7] + esq[8] + esq[9] + esq[10] + esq[11] +
662 esq[12] + esq[13] + esq[14] + esq[15];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663 if (total > 0) {
664 const double e_recip = 1.0 / total;
Alex Converse9f217762017-04-20 15:34:54 -0700665 hordist[0] = ((double)esq[0] + esq[4] + esq[8] + esq[12]) * e_recip;
666 hordist[1] = ((double)esq[1] + esq[5] + esq[9] + esq[13]) * e_recip;
667 hordist[2] = ((double)esq[2] + esq[6] + esq[10] + esq[14]) * e_recip;
668 verdist[0] = ((double)esq[0] + esq[1] + esq[2] + esq[3]) * e_recip;
669 verdist[1] = ((double)esq[4] + esq[5] + esq[6] + esq[7]) * e_recip;
670 verdist[2] = ((double)esq[8] + esq[9] + esq[10] + esq[11]) * e_recip;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700671 } else {
672 hordist[0] = verdist[0] = 0.25;
673 hordist[1] = verdist[1] = 0.25;
674 hordist[2] = verdist[2] = 0.25;
675 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676}
677
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700678static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize,
679 const uint8_t *src, int src_stride,
680 const uint8_t *dst, int dst_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700681 int prune_bitmask = 0;
682 double svm_proj_h = 0, svm_proj_v = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700683 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
685 hdist, vdist);
686
687 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
688 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
689 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
690 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
691 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
692 prune_bitmask |= 1 << FLIPADST_1D;
693 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
694 prune_bitmask |= 1 << ADST_1D;
695
696 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
697 prune_bitmask |= 1 << (FLIPADST_1D + 8);
698 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
699 prune_bitmask |= 1 << (ADST_1D + 8);
700
701 return prune_bitmask;
702}
703
704#if CONFIG_EXT_TX
Alex Converse89912f92017-04-21 13:28:50 -0700705static void get_horver_correlation(const int16_t *diff, int stride, int w,
706 int h, double *hcorr, double *vcorr) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707 // Returns hor/ver correlation coefficient
708 const int num = (h - 1) * (w - 1);
709 double num_r;
710 int i, j;
711 int64_t xy_sum = 0, xz_sum = 0;
712 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
713 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
714 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
715 *hcorr = *vcorr = 1;
716
717 assert(num > 0);
718 num_r = 1.0 / num;
719 for (i = 1; i < h; ++i) {
720 for (j = 1; j < w; ++j) {
721 const int16_t x = diff[i * stride + j];
722 const int16_t y = diff[i * stride + j - 1];
723 const int16_t z = diff[(i - 1) * stride + j];
724 xy_sum += x * y;
725 xz_sum += x * z;
726 x_sum += x;
727 y_sum += y;
728 z_sum += z;
729 x2_sum += x * x;
730 y2_sum += y * y;
731 z2_sum += z * z;
732 }
733 }
734 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
735 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
736 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
737 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
738 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
739 if (x_var_n > 0 && y_var_n > 0) {
740 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
741 *hcorr = *hcorr < 0 ? 0 : *hcorr;
742 }
743 if (x_var_n > 0 && z_var_n > 0) {
744 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
745 *vcorr = *vcorr < 0 ? 0 : *vcorr;
746 }
747}
748
Alex Converse89912f92017-04-21 13:28:50 -0700749int dct_vs_idtx(const int16_t *diff, int stride, int w, int h) {
750 double hcorr, vcorr;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700751 int prune_bitmask = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700752 get_horver_correlation(diff, stride, w, h, &hcorr, &vcorr);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753
Alex Converse89912f92017-04-21 13:28:50 -0700754 if (vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700755 prune_bitmask |= 1 << IDTX_1D;
Alex Converse89912f92017-04-21 13:28:50 -0700756 else if (vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700757 prune_bitmask |= 1 << DCT_1D;
758
Alex Converse89912f92017-04-21 13:28:50 -0700759 if (hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700760 prune_bitmask |= 1 << (IDTX_1D + 8);
Alex Converse89912f92017-04-21 13:28:50 -0700761 else if (hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 prune_bitmask |= 1 << (DCT_1D + 8);
763 return prune_bitmask;
764}
765
766// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -0700767static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700768 MACROBLOCK *x, const MACROBLOCKD *xd,
769 int adst_flipadst, int dct_idtx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 int prune = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700771
Alex Converse89912f92017-04-21 13:28:50 -0700772 if (adst_flipadst) {
773 const struct macroblock_plane *const p = &x->plane[0];
774 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
Alex Converse89912f92017-04-21 13:28:50 -0700776 pd->dst.buf, pd->dst.stride);
777 }
778 if (dct_idtx) {
779 av1_subtract_plane(x, bsize, 0);
780 const struct macroblock_plane *const p = &x->plane[0];
781 const int bw = 4 << (b_width_log2_lookup[bsize]);
782 const int bh = 4 << (b_height_log2_lookup[bsize]);
783 prune |= dct_vs_idtx(p->src_diff, bw, bw, bh);
784 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700785
786 return prune;
787}
788#endif // CONFIG_EXT_TX
789
790// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -0700791static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -0700792 const MACROBLOCK *x, const MACROBLOCKD *xd) {
793 const struct macroblock_plane *const p = &x->plane[0];
794 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700795 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
Alex Converse89912f92017-04-21 13:28:50 -0700796 pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700797}
798
Yaowu Xuf883b422016-08-30 14:01:10 -0700799static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700800 const MACROBLOCKD *const xd, int tx_set) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700801#if CONFIG_EXT_TX
Yaowu Xu37fe5fb2017-05-09 11:43:45 -0700802 const int *tx_set_1D = tx_set >= 0 ? ext_tx_used_inter_1D[tx_set] : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700803#else
804 const int tx_set_1D[TX_TYPES_1D] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -0800805#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700806
807 switch (cpi->sf.tx_type_search.prune_mode) {
808 case NO_PRUNE: return 0; break;
809 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -0700810 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811 return 0;
812 return prune_one_for_sby(cpi, bsize, x, xd);
813 break;
814#if CONFIG_EXT_TX
815 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -0700816 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700817 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
818 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
819 }
Sarah Parker68a26b62016-10-28 13:19:33 -0700820 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -0700821 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
822 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
823 break;
Fergus Simpson4063a682017-02-28 16:52:22 -0800824#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700825 }
826 assert(0);
827 return 0;
828}
829
830static int do_tx_type_search(TX_TYPE tx_type, int prune) {
831// TODO(sarahparker) implement for non ext tx
832#if CONFIG_EXT_TX
833 return !(((prune >> vtx_tab[tx_type]) & 1) |
834 ((prune >> (htx_tab[tx_type] + 8)) & 1));
835#else
836 // temporary to avoid compiler warnings
837 (void)vtx_tab;
838 (void)htx_tab;
839 (void)tx_type;
840 (void)prune;
841 return 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800842#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843}
844
Yaowu Xuf883b422016-08-30 14:01:10 -0700845static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700846 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
847 int plane, int64_t sse, int *rate,
848 int64_t *dist) {
849 const struct macroblockd_plane *const pd = &xd->plane[plane];
850 const int dequant_shift =
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200851#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700852 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200853#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854 3;
855
856 // Fast approximate the modelling function.
857 if (cpi->sf.simple_model_rd_from_var) {
858 const int64_t square_error = sse;
859 int quantizer = (pd->dequant[1] >> dequant_shift);
860
861 if (quantizer < 120)
862 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -0700863 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700864 else
865 *rate = 0;
866 *dist = (square_error * quantizer) >> 8;
867 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700868 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
869 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700870 }
871
872 *dist <<= 4;
873}
874
Yaowu Xuf883b422016-08-30 14:01:10 -0700875static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700876 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
877 int plane_to, int *out_rate_sum,
878 int64_t *out_dist_sum, int *skip_txfm_sb,
879 int64_t *skip_sse_sb) {
880 // Note our transform coeffs are 8 times an orthogonal transform.
881 // Hence quantizer step is also 8 times. To get effective quantizer
882 // we need to divide by 8 before sending to modeling function.
883 int plane;
884 const int ref = xd->mi[0]->mbmi.ref_frame[0];
885
886 int64_t rate_sum = 0;
887 int64_t dist_sum = 0;
888 int64_t total_sse = 0;
889
890 x->pred_sse[ref] = 0;
891
892 for (plane = plane_from; plane <= plane_to; ++plane) {
893 struct macroblock_plane *const p = &x->plane[plane];
894 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han31b6a4f2017-02-23 11:05:53 -0800895#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -0800896 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
897#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700898 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Fergus Simpson4063a682017-02-28 16:52:22 -0800899#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900
901 unsigned int sse;
902 int rate;
903 int64_t dist;
904
Jingning Han9ce464c2017-02-20 15:36:30 -0800905#if CONFIG_CB4X4
906 if (x->skip_chroma_rd && plane) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -0800907#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -0800908
Yaowu Xuc27fc142016-08-22 16:08:15 -0700909 // TODO(geza): Write direct sse functions that do not compute
910 // variance as well.
911 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
912 &sse);
913
914 if (plane == 0) x->pred_sse[ref] = sse;
915
916 total_sse += sse;
917
918 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
919
920 rate_sum += rate;
921 dist_sum += dist;
922 }
923
924 *skip_txfm_sb = total_sse == 0;
925 *skip_sse_sb = total_sse << 4;
926 *out_rate_sum = (int)rate_sum;
927 *out_dist_sum = dist_sum;
928}
929
Yaowu Xuf883b422016-08-30 14:01:10 -0700930int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
931 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700932 int i;
933 int64_t error = 0, sqcoeff = 0;
934
935 for (i = 0; i < block_size; i++) {
936 const int diff = coeff[i] - dqcoeff[i];
937 error += diff * diff;
938 sqcoeff += coeff[i] * coeff[i];
939 }
940
941 *ssz = sqcoeff;
942 return error;
943}
944
Yaowu Xuf883b422016-08-30 14:01:10 -0700945int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
946 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947 int i;
948 int64_t error = 0;
949
950 for (i = 0; i < block_size; i++) {
951 const int diff = coeff[i] - dqcoeff[i];
952 error += diff * diff;
953 }
954
955 return error;
956}
957
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200958#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -0700959int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
960 const tran_low_t *dqcoeff, intptr_t block_size,
961 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962 int i;
963 int64_t error = 0, sqcoeff = 0;
964 int shift = 2 * (bd - 8);
965 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
966
967 for (i = 0; i < block_size; i++) {
968 const int64_t diff = coeff[i] - dqcoeff[i];
969 error += diff * diff;
970 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
971 }
972 assert(error >= 0 && sqcoeff >= 0);
973 error = (error + rounding) >> shift;
974 sqcoeff = (sqcoeff + rounding) >> shift;
975
976 *ssz = sqcoeff;
977 return error;
978}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200979#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980
Thomas Daede6ff6af62017-02-03 16:29:24 -0800981#if CONFIG_PVQ
982// Without PVQ, av1_block_error_c() return two kind of errors,
983// 1) reconstruction (i.e. decoded) error and
984// 2) Squared sum of transformed residue (i.e. 'coeff')
985// However, if PVQ is enabled, coeff does not keep the transformed residue
986// but instead a transformed original is kept.
987// Hence, new parameter ref vector (i.e. transformed predicted signal)
988// is required to derive the residue signal,
989// i.e. coeff - ref = residue (all transformed).
990
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200991#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800992static int64_t av1_highbd_block_error2_c(const tran_low_t *coeff,
993 const tran_low_t *dqcoeff,
994 const tran_low_t *ref,
995 intptr_t block_size, int64_t *ssz,
996 int bd) {
997 int64_t error;
998 int64_t sqcoeff;
999 int shift = 2 * (bd - 8);
1000 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1001 // Use the existing sse codes for calculating distortion of decoded signal:
1002 // i.e. (orig - decoded)^2
1003 // For high bit depth, throw away ssz until a 32-bit version of
1004 // av1_block_error_fp is written.
1005 int64_t ssz_trash;
1006 error = av1_block_error(coeff, dqcoeff, block_size, &ssz_trash);
1007 // prediction residue^2 = (orig - ref)^2
1008 sqcoeff = av1_block_error(coeff, ref, block_size, &ssz_trash);
1009 error = (error + rounding) >> shift;
1010 sqcoeff = (sqcoeff + rounding) >> shift;
1011 *ssz = sqcoeff;
1012 return error;
1013}
1014#else
1015// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1016// a separate function that does not do the extra computations for ssz.
1017static int64_t av1_block_error2_c(const tran_low_t *coeff,
1018 const tran_low_t *dqcoeff,
1019 const tran_low_t *ref, intptr_t block_size,
1020 int64_t *ssz) {
1021 int64_t error;
1022 // Use the existing sse codes for calculating distortion of decoded signal:
1023 // i.e. (orig - decoded)^2
1024 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1025 // prediction residue^2 = (orig - ref)^2
1026 *ssz = av1_block_error_fp(coeff, ref, block_size);
1027 return error;
1028}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001029#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001030#endif // CONFIG_PVQ
1031
Jingning Hanab77e732017-02-28 15:20:59 -08001032#if !CONFIG_PVQ || CONFIG_VAR_TX
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001033/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001034 * decide whether to include cost of a trailing EOB node or not (i.e. we
1035 * can skip this if the last coefficient in this transform block, e.g. the
1036 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1037 * were non-zero). */
Angie Chiang47e4b362017-03-24 11:25:10 -07001038#if !CONFIG_LV_MAP
1039static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1040 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1041 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1042 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043 MACROBLOCKD *const xd = &x->e_mbd;
1044 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1045 const struct macroblock_plane *p = &x->plane[plane];
1046 const struct macroblockd_plane *pd = &xd->plane[plane];
1047 const PLANE_TYPE type = pd->plane_type;
1048 const uint16_t *band_count = &band_count_table[tx_size][1];
1049 const int eob = p->eobs[block];
1050 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1051 const int tx_size_ctx = txsize_sqr_map[tx_size];
1052 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1053 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1054 uint8_t token_cache[MAX_TX_SQUARE];
Angie Chiang77368af2017-03-23 16:22:07 -07001055 int pt = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 int c, cost;
Angie Chiang77368af2017-03-23 16:22:07 -07001057 const int16_t *scan = scan_order->scan;
1058 const int16_t *nb = scan_order->neighbors;
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001059 const int ref = is_inter_block(mbmi);
1060 aom_prob *blockz_probs =
1061 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
Thomas Davies10525752017-03-06 12:10:46 +00001062
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001063#if CONFIG_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001064 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001065#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001066 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001067#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001068
1069#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1070 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001071 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001073 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001074
1075 if (eob == 0) {
1076 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001077 cost = av1_cost_bit(blockz_probs[pt], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001078 } else {
1079 if (use_fast_coef_costing) {
1080 int band_left = *band_count++;
1081
1082 // dc token
1083 int v = qcoeff[0];
1084 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001085 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001086 cost += (*token_costs)[!prev_t][pt][prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087
Yaowu Xuf883b422016-08-30 14:01:10 -07001088 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001089 ++token_costs;
1090
1091 // ac tokens
1092 for (c = 1; c < eob; c++) {
1093 const int rc = scan[c];
1094 int16_t t;
1095
1096 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001097 cost += av1_get_token_cost(v, &t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001098 cost += (*token_costs)[!t][!prev_t][t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001099 prev_t = t;
1100 if (!--band_left) {
1101 band_left = *band_count++;
1102 ++token_costs;
1103 }
1104 }
1105
1106 // eob token
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001107 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108
1109 } else { // !use_fast_coef_costing
1110 int band_left = *band_count++;
1111
1112 // dc token
1113 int v = qcoeff[0];
1114 int16_t tok;
Alex Converseda3d94f2017-03-15 14:54:29 -07001115 cost = av1_get_token_cost(v, &tok, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001116 cost += (*token_costs)[!tok][pt][tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001117
Yaowu Xuf883b422016-08-30 14:01:10 -07001118 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119 ++token_costs;
1120
Yaowu Xuc27fc142016-08-22 16:08:15 -07001121 // ac tokens
1122 for (c = 1; c < eob; c++) {
1123 const int rc = scan[c];
1124
1125 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001126 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001127 pt = get_coef_context(nb, token_cache, c);
Thomas Davies10525752017-03-06 12:10:46 +00001128 cost += (*token_costs)[!tok][pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -07001129 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130 if (!--band_left) {
1131 band_left = *band_count++;
1132 ++token_costs;
1133 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001134 }
1135
1136 // eob token
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001137 pt = get_coef_context(nb, token_cache, c);
1138 cost += (*token_costs)[0][pt][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001139 }
1140 }
1141
Yaowu Xuc27fc142016-08-22 16:08:15 -07001142 return cost;
1143}
Angie Chiang47e4b362017-03-24 11:25:10 -07001144#endif // !CONFIG_LV_MAP
1145
Angie Chiang05917872017-04-15 12:28:56 -07001146int av1_cost_coeffs(const AV1_COMP *const cpi, MACROBLOCK *x, int plane,
Angie Chiang47e4b362017-03-24 11:25:10 -07001147 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1148 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1149 int use_fast_coef_costing) {
1150#if !CONFIG_LV_MAP
Angie Chiang05917872017-04-15 12:28:56 -07001151 const AV1_COMMON *const cm = &cpi->common;
Angie Chiang47e4b362017-03-24 11:25:10 -07001152 return cost_coeffs(cm, x, plane, block, tx_size, scan_order, a, l,
1153 use_fast_coef_costing);
1154#else // !CONFIG_LV_MAP
1155 (void)scan_order;
1156 (void)use_fast_coef_costing;
1157 const MACROBLOCKD *xd = &x->e_mbd;
1158 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1159 const struct macroblockd_plane *pd = &xd->plane[plane];
1160 const BLOCK_SIZE bsize = mbmi->sb_type;
1161#if CONFIG_CB4X4
1162#if CONFIG_CHROMA_2X2
1163 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
1164#else
1165 const BLOCK_SIZE plane_bsize =
1166 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
1167#endif // CONFIG_CHROMA_2X2
1168#else // CONFIG_CB4X4
1169 const BLOCK_SIZE plane_bsize =
1170 get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
1171#endif // CONFIG_CB4X4
1172
1173 TXB_CTX txb_ctx;
1174 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
Angie Chiang05917872017-04-15 12:28:56 -07001175 return av1_cost_coeffs_txb(cpi, x, plane, block, &txb_ctx);
Angie Chiang47e4b362017-03-24 11:25:10 -07001176#endif // !CONFIG_LV_MAP
1177}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001178#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001179
Alex Converse61f37b82017-03-29 15:26:03 -07001180// Get transform block visible dimensions cropped to the MI units.
1181static void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
1182 BLOCK_SIZE plane_bsize, int blk_row, int blk_col,
1183 BLOCK_SIZE tx_bsize, int *width, int *height,
1184 int *visible_width, int *visible_height) {
Yue Chen56e226e2017-05-02 16:21:40 -07001185#if !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
Alex Converse61f37b82017-03-29 15:26:03 -07001186 assert(tx_bsize <= plane_bsize);
Yue Chen56e226e2017-05-02 16:21:40 -07001187#endif // !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
Alex Converse61f37b82017-03-29 15:26:03 -07001188 int txb_height = block_size_high[tx_bsize];
1189 int txb_width = block_size_wide[tx_bsize];
1190 const int block_height = block_size_high[plane_bsize];
1191 const int block_width = block_size_wide[plane_bsize];
1192 const struct macroblockd_plane *const pd = &xd->plane[plane];
1193 // TODO(aconverse@google.com): Investigate using crop_width/height here rather
1194 // than the MI size
1195 const int block_rows =
1196 (xd->mb_to_bottom_edge >= 0)
1197 ? block_height
1198 : (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
1199 const int block_cols =
1200 (xd->mb_to_right_edge >= 0)
1201 ? block_width
1202 : (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) + block_width;
1203 const int tx_unit_size = tx_size_wide_log2[0];
1204 if (width) *width = txb_width;
1205 if (height) *height = txb_height;
1206 *visible_width = clamp(block_cols - (blk_col << tx_unit_size), 0, txb_width);
1207 *visible_height =
1208 clamp(block_rows - (blk_row << tx_unit_size), 0, txb_height);
1209}
1210
1211// Compute the pixel domain sum square error on all visible 4x4s in the
1212// transform block.
1213static unsigned pixel_sse(const AV1_COMP *const cpi, const MACROBLOCKD *xd,
1214 int plane, const uint8_t *src, const int src_stride,
1215 const uint8_t *dst, const int dst_stride, int blk_row,
1216 int blk_col, const BLOCK_SIZE plane_bsize,
1217 const BLOCK_SIZE tx_bsize) {
1218 int txb_rows, txb_cols, visible_rows, visible_cols;
1219 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize,
1220 &txb_cols, &txb_rows, &visible_cols, &visible_rows);
1221 assert(visible_rows > 0);
1222 assert(visible_cols > 0);
Yue Chen56e226e2017-05-02 16:21:40 -07001223#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
1224 if ((txb_rows == visible_rows && txb_cols == visible_cols) &&
1225 tx_bsize < BLOCK_SIZES) {
1226#else
Alex Converse61f37b82017-03-29 15:26:03 -07001227 if (txb_rows == visible_rows && txb_cols == visible_cols) {
Yue Chen56e226e2017-05-02 16:21:40 -07001228#endif
Alex Converse61f37b82017-03-29 15:26:03 -07001229 unsigned sse;
1230 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse);
1231 return sse;
1232 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001233#if CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001234 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1235 uint64_t sse = aom_highbd_sse_odd_size(src, src_stride, dst, dst_stride,
1236 visible_cols, visible_rows);
1237 return (unsigned int)ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
1238 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001239#endif // CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001240 unsigned sse = aom_sse_odd_size(src, src_stride, dst, dst_stride,
1241 visible_cols, visible_rows);
1242 return sse;
1243}
1244
1245// Compute the squares sum squares on all visible 4x4s in the transform block.
1246static int64_t sum_squares_visible(const MACROBLOCKD *xd, int plane,
1247 const int16_t *diff, const int diff_stride,
1248 int blk_row, int blk_col,
1249 const BLOCK_SIZE plane_bsize,
1250 const BLOCK_SIZE tx_bsize) {
1251 int visible_rows, visible_cols;
1252 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize, NULL,
1253 NULL, &visible_cols, &visible_rows);
1254 return aom_sum_squares_2d_i16(diff, diff_stride, visible_cols, visible_rows);
1255}
1256
Angie Chiang808d8592017-04-06 18:36:55 -07001257void av1_dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
1258 BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col,
1259 TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse,
1260 OUTPUT_STATUS output_status) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001261 MACROBLOCKD *const xd = &x->e_mbd;
1262 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001263#if CONFIG_DAALA_DIST
1264 int qm = OD_HVS_QM;
1265 int use_activity_masking = 0;
1266#if CONFIG_PVQ
1267 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001268#endif // CONFIG_PVQ
Yushin Cho4483e3d2017-04-18 19:41:20 -07001269 struct macroblockd_plane *const pd = &xd->plane[plane];
1270#else // CONFIG_DAALA_DIST
1271 const struct macroblockd_plane *const pd = &xd->plane[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001272#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001273
1274 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
hui sud2f12ba2017-04-12 10:08:43 -07001275 // Transform domain distortion computation is more efficient as it does
Yaowu Xuc27fc142016-08-22 16:08:15 -07001276 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001277 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001278 int64_t this_sse;
Jingning Hanff705452017-04-27 11:32:15 -07001279 int shift = (MAX_TX_SCALE - av1_get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001280 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1281 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001282#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001283 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001284
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001285#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001286 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001287 *out_dist = av1_highbd_block_error2_c(coeff, dqcoeff, ref_coeff,
1288 buffer_length, &this_sse, bd) >>
1289 shift;
1290#else
1291 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1292 &this_sse) >>
1293 shift;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001294#endif // CONFIG_HIGHBITDEPTH
Yi Luod61e6082017-05-26 16:14:39 -07001295#else // !CONFIG_PVQ
1296#if CONFIG_HIGHBITDEPTH
1297 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1298 *out_dist = av1_highbd_block_error(coeff, dqcoeff, buffer_length,
1299 &this_sse, xd->bd) >>
1300 shift;
1301 else
1302#endif
1303 *out_dist =
1304 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001305#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 *out_sse = this_sse >> shift;
1307 } else {
1308 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Angie Chiang50910f62017-04-03 12:31:34 -07001309#if !CONFIG_PVQ || CONFIG_DAALA_DIST
Jingning Hanb9c57272016-10-25 10:15:39 -07001310 const int bsw = block_size_wide[tx_bsize];
1311 const int bsh = block_size_high[tx_bsize];
Angie Chiang50910f62017-04-03 12:31:34 -07001312#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313 const int src_stride = x->plane[plane].src.stride;
1314 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001315 // Scale the transform block index to pixel unit.
1316 const int src_idx = (blk_row * src_stride + blk_col)
1317 << tx_size_wide_log2[0];
1318 const int dst_idx = (blk_row * dst_stride + blk_col)
1319 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1321 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1322 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1323 const uint16_t eob = p->eobs[block];
1324
Yaowu Xuc27fc142016-08-22 16:08:15 -07001325 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001326 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001327
Yushin Cho7a428ba2017-01-12 16:28:49 -08001328#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001329 if (plane == 0 && bsw >= 8 && bsh >= 8) {
1330 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
1331 const int pred_stride = block_size_wide[plane_bsize];
1332 const int pred_idx = (blk_row * pred_stride + blk_col)
1333 << tx_size_wide_log2[0];
1334 const int16_t *pred = &pd->pred[pred_idx];
1335 int i, j;
1336 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001337
Yushin Cho4483e3d2017-04-18 19:41:20 -07001338 for (j = 0; j < bsh; j++)
1339 for (i = 0; i < bsw; i++)
1340 pred8[j * bsw + i] = pred[j * pred_stride + i];
Alex Conversef323f012017-04-24 09:26:33 -07001341 *out_sse = av1_daala_dist(src, src_stride, pred8, bsw, bsw, bsh, qm,
1342 use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001343 } else {
Alex Conversef323f012017-04-24 09:26:33 -07001344 *out_sse = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1345 qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001346 }
Yushin Cho7a428ba2017-01-12 16:28:49 -08001347 } else
Fergus Simpson4063a682017-02-28 16:52:22 -08001348#endif // CONFIG_DAALA_DIST
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001349 {
1350 const int diff_stride = block_size_wide[plane_bsize];
1351 const int diff_idx = (blk_row * diff_stride + blk_col)
1352 << tx_size_wide_log2[0];
1353 const int16_t *diff = &p->src_diff[diff_idx];
Alex Conversef323f012017-04-24 09:26:33 -07001354 *out_sse = sum_squares_visible(xd, plane, diff, diff_stride, blk_row,
1355 blk_col, plane_bsize, tx_bsize);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001356#if CONFIG_HIGHBITDEPTH
hui sub1cc1f92017-04-11 17:41:29 -07001357 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Alex Conversef323f012017-04-24 09:26:33 -07001358 *out_sse = ROUND_POWER_OF_TWO(*out_sse, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001359#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001360 }
Alex Conversef323f012017-04-24 09:26:33 -07001361 *out_sse *= 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001362
1363 if (eob) {
Angie Chiang228cc182017-04-07 15:22:16 -07001364 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001365#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001366 if (plane == 0 && bsw >= 8 && bsh >= 8)
Alex Conversef323f012017-04-24 09:26:33 -07001367 *out_dist = av1_daala_dist(src, src_stride, dst, dst_stride, bsw, bsh,
1368 qm, use_activity_masking, x->qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001369 else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001370#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001371 *out_dist =
1372 pixel_sse(cpi, xd, plane, src, src_stride, dst, dst_stride,
1373 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001374 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001375#if CONFIG_HIGHBITDEPTH
Jingning Han6a9dbef2017-04-10 10:25:14 -07001376 uint8_t *recon;
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001377 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
Jingning Han6a9dbef2017-04-10 10:25:14 -07001378
1379 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1380 recon = CONVERT_TO_BYTEPTR(recon16);
1381 else
1382 recon = (uint8_t *)recon16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001384 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001385#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001386
Angie Chiang50910f62017-04-03 12:31:34 -07001387#if !CONFIG_PVQ
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001388#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001389 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1390 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
1391 NULL, 0, bsw, bsh, xd->bd);
1392 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001393#endif // CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001394 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL,
1395 0, bsw, bsh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001396#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001397 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001398#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001399#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001400 (void)dst;
Angie Chiang50910f62017-04-03 12:31:34 -07001401#endif // !CONFIG_PVQ
Angie Chiang41fffae2017-04-03 10:33:18 -07001402
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001403 const PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001404 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang41fffae2017-04-03 10:33:18 -07001405
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001406 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, recon,
1407 MAX_TX_SIZE, eob);
Angie Chiang41fffae2017-04-03 10:33:18 -07001408
Yushin Cho7a428ba2017-01-12 16:28:49 -08001409#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001410 if (plane == 0 && bsw >= 8 && bsh >= 8) {
Alex Conversef323f012017-04-24 09:26:33 -07001411 *out_dist = av1_daala_dist(src, src_stride, recon, MAX_TX_SIZE, bsw,
1412 bsh, qm, use_activity_masking, x->qindex);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001413 } else {
Yushin Cho4483e3d2017-04-18 19:41:20 -07001414 if (plane == 0) {
1415 // Save decoded pixels for inter block in pd->pred to avoid
1416 // block_8x8_rd_txfm_daala_dist() need to produce them
1417 // by calling av1_inverse_transform_block() again.
1418 const int pred_stride = block_size_wide[plane_bsize];
1419 const int pred_idx = (blk_row * pred_stride + blk_col)
1420 << tx_size_wide_log2[0];
1421 int16_t *pred = &pd->pred[pred_idx];
1422 int i, j;
1423
1424 for (j = 0; j < bsh; j++)
1425 for (i = 0; i < bsw; i++)
1426 pred[j * pred_stride + i] = recon[j * MAX_TX_SIZE + i];
1427 }
Fergus Simpson4063a682017-02-28 16:52:22 -08001428#endif // CONFIG_DAALA_DIST
Alex Conversef323f012017-04-24 09:26:33 -07001429 *out_dist =
1430 pixel_sse(cpi, xd, plane, src, src_stride, recon, MAX_TX_SIZE,
1431 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001432#if CONFIG_DAALA_DIST
1433 }
1434#endif // CONFIG_DAALA_DIST
1435 }
Alex Conversef323f012017-04-24 09:26:33 -07001436 *out_dist *= 16;
1437 } else {
1438 *out_dist = *out_sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001439 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001440 }
1441}
1442
Yaowu Xuc27fc142016-08-22 16:08:15 -07001443static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1444 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1445 struct rdcost_block_args *args = arg;
1446 MACROBLOCK *const x = args->x;
1447 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001448 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiange50f3ec2017-04-10 15:50:33 -07001449 const AV1_COMP *cpi = args->cpi;
Angie Chiang65a39bb2017-04-11 16:50:04 -07001450 ENTROPY_CONTEXT *a = args->t_above + blk_col;
1451 ENTROPY_CONTEXT *l = args->t_left + blk_row;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001452#if !CONFIG_TXK_SEL
Angie Chiang18ad8942017-04-11 12:37:07 -07001453 const AV1_COMMON *cm = &cpi->common;
1454#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455 int64_t rd1, rd2, rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001456 RD_STATS this_rd_stats;
Yushin Cho6341f5c2017-03-24 14:36:28 -07001457
Angie Chiangbc2288c2017-04-09 15:41:17 -07001458 assert(tx_size == get_tx_size(plane, xd));
1459
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001460 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461
1462 if (args->exit_early) return;
1463
1464 if (!is_inter_block(mbmi)) {
Luc Trudeauf5334002017-04-25 12:21:26 -04001465#if CONFIG_CFL
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001466
1467#if CONFIG_EC_ADAPT
1468 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
1469#else
1470 FRAME_CONTEXT *const ec_ctx = cm->fc;
1471#endif // CONFIG_EC_ADAPT
1472
1473 av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
1474 blk_row, tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04001475#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001476 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001477#endif
hui sub8a6fd62017-05-10 10:57:57 -07001478#if CONFIG_DPCM_INTRA
1479 const int block_raster_idx =
1480 av1_block_index_to_raster_order(tx_size, block);
1481 const PREDICTION_MODE mode =
1482 (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
1483 TX_TYPE tx_type = get_tx_type((plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV,
1484 xd, block, tx_size);
1485 if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
1486 int8_t skip;
1487 av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
1488 plane_bsize, tx_size, tx_type, a, l, &skip);
1489 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1490 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1491 OUTPUT_HAS_DECODED_PIXELS);
1492 goto CALCULATE_RD;
1493 }
1494#endif // CONFIG_DPCM_INTRA
Angie Chiang62e54cd2017-04-06 10:45:56 -07001495 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
1496 }
1497
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001498#if !CONFIG_TXK_SEL
Angie Chiang62e54cd2017-04-06 10:45:56 -07001499 // full forward transform and quantization
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001500 const int coeff_ctx = combine_entropy_contexts(*a, *l);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001501 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1502 coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07001503 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Angie Chiang62e54cd2017-04-06 10:45:56 -07001504
1505 if (!is_inter_block(mbmi)) {
1506 struct macroblock_plane *const p = &x->plane[plane];
Angie Chiangbc2288c2017-04-09 15:41:17 -07001507 av1_inverse_transform_block_facade(xd, plane, block, blk_row, blk_col,
1508 p->eobs[block]);
Angie Chiang808d8592017-04-06 18:36:55 -07001509 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1510 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1511 OUTPUT_HAS_DECODED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001512 } else {
Angie Chiang808d8592017-04-06 18:36:55 -07001513 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1514 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1515 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001516 }
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001517#if CONFIG_CFL
1518 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1519 struct macroblockd_plane *const pd = &xd->plane[plane];
1520 const int dst_stride = pd->dst.stride;
1521 uint8_t *dst =
1522 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1523 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
1524 }
1525#endif
hui sub8a6fd62017-05-10 10:57:57 -07001526#if CONFIG_DPCM_INTRA
1527CALCULATE_RD : {}
1528#endif // CONFIG_DPCM_INTRA
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001529 rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001530 if (args->this_rd + rd > args->best_rd) {
1531 args->exit_early = 1;
1532 return;
1533 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001534#if !CONFIG_PVQ
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001535 const PLANE_TYPE plane_type = get_plane_type(plane);
1536 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang18ad8942017-04-11 12:37:07 -07001537 const SCAN_ORDER *scan_order =
1538 get_scan(cm, tx_size, tx_type, is_inter_block(mbmi));
Angie Chiang05917872017-04-15 12:28:56 -07001539 this_rd_stats.rate =
1540 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l,
1541 args->use_fast_coef_costing);
Angie Chiang65a39bb2017-04-11 16:50:04 -07001542#else // !CONFIG_PVQ
1543 this_rd_stats.rate = x->rate;
1544#endif // !CONFIG_PVQ
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001545#else // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001546 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
1547 tx_size, a, l, args->use_fast_coef_costing,
1548 &this_rd_stats);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001549#endif // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001550
1551#if !CONFIG_PVQ
Angie Chiang3963d632016-11-10 18:41:40 -08001552#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001553 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1554 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001555#endif // CONFIG_RD_DEBUG
Yushin Cho6341f5c2017-03-24 14:36:28 -07001556 av1_set_txb_context(x, plane, block, tx_size, a, l);
Fergus Simpson4063a682017-02-28 16:52:22 -08001557#endif // !CONFIG_PVQ
Angie Chiangb3a12b52017-03-23 14:53:10 -07001558
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001559 rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
1560 rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001561
1562 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001563 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001564
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001565#if !CONFIG_PVQ
1566 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1567#else
1568 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001569#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001570 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001571
Yaowu Xuc27fc142016-08-22 16:08:15 -07001572 args->this_rd += rd;
1573
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001574#if CONFIG_DAALA_DIST
1575 if (!(plane == 0 && plane_bsize >= BLOCK_8X8 &&
1576 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))) {
1577#endif
1578 if (args->this_rd > args->best_rd) {
1579 args->exit_early = 1;
1580 return;
1581 }
1582#if CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07001583 }
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001584#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001585}
1586
Yushin Cho7a428ba2017-01-12 16:28:49 -08001587#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001588static void daala_dist_sub8x8_txfm_rd(MACROBLOCK *x, BLOCK_SIZE bsize,
1589 struct rdcost_block_args *args) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08001590 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001591 const struct macroblockd_plane *const pd = &xd->plane[0];
1592 const struct macroblock_plane *const p = &x->plane[0];
Yushin Cho4483e3d2017-04-18 19:41:20 -07001593 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001594#if CONFIG_PVQ
1595 use_activity_masking = x->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08001596#endif // CONFIG_PVQ
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001597 const int src_stride = p->src.stride;
1598 const int dst_stride = pd->dst.stride;
1599 const int pred_stride = block_size_wide[bsize];
1600 const uint8_t *src = &p->src.buf[0];
1601 const uint8_t *dst = &pd->dst.buf[0];
1602 const int16_t *pred = &pd->pred[0];
1603 const int bw = block_size_wide[bsize];
1604 const int bh = block_size_high[bsize];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001605
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001606 int i, j;
1607 int64_t rd, rd1, rd2;
1608 int qm = OD_HVS_QM;
1609 int use_activity_masking = 0;
1610 unsigned int tmp1, tmp2;
1611 int qindex = x->qindex;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001612
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001613 assert((bw & 0x07) == 0);
1614 assert((bh & 0x07) == 0);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001615
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001616 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_SB_SQUARE]);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001617
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001618 for (j = 0; j < bh; j++)
1619 for (i = 0; i < bw; i++) pred8[j * bh + i] = pred[j * pred_stride + i];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001620
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001621 tmp1 = av1_daala_dist(src, src_stride, pred8, bw, bw, bh, qm,
1622 use_activity_masking, qindex);
1623 tmp2 = av1_daala_dist(src, src_stride, dst, dst_stride, bw, bh, qm,
1624 use_activity_masking, qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001625
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001626 if (!is_inter_block(mbmi)) {
1627 args->rd_stats.sse = (int64_t)tmp1 * 16;
1628 args->rd_stats.dist = (int64_t)tmp2 * 16;
1629 } else {
1630 // For inter mode, the decoded pixels are provided in pd->pred,
1631 // while the predicted pixels are in dst.
1632 args->rd_stats.sse = (int64_t)tmp2 * 16;
1633 args->rd_stats.dist = (int64_t)tmp1 * 16;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001634 }
1635
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001636 rd1 = RDCOST(x->rdmult, x->rddiv, args->rd_stats.rate, args->rd_stats.dist);
1637 rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->rd_stats.sse);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001638 rd = AOMMIN(rd1, rd2);
1639
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001640 args->rd_stats.rdcost = rd;
1641 args->this_rd = rd;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001642}
Fergus Simpson4063a682017-02-28 16:52:22 -08001643#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001644
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001645static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1646 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1647 BLOCK_SIZE bsize, TX_SIZE tx_size,
1648 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001649 MACROBLOCKD *const xd = &x->e_mbd;
1650 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001651 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001652 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001653 args.x = x;
1654 args.cpi = cpi;
1655 args.best_rd = ref_best_rd;
1656 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001657 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001658
1659 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1660
Yaowu Xuf883b422016-08-30 14:01:10 -07001661 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001662
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001663 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1664 &args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001665#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001666 if (!args.exit_early && plane == 0 && bsize >= BLOCK_8X8 &&
Yushin Cho7a428ba2017-01-12 16:28:49 -08001667 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001668 daala_dist_sub8x8_txfm_rd(x, bsize, &args);
1669#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -08001670
Yaowu Xuc27fc142016-08-22 16:08:15 -07001671 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001672 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001673 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001674 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001675 }
1676}
1677
1678#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001679void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1680 int64_t *distortion, int *skippable,
1681 int64_t *sse, int64_t ref_best_rd, int plane,
1682 BLOCK_SIZE bsize, TX_SIZE tx_size,
1683 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001684 MACROBLOCKD *const xd = &x->e_mbd;
1685 const struct macroblockd_plane *const pd = &xd->plane[plane];
1686 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001687 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001688 args.cpi = cpi;
1689 args.x = x;
1690 args.best_rd = ref_best_rd;
1691 args.use_fast_coef_costing = use_fast_coef_casting;
1692
1693#if CONFIG_EXT_TX
1694 assert(tx_size < TX_SIZES);
1695#endif // CONFIG_EXT_TX
1696
1697 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1698
Yaowu Xuf883b422016-08-30 14:01:10 -07001699 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001700
Yaowu Xuc27fc142016-08-22 16:08:15 -07001701 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
1702 &args);
1703
1704 if (args.exit_early) {
1705 *rate = INT_MAX;
1706 *distortion = INT64_MAX;
1707 *sse = INT64_MAX;
1708 *skippable = 0;
1709 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001710 *distortion = args.rd_stats.dist;
1711 *rate = args.rd_stats.rate;
1712 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001713 *skippable = !x->plane[plane].eobs[0];
1714 }
1715}
1716#endif // CONFIG_SUPERTX
1717
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001718static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Urvang Joshifeb925f2016-12-05 10:37:29 -08001719 BLOCK_SIZE bsize, TX_SIZE tx_size) {
1720 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001721 const MACROBLOCKD *const xd = &x->e_mbd;
1722 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001723
1724 const int tx_select =
1725 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
1726
1727 if (tx_select) {
1728 const int is_inter = is_inter_block(mbmi);
1729 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
1730 : intra_tx_size_cat_lookup[bsize];
1731 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
1732 const int depth = tx_size_to_depth(coded_tx_size);
1733 const int tx_size_ctx = get_tx_size_context(xd);
Yue Chen56e226e2017-05-02 16:21:40 -07001734 int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
1735#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
1736 if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size)
1737 r_tx_size += av1_cost_bit(cm->fc->quarter_tx_size_prob,
1738 tx_size == quarter_txsize_lookup[bsize]);
1739#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
Urvang Joshifeb925f2016-12-05 10:37:29 -08001740 return r_tx_size;
1741 } else {
1742 return 0;
1743 }
1744}
1745
Angie Chiang65201562017-04-10 15:23:28 -07001746// #TODO(angiebird): use this function whenever it's possible
Angie Chiang05917872017-04-15 12:28:56 -07001747int av1_tx_type_cost(const AV1_COMP *cpi, const MACROBLOCKD *xd,
1748 BLOCK_SIZE bsize, int plane, TX_SIZE tx_size,
1749 TX_TYPE tx_type) {
1750 if (plane > 0) return 0;
1751
Angie Chiang65201562017-04-10 15:23:28 -07001752 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1753 const int is_inter = is_inter_block(mbmi);
1754#if CONFIG_EXT_TX
1755 const AV1_COMMON *cm = &cpi->common;
1756 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
1757 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
1758 const int ext_tx_set =
1759 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
1760 if (is_inter) {
1761 if (ext_tx_set > 0)
1762 return cpi
1763 ->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]][tx_type];
1764 } else {
1765 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
1766 return cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]]
1767 [mbmi->mode][tx_type];
1768 }
1769 }
1770#else
1771 (void)bsize;
1772 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1773 !FIXED_TX_TYPE) {
1774 if (is_inter) {
1775 return cpi->inter_tx_type_costs[tx_size][tx_type];
1776 } else {
1777 return cpi->intra_tx_type_costs[tx_size]
1778 [intra_mode_to_tx_type_context[mbmi->mode]]
1779 [tx_type];
1780 }
1781 }
1782#endif // CONFIG_EXT_TX
1783 return 0;
1784}
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001785static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
1786 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
1787 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07001788 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001789 MACROBLOCKD *const xd = &x->e_mbd;
1790 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1791 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001792 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001793 int s0, s1;
1794 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001795 const int tx_select =
1796 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08001797
1798 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001799
1800 assert(skip_prob > 0);
1801#if CONFIG_EXT_TX && CONFIG_RECT_TX
1802 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
1803#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
1804
Yaowu Xuf883b422016-08-30 14:01:10 -07001805 s0 = av1_cost_bit(skip_prob, 0);
1806 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001807
1808 mbmi->tx_type = tx_type;
1809 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001810 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001811 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001812 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001813#if !CONFIG_TXK_SEL
Angie Chiang05917872017-04-15 12:28:56 -07001814 int plane = 0;
1815 rd_stats->rate += av1_tx_type_cost(cpi, xd, bs, plane, tx_size, tx_type);
1816#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001817
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001818 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001819 if (is_inter) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001820 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001821 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001822 rd = RDCOST(x->rdmult, x->rddiv, s1 + r_tx_size * tx_select,
1823 rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001824 }
1825 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001826 rd = RDCOST(x->rdmult, x->rddiv,
1827 rd_stats->rate + s0 + r_tx_size * tx_select, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 }
1829
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001830 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001831
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001832 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
1833 !(rd_stats->skip))
1834 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835
1836 return rd;
1837}
1838
Angie Chiang2d147c12017-04-05 11:23:59 -07001839static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
1840 TX_TYPE tx_type, TX_SIZE tx_size) {
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001841 const MACROBLOCKD *const xd = &x->e_mbd;
1842 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiang2d147c12017-04-05 11:23:59 -07001843 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
1844 const int is_inter = is_inter_block(mbmi);
1845 int prune = 0;
1846 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1847 // passing -1 in for tx_type indicates that all 1D
1848 // transforms should be considered for pruning
1849 prune = prune_tx_types(cpi, bs, x, xd, -1);
1850
Angie Chianga4fa1902017-04-05 15:26:09 -07001851 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
Angie Chiang2d147c12017-04-05 11:23:59 -07001852 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
1853 return 1;
1854 if (!is_inter && x->use_default_intra_tx_type &&
1855 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1856 return 1;
1857 if (is_inter && x->use_default_inter_tx_type &&
1858 tx_type != get_default_tx_type(0, xd, 0, tx_size))
1859 return 1;
1860 if (max_tx_size >= TX_32X32 && tx_size == TX_4X4) return 1;
1861#if CONFIG_EXT_TX
1862 const AV1_COMMON *const cm = &cpi->common;
1863 int ext_tx_set =
1864 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
1865 if (is_inter) {
1866 if (!ext_tx_used_inter[ext_tx_set][tx_type]) return 1;
1867 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1868 if (!do_tx_type_search(tx_type, prune)) return 1;
1869 }
1870 } else {
1871 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1872 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) return 1;
1873 }
1874 if (!ext_tx_used_intra[ext_tx_set][tx_type]) return 1;
1875 }
1876#else // CONFIG_EXT_TX
1877 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) return 1;
1878 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
1879 !do_tx_type_search(tx_type, prune))
1880 return 1;
1881#endif // CONFIG_EXT_TX
1882 return 0;
1883}
1884
Yue Chen5e606542017-05-24 17:03:17 -07001885#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Urvang Joshi52648442016-10-13 17:27:51 -07001886static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
1887 MACROBLOCK *x, int *r, int64_t *d, int *s,
1888 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001889 RD_STATS rd_stats;
1890 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
1891 max_txsize_lookup[bs]);
1892 *r = rd_stats.rate;
1893 *d = rd_stats.dist;
1894 *s = rd_stats.skip;
1895 *sse = rd_stats.sse;
1896 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001897}
Yue Chen5e606542017-05-24 17:03:17 -07001898#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899
Urvang Joshi52648442016-10-13 17:27:51 -07001900static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001901 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07001902 BLOCK_SIZE bs) {
1903 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001904 MACROBLOCKD *const xd = &x->e_mbd;
1905 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1906 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001907 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07001908 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
1909 int s0 = av1_cost_bit(skip_prob, 0);
1910 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001911 const int is_inter = is_inter_block(mbmi);
1912 int prune = 0;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07001913 const int plane = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914#if CONFIG_EXT_TX
1915 int ext_tx_set;
1916#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001917 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001918
1919 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07001920#if CONFIG_VAR_TX
1921 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08001922#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001923#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001924 ext_tx_set =
1925 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001926#endif // CONFIG_EXT_TX
1927
1928 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
1929#if CONFIG_EXT_TX
1930 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
1931#else
1932 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08001933#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001934#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08001935 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
1936 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001938#if CONFIG_PVQ
1939 od_rollback_buffer pre_buf, post_buf;
1940
1941 od_encode_checkpoint(&x->daala_enc, &pre_buf);
1942 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08001943#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07001944
1945 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001946 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001947 if (is_inter) {
1948 if (x->use_default_inter_tx_type &&
1949 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1950 continue;
1951 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
1952 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
1953 if (!do_tx_type_search(tx_type, prune)) continue;
1954 }
1955 } else {
1956 if (x->use_default_intra_tx_type &&
1957 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
1958 continue;
1959 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
1960 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
1961 }
1962 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
1963 }
1964
1965 mbmi->tx_type = tx_type;
1966
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001967 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001968 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001969#if CONFIG_PVQ
1970 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08001971#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001972 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07001973 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001974
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001975 if (this_rd_stats.skip)
1976 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001978 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
1979 this_rd_stats.dist);
1980 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
1981 !this_rd_stats.skip)
1982 this_rd =
1983 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001984
1985 if (this_rd < best_rd) {
1986 best_rd = this_rd;
1987 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001988 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001989#if CONFIG_PVQ
1990 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08001991#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001992 }
1993 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001994#if CONFIG_PVQ
1995 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08001996#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07001997 } else {
1998 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001999 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2000 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002#else // CONFIG_EXT_TX
2003 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2004 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002005 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006 if (!is_inter && x->use_default_intra_tx_type &&
2007 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2008 continue;
2009 if (is_inter && x->use_default_inter_tx_type &&
2010 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2011 continue;
2012 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002013 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002014 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002015 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002016
2017 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002018 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002019 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2020 !do_tx_type_search(tx_type, prune))
2021 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002022 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002023 if (this_rd_stats.skip)
2024 this_rd = RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002026 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + s0,
2027 this_rd_stats.dist);
2028 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2029 this_rd =
2030 AOMMIN(this_rd, RDCOST(x->rdmult, x->rddiv, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031
2032 if (this_rd < best_rd) {
2033 best_rd = this_rd;
2034 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002035 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002036 }
2037 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002038 } else {
2039 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002040 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2041 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002042 }
2043#endif // CONFIG_EXT_TX
2044 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002045}
2046
Urvang Joshi52648442016-10-13 17:27:51 -07002047static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002048 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002049 BLOCK_SIZE bs) {
2050 MACROBLOCKD *const xd = &x->e_mbd;
2051 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2052
2053 mbmi->tx_size = TX_4X4;
2054 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002055#if CONFIG_VAR_TX
2056 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002057#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002058
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002059 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2060 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061}
2062
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002063#if CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002064static INLINE int bsize_to_num_blk(BLOCK_SIZE bsize) {
2065 int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
2066 return num_blk;
2067}
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002068#endif // CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002069
Urvang Joshi52648442016-10-13 17:27:51 -07002070static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002071 MACROBLOCK *x, RD_STATS *rd_stats,
2072 int64_t ref_best_rd, BLOCK_SIZE bs) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002073 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002074 MACROBLOCKD *const xd = &x->e_mbd;
2075 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002076 int64_t rd = INT64_MAX;
Angie Chianga4fa1902017-04-05 15:26:09 -07002077 int n;
2078 int start_tx, end_tx;
2079 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
2080 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2081 TX_SIZE best_tx_size = max_tx_size;
2082 TX_TYPE best_tx_type = DCT_DCT;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002083#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002084 TX_TYPE best_txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
2085 const int num_blk = bsize_to_num_blk(bs);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002086#endif // CONFIG_TXK_SEL
Angie Chianga4fa1902017-04-05 15:26:09 -07002087 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
2088 const int is_inter = is_inter_block(mbmi);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002089#if CONFIG_PVQ
2090 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002091 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002092#endif // CONFIG_PVQ
Angie Chianga4fa1902017-04-05 15:26:09 -07002093
2094 av1_invalid_rd_stats(rd_stats);
2095
2096#if CONFIG_EXT_TX && CONFIG_RECT_TX
2097 int evaluate_rect_tx = 0;
2098 if (tx_select) {
2099 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
2100 } else {
2101 const TX_SIZE chosen_tx_size =
2102 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2103 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
2104 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
2105 }
2106 if (evaluate_rect_tx) {
Angie Chiangf1cb0752017-04-10 16:01:20 -07002107 TX_TYPE tx_start = DCT_DCT;
2108 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002109#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002110 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2111 // performed in av1_search_txk_type()
2112 tx_end = DCT_DCT + 1;
2113#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002114 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002115 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002116 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Angie Chianga4fa1902017-04-05 15:26:09 -07002117 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
2118 RD_STATS this_rd_stats;
2119 int ext_tx_set =
2120 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
2121 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2122 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2123 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
2124 rect_tx_size);
2125 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002126#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002127 memcpy(best_txk_type, mbmi->txk_type,
2128 sizeof(best_txk_type[0]) * num_blk);
2129#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002130 best_tx_type = tx_type;
2131 best_tx_size = rect_tx_size;
2132 best_rd = rd;
2133 *rd_stats = this_rd_stats;
2134 }
2135 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002136#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002137 const int is_inter = is_inter_block(mbmi);
2138 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002139#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002140 }
2141 }
Yue Chen56e226e2017-05-02 16:21:40 -07002142
2143#if CONFIG_RECT_TX_EXT
2144 // test 1:4/4:1 tx
2145 int evaluate_quarter_tx = 0;
2146 if (is_quarter_tx_allowed(xd, mbmi, is_inter)) {
2147 if (tx_select) {
2148 evaluate_quarter_tx = 1;
2149 } else {
2150 const TX_SIZE chosen_tx_size =
2151 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2152 evaluate_quarter_tx = chosen_tx_size == quarter_txsize_lookup[bs];
2153 }
2154 }
2155 if (evaluate_quarter_tx) {
2156 TX_TYPE tx_start = DCT_DCT;
2157 TX_TYPE tx_end = TX_TYPES;
2158#if CONFIG_TXK_SEL
2159 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2160 // performed in av1_search_txk_type()
2161 tx_end = DCT_DCT + 1;
2162#endif
2163 TX_TYPE tx_type;
2164 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
2165 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
2166 const TX_SIZE tx_size = quarter_txsize_lookup[bs];
2167 RD_STATS this_rd_stats;
2168 int ext_tx_set =
2169 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
2170 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2171 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2172 rd =
2173 txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, tx_size);
2174 if (rd < best_rd) {
2175#if CONFIG_TXK_SEL
2176 memcpy(best_txk_type, mbmi->txk_type,
2177 sizeof(best_txk_type[0]) * num_blk);
2178#endif
2179 best_tx_type = tx_type;
2180 best_tx_size = tx_size;
2181 best_rd = rd;
2182 *rd_stats = this_rd_stats;
2183 }
2184 }
2185#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2186 const int is_inter = is_inter_block(mbmi);
2187 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2188#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2189 }
2190 }
2191#endif // CONFIG_RECT_TX_EXT
Angie Chianga4fa1902017-04-05 15:26:09 -07002192#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2193
2194 if (tx_select) {
2195 start_tx = max_tx_size;
2196 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
2197 } else {
2198 const TX_SIZE chosen_tx_size =
2199 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2200 start_tx = chosen_tx_size;
2201 end_tx = chosen_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002202 }
2203
Angie Chianga4fa1902017-04-05 15:26:09 -07002204 last_rd = INT64_MAX;
2205 for (n = start_tx; n >= end_tx; --n) {
Sarah Parker36661922017-04-13 14:26:49 -07002206#if CONFIG_EXT_TX && CONFIG_RECT_TX
2207 if (is_rect_tx(n)) break;
2208#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002209 TX_TYPE tx_start = DCT_DCT;
2210 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002211#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002212 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2213 // performed in av1_search_txk_type()
2214 tx_end = DCT_DCT + 1;
2215#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002216 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002217 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002218 RD_STATS this_rd_stats;
2219 if (skip_txfm_search(cpi, x, bs, tx_type, n)) continue;
2220 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
2221#if CONFIG_PVQ
2222 od_encode_rollback(&x->daala_enc, &buf);
2223#endif // CONFIG_PVQ
2224 // Early termination in transform size search.
2225 if (cpi->sf.tx_size_search_breakout &&
2226 (rd == INT64_MAX ||
2227 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
2228 (n < (int)max_tx_size && rd > last_rd)))
2229 break;
2230
2231 last_rd = rd;
2232 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002233#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002234 memcpy(best_txk_type, mbmi->txk_type,
2235 sizeof(best_txk_type[0]) * num_blk);
2236#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002237 best_tx_type = tx_type;
2238 best_tx_size = n;
2239 best_rd = rd;
2240 *rd_stats = this_rd_stats;
2241 }
2242#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2243 const int is_inter = is_inter_block(mbmi);
2244 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2245#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2246 }
2247 }
2248 mbmi->tx_size = best_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002249 mbmi->tx_type = best_tx_type;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002250#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002251 memcpy(mbmi->txk_type, best_txk_type, sizeof(best_txk_type[0]) * num_blk);
2252#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253
Jingning Hane67b38a2016-11-04 10:30:00 -07002254#if CONFIG_VAR_TX
2255 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002256#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002257
Yaowu Xuc27fc142016-08-22 16:08:15 -07002258#if !CONFIG_EXT_TX
2259 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002260#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002261#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002262 if (best_rd != INT64_MAX) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002263 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx_size);
Yushin Cho05f540a2016-11-08 22:12:51 -08002264 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002265#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002266}
2267
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002268static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2269 RD_STATS *rd_stats, BLOCK_SIZE bs,
2270 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002271 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002272 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002273
2274 assert(bs == xd->mi[0]->mbmi.sb_type);
2275
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002276 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002277 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002278 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002279 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002280 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002281 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002282 }
2283}
2284
2285static int conditional_skipintra(PREDICTION_MODE mode,
2286 PREDICTION_MODE best_intra_mode) {
2287 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2288 best_intra_mode != D135_PRED)
2289 return 1;
2290 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2291 best_intra_mode != D45_PRED)
2292 return 1;
2293 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2294 best_intra_mode != D45_PRED)
2295 return 1;
2296 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2297 best_intra_mode != D135_PRED)
2298 return 1;
2299 return 0;
2300}
2301
hui su308a6392017-01-12 14:49:57 -08002302// Model based RD estimation for luma intra blocks.
2303static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002304 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002305 MACROBLOCKD *const xd = &x->e_mbd;
2306 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002307 assert(!is_inter_block(mbmi));
hui su308a6392017-01-12 14:49:57 -08002308 RD_STATS this_rd_stats;
2309 int row, col;
2310 int64_t temp_sse, this_rd;
2311 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2312 const int stepr = tx_size_high_unit[tx_size];
2313 const int stepc = tx_size_wide_unit[tx_size];
2314 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2315 const int max_blocks_high = max_block_high(xd, bsize, 0);
2316 mbmi->tx_size = tx_size;
2317 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002318 const int step = stepr * stepc;
2319 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002320 for (row = 0; row < max_blocks_high; row += stepr) {
2321 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002322#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09002323 const struct macroblockd_plane *const pd = &xd->plane[0];
2324 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002325
2326#if CONFIG_EC_ADAPT
2327 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
2328#else
Luc Trudeau64ed2ce2017-05-12 12:01:24 -04002329 FRAME_CONTEXT *const ec_ctx = cpi->common.fc;
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002330#endif // CONFIG_EC_ADAPT
2331
2332 av1_predict_intra_block_encoder_facade(x, ec_ctx, 0, block, col, row,
2333 tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04002334#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002335 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002336#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002337 block += step;
hui su308a6392017-01-12 14:49:57 -08002338 }
2339 }
2340 // RD estimation.
2341 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2342 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002343#if CONFIG_EXT_INTRA
2344 if (av1_is_directional_mode(mbmi->mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002345 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2346 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002347 }
2348#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002349#if CONFIG_FILTER_INTRA
2350 if (mbmi->mode == DC_PRED) {
2351 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2352 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2353 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2354 mode_cost += (av1_cost_bit(prob, 1) +
2355 write_uniform_cost(FILTER_INTRA_MODES, mode));
2356 } else {
2357 mode_cost += av1_cost_bit(prob, 0);
2358 }
2359 }
2360#endif // CONFIG_FILTER_INTRA
hui su9a416f52017-01-13 11:37:53 -08002361 this_rd = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate + mode_cost,
2362 this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002363 return this_rd;
2364}
2365
Urvang Joshib100db72016-10-12 16:28:56 -07002366#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002367// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2368// new_height'. Extra rows and columns are filled in by copying last valid
2369// row/column.
2370static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2371 int orig_height, int new_width,
2372 int new_height) {
2373 int j;
2374 assert(new_width >= orig_width);
2375 assert(new_height >= orig_height);
2376 if (new_width == orig_width && new_height == orig_height) return;
2377
2378 for (j = orig_height - 1; j >= 0; --j) {
2379 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2380 // Copy last column to extra columns.
2381 memset(color_map + j * new_width + orig_width,
2382 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2383 }
2384 // Copy last row to extra rows.
2385 for (j = orig_height; j < new_height; ++j) {
2386 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2387 new_width);
2388 }
2389}
2390
hui su33567b22017-04-30 16:40:19 -07002391#if CONFIG_PALETTE_DELTA_ENCODING
2392// Bias toward using colors in the cache.
2393// TODO(huisu): Try other schemes to improve compression.
2394static void optimize_palette_colors(uint16_t *color_cache, int n_cache,
2395 int n_colors, int stride,
2396 float *centroids) {
2397 if (n_cache <= 0) return;
2398 for (int i = 0; i < n_colors * stride; i += stride) {
2399 float min_diff = fabsf(centroids[i] - color_cache[0]);
2400 int idx = 0;
2401 for (int j = 1; j < n_cache; ++j) {
2402 float this_diff = fabsf(centroids[i] - color_cache[j]);
2403 if (this_diff < min_diff) {
2404 min_diff = this_diff;
2405 idx = j;
2406 }
2407 }
2408 if (min_diff < 1.5) centroids[i] = color_cache[idx];
2409 }
2410}
2411#endif // CONFIG_PALETTE_DELTA_ENCODING
2412
hui sude0c70a2017-01-09 17:12:17 -08002413static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2414 BLOCK_SIZE bsize, int palette_ctx,
2415 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2416 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002417 int64_t *best_rd, int64_t *best_model_rd,
2418 int *rate, int *rate_tokenonly,
2419 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002420 int rate_overhead = 0;
2421 MACROBLOCKD *const xd = &x->e_mbd;
2422 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002423 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002424 assert(!is_inter_block(mbmi));
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002425 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002426 const int src_stride = x->plane[0].src.stride;
2427 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002428 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002429 int block_width, block_height, rows, cols;
2430 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2431 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002432
2433 assert(cpi->common.allow_screen_content_tools);
2434
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002435#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002436 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002437 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2438 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002439 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002440#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002441 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002442#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002443 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002444#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002445
2446 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002447 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002449 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450 float *const data = x->palette_buffer->kmeans_data_buf;
2451 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002452 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002453 RD_STATS tokenonly_rd_stats;
2454 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002455 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002456#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2458 if (cpi->common.use_highbitdepth)
2459 lb = ub = src16[0];
2460 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002461#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002462 lb = ub = src[0];
2463
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002464#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002465 if (cpi->common.use_highbitdepth) {
2466 for (r = 0; r < rows; ++r) {
2467 for (c = 0; c < cols; ++c) {
2468 val = src16[r * src_stride + c];
2469 data[r * cols + c] = val;
2470 if (val < lb)
2471 lb = val;
2472 else if (val > ub)
2473 ub = val;
2474 }
2475 }
2476 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002477#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002478 for (r = 0; r < rows; ++r) {
2479 for (c = 0; c < cols; ++c) {
2480 val = src[r * src_stride + c];
2481 data[r * cols + c] = val;
2482 if (val < lb)
2483 lb = val;
2484 else if (val > ub)
2485 ub = val;
2486 }
2487 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002488#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002489 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002490#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491
2492 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002493#if CONFIG_FILTER_INTRA
2494 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2495#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002496
2497 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2498
hui su33567b22017-04-30 16:40:19 -07002499#if CONFIG_PALETTE_DELTA_ENCODING
2500 const MODE_INFO *above_mi = xd->above_mi;
2501 const MODE_INFO *left_mi = xd->left_mi;
2502 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
2503 const int n_cache =
2504 av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
2505#endif // CONFIG_PALETTE_DELTA_ENCODING
2506
Yaowu Xuc27fc142016-08-22 16:08:15 -07002507 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2508 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002509 if (colors == PALETTE_MIN_SIZE) {
2510 // Special case: These colors automatically become the centroids.
2511 assert(colors == n);
2512 assert(colors == 2);
2513 centroids[0] = lb;
2514 centroids[1] = ub;
2515 k = 2;
2516 } else {
2517 for (i = 0; i < n; ++i) {
2518 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2519 }
2520 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
hui su33567b22017-04-30 16:40:19 -07002521#if CONFIG_PALETTE_DELTA_ENCODING
2522 optimize_palette_colors(color_cache, n_cache, n, 1, centroids);
2523#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi773e3542017-05-05 18:09:42 -07002524 k = av1_remove_duplicates(centroids, n);
2525 if (k < PALETTE_MIN_SIZE) {
2526 // Too few unique colors to create a palette. And DC_PRED will work
2527 // well for that case anyway. So skip.
2528 continue;
2529 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002530 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002531
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002532#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002533 if (cpi->common.use_highbitdepth)
2534 for (i = 0; i < k; ++i)
2535 pmi->palette_colors[i] =
2536 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2537 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002538#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002539 for (i = 0; i < k; ++i)
2540 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2541 pmi->palette_size[0] = k;
2542
Yaowu Xuf883b422016-08-30 14:01:10 -07002543 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002544 extend_palette_color_map(color_map, cols, rows, block_width,
2545 block_height);
hui su78c611a2017-01-13 17:06:04 -08002546 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002547 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002548 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002549 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002550 av1_cost_bit(
2551 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002552 1);
hui su33567b22017-04-30 16:40:19 -07002553 palette_mode_cost += av1_palette_color_cost_y(pmi,
2554#if CONFIG_PALETTE_DELTA_ENCODING
2555 color_cache, n_cache,
2556#endif // CONFIG_PALETTE_DELTA_ENCODING
2557 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558 for (i = 0; i < rows; ++i) {
2559 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002560 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002561 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002562 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002563 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002564 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2565 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002566 }
2567 }
hui su78c611a2017-01-13 17:06:04 -08002568 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2569 if (*best_model_rd != INT64_MAX &&
2570 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2571 continue;
2572 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2573 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2574 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2575 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002576 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002577 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002578 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002579 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580 if (this_rd < *best_rd) {
2581 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002582 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002583 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002584 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002585 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002586 if (rate) *rate = this_rate;
2587 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2588 if (distortion) *distortion = tokenonly_rd_stats.dist;
2589 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590 }
2591 }
2592 }
hui sude0c70a2017-01-09 17:12:17 -08002593
2594 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2595 memcpy(color_map, best_palette_color_map,
2596 rows * cols * sizeof(best_palette_color_map[0]));
2597 }
2598 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 return rate_overhead;
2600}
Urvang Joshib100db72016-10-12 16:28:56 -07002601#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002602
Urvang Joshifeb925f2016-12-05 10:37:29 -08002603static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002604 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2605 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2606 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002607 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002608 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002609 PREDICTION_MODE mode;
2610 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi330aec82017-05-08 15:37:42 -07002611 assert(!is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002612 int64_t best_rd = rd_thresh;
2613 struct macroblock_plane *p = &x->plane[0];
2614 struct macroblockd_plane *pd = &xd->plane[0];
2615 const int src_stride = p->src.stride;
2616 const int dst_stride = pd->dst.stride;
2617 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002618 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002619#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08002620 // TODO(jingning): This is a temporal change. The whole function should be
2621 // out when cb4x4 is enabled.
2622 ENTROPY_CONTEXT ta[4], tempa[4];
2623 ENTROPY_CONTEXT tl[4], templ[4];
2624#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002625 ENTROPY_CONTEXT ta[2], tempa[2];
2626 ENTROPY_CONTEXT tl[2], templ[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002627#endif // CONFIG_CHROMA_2X2
Urvang Joshifeb925f2016-12-05 10:37:29 -08002628
2629 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2630 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2631 const int tx_width_unit = tx_size_wide_unit[tx_size];
2632 const int tx_height_unit = tx_size_high_unit[tx_size];
2633 const int pred_block_width = block_size_wide[bsize];
2634 const int pred_block_height = block_size_high[bsize];
2635 const int tx_width = tx_size_wide[tx_size];
2636 const int tx_height = tx_size_high[tx_size];
2637 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2638 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002639 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002640 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002641 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002642#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002643 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002644#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002645 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2646#if CONFIG_EXT_TX && CONFIG_RECT_TX
2647 const int sub_bsize = bsize;
2648#else
2649 const int sub_bsize = BLOCK_4X4;
2650#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002651
Yushin Cho77bba8d2016-11-04 16:36:56 -07002652#if CONFIG_PVQ
2653 od_rollback_buffer pre_buf, post_buf;
2654 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2655 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002656#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002657
Urvang Joshifeb925f2016-12-05 10:37:29 -08002658 assert(bsize < BLOCK_8X8);
2659 assert(tx_width < 8 || tx_height < 8);
2660#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002661 if (is_lossless)
2662 assert(tx_width == 4 && tx_height == 4);
2663 else
2664 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002665#else
2666 assert(tx_width == 4 && tx_height == 4);
2667#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2668
2669 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2670 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2671
2672 xd->mi[0]->mbmi.tx_size = tx_size;
2673
Urvang Joshib100db72016-10-12 16:28:56 -07002674#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002675 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002676#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002677
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002678#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002680#if CONFIG_PVQ
2681 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2682#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002683 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2684 int64_t this_rd;
2685 int ratey = 0;
2686 int64_t distortion = 0;
2687 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002688 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002689
Urvang Joshifeb925f2016-12-05 10:37:29 -08002690 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2691 (1 << mode)))
2692 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002693
2694 // Only do the oblique modes if the best so far is
2695 // one of the neighboring directional modes
2696 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2697 if (conditional_skipintra(mode, *best_mode)) continue;
2698 }
2699
Urvang Joshifeb925f2016-12-05 10:37:29 -08002700 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2701 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002702
Urvang Joshifeb925f2016-12-05 10:37:29 -08002703 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
2704 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
2705 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2706 const int block =
2707 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002708 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2709 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08002710#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002711 int16_t *const src_diff = av1_raster_block_offset_int16(
2712 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002713#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002714 int skip;
2715 assert(block < 4);
2716 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2717 idx == 0 && idy == 0));
2718 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2719 block == 0 || block == 2));
2720 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002721 av1_predict_intra_block(
2722 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
2723 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002724#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002725 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
2726 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002727#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002728 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07002729 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002730 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002731 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002732 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002733#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002734 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002735 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07002736 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002737 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002738 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002739 skip = (p->eobs[block] == 0);
2740 can_skip &= skip;
2741 tempa[idx] = !skip;
2742 templ[idy] = !skip;
2743#if CONFIG_EXT_TX
2744 if (tx_size == TX_8X4) {
2745 tempa[idx + 1] = tempa[idx];
2746 } else if (tx_size == TX_4X8) {
2747 templ[idy + 1] = templ[idy];
2748 }
2749#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002750#else
2751 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002752
Thomas Daede6ff6af62017-02-03 16:29:24 -08002753 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2754 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
2755
2756 ratey += x->rate;
2757 skip = x->pvq_skip[0];
2758 tempa[idx] = !skip;
2759 templ[idy] = !skip;
2760 can_skip &= skip;
2761#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2763 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08002764#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002765 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002766#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002767 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2768 DCT_DCT, tx_size, dst, dst_stride,
2769 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002770 } else {
2771 int64_t dist;
2772 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07002773 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002774 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002775 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08002776 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08002777#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07002778 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002779 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07002780 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
2781 templ + idy);
Angie Chiang05917872017-04-15 12:28:56 -07002782 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07002783 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07002784 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002785 skip = (p->eobs[block] == 0);
2786 can_skip &= skip;
2787 tempa[idx] = !skip;
2788 templ[idy] = !skip;
2789#if CONFIG_EXT_TX
2790 if (tx_size == TX_8X4) {
2791 tempa[idx + 1] = tempa[idx];
2792 } else if (tx_size == TX_4X8) {
2793 templ[idy + 1] = templ[idy];
2794 }
2795#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08002796#else
2797 (void)scan_order;
2798
2799 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
2800 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2801 ratey += x->rate;
2802 skip = x->pvq_skip[0];
2803 tempa[idx] = !skip;
2804 templ[idy] = !skip;
2805 can_skip &= skip;
2806#endif
2807#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002808 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08002809#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07002810 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2811 tx_type, tx_size, dst, dst_stride,
2812 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002813 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002814 dist = (int64_t)tmp << 4;
2815 distortion += dist;
2816 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2817 goto next_highbd;
2818 }
2819 }
2820 }
2821
2822 rate += ratey;
2823 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
2824
2825 if (this_rd < best_rd) {
2826 *bestrate = rate;
2827 *bestratey = ratey;
2828 *bestdistortion = distortion;
2829 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002830 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002831 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002832 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
2833 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08002834#if CONFIG_PVQ
2835 od_encode_checkpoint(&x->daala_enc, &post_buf);
2836#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08002837 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002838 memcpy(best_dst16 + idy * 8,
2839 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002840 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002841 }
2842 }
2843 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08002844#if CONFIG_PVQ
2845 od_encode_rollback(&x->daala_enc, &pre_buf);
2846#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847 }
2848
2849 if (best_rd >= rd_thresh) return best_rd;
2850
Thomas Daede6ff6af62017-02-03 16:29:24 -08002851#if CONFIG_PVQ
2852 od_encode_rollback(&x->daala_enc, &post_buf);
2853#endif
2854
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002855 if (y_skip) *y_skip &= best_can_skip;
2856
Urvang Joshifeb925f2016-12-05 10:37:29 -08002857 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002858 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08002859 best_dst16 + idy * 8,
2860 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861 }
2862
2863 return best_rd;
2864 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002865#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002866
Yushin Cho77bba8d2016-11-04 16:36:56 -07002867#if CONFIG_PVQ
2868 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002869#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002870
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2872 int64_t this_rd;
2873 int ratey = 0;
2874 int64_t distortion = 0;
2875 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002876 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877
Urvang Joshifeb925f2016-12-05 10:37:29 -08002878 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
2879 (1 << mode))) {
2880 continue;
2881 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882
2883 // Only do the oblique modes if the best so far is
2884 // one of the neighboring directional modes
2885 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
2886 if (conditional_skipintra(mode, *best_mode)) continue;
2887 }
2888
Urvang Joshifeb925f2016-12-05 10:37:29 -08002889 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
2890 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002891
Urvang Joshifeb925f2016-12-05 10:37:29 -08002892 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
2893 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
2894 const int block_raster_idx = (row + idy) * 2 + (col + idx);
2895 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002896 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
2897 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07002898#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002899 int16_t *const src_diff = av1_raster_block_offset_int16(
2900 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08002901#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002902 int skip;
2903 assert(block < 4);
2904 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2905 idx == 0 && idy == 0));
2906 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
2907 block == 0 || block == 2));
2908 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00002909 av1_predict_intra_block(xd, pd->width, pd->height,
2910 txsize_to_bsize[tx_size], mode, dst, dst_stride,
2911 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08002912#if CONFIG_CB4X4
2913 2 * (col + idx), 2 * (row + idy),
2914#else
2915 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08002916#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08002917 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002918#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08002919 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
2920 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08002921#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002922
Urvang Joshi14731732017-04-27 18:40:49 -07002923 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
2924 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 0);
2925 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08002926#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002927 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08002928#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08002929#if !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002930 const AV1_XFORM_QUANT xform_quant =
2931 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
2932 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08002933#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002934 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08002935#else
Urvang Joshi14731732017-04-27 18:40:49 -07002936 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002937#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002938 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08002939
Angie Chiang3511c372017-05-31 12:47:07 -07002940 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
2941 templ + idy);
Urvang Joshi14731732017-04-27 18:40:49 -07002942
2943 ratey +=
2944 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
2945 templ + idy, cpi->sf.use_fast_coef_costing);
2946 skip = (p->eobs[block] == 0);
2947 can_skip &= skip;
2948 tempa[idx] = !skip;
2949 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002950#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07002951 if (tx_size == TX_8X4) {
2952 tempa[idx + 1] = tempa[idx];
2953 } else if (tx_size == TX_4X8) {
2954 templ[idy + 1] = templ[idy];
2955 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08002956#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002957#else
Urvang Joshi14731732017-04-27 18:40:49 -07002958 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08002959
Urvang Joshi14731732017-04-27 18:40:49 -07002960 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08002961#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002962 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08002963#else
Urvang Joshi14731732017-04-27 18:40:49 -07002964 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08002965#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07002966 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
2967
2968 ratey += x->rate;
2969 skip = x->pvq_skip[0];
2970 tempa[idx] = !skip;
2971 templ[idy] = !skip;
2972 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08002973#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07002974
2975 if (!is_lossless) { // To use the pixel domain distortion, we need to
2976 // calculate inverse txfm *before* calculating RD
2977 // cost. Compared to calculating the distortion in
2978 // the frequency domain, the overhead of encoding
2979 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08002980#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002981 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08002982#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07002983 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
2984 tx_type, tx_size, dst, dst_stride,
2985 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07002986 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002987 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07002988 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002989 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07002990 }
2991
2992 if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
2993 goto next;
2994
2995 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
2996#if CONFIG_PVQ
2997 if (!skip)
2998#endif // CONFIG_PVQ
2999 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3000 DCT_DCT, tx_size, dst, dst_stride,
3001 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003002 }
3003 }
3004 }
3005
3006 rate += ratey;
3007 this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
3008
3009 if (this_rd < best_rd) {
3010 *bestrate = rate;
3011 *bestratey = ratey;
3012 *bestdistortion = distortion;
3013 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003014 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003015 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003016 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3017 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003018#if CONFIG_PVQ
3019 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003020#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003021 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003023 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003024 }
3025 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003026#if CONFIG_PVQ
3027 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003028#endif // CONFIG_PVQ
3029 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003030
3031 if (best_rd >= rd_thresh) return best_rd;
3032
Yushin Cho77bba8d2016-11-04 16:36:56 -07003033#if CONFIG_PVQ
3034 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003035#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003036
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003037 if (y_skip) *y_skip &= best_can_skip;
3038
Urvang Joshifeb925f2016-12-05 10:37:29 -08003039 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003040 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003041 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003042
3043 return best_rd;
3044}
3045
Urvang Joshi52648442016-10-13 17:27:51 -07003046static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3047 MACROBLOCK *mb, int *rate,
3048 int *rate_y, int64_t *distortion,
3049 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003050 const MACROBLOCKD *const xd = &mb->e_mbd;
3051 MODE_INFO *const mic = xd->mi[0];
3052 const MODE_INFO *above_mi = xd->above_mi;
3053 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003054 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003055 assert(!is_inter_block(mbmi));
Urvang Joshifeb925f2016-12-05 10:37:29 -08003056 const BLOCK_SIZE bsize = mbmi->sb_type;
3057 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3058 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059 int idx, idy;
3060 int cost = 0;
3061 int64_t total_distortion = 0;
3062 int tot_rate_y = 0;
3063 int64_t total_rd = 0;
3064 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003065 const int is_lossless = xd->lossless[mbmi->segment_id];
3066#if CONFIG_EXT_TX && CONFIG_RECT_TX
3067 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3068#else
3069 const TX_SIZE tx_size = TX_4X4;
3070#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003071
3072#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003073#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003074 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003075#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003076#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003077#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003078 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003079#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003080
3081 // TODO(any): Add search of the tx_type to improve rd performance at the
3082 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003083 mbmi->tx_type = DCT_DCT;
3084 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003085
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003086 if (y_skip) *y_skip = 1;
3087
Urvang Joshifeb925f2016-12-05 10:37:29 -08003088 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3089 // 8x8 coding block.
3090 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3091 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092 PREDICTION_MODE best_mode = DC_PRED;
3093 int r = INT_MAX, ry = INT_MAX;
3094 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003095 int j;
3096 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003097 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003098 const PREDICTION_MODE A =
3099 av1_above_block_mode(mic, above_mi, pred_block_idx);
3100 const PREDICTION_MODE L =
3101 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003102
3103 bmode_costs = cpi->y_mode_costs[A][L];
3104 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003105 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003106 cpi, mb, idy, idx, &best_mode, bmode_costs,
3107 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003108 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003109#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003110 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003111#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003112 total_rd += this_rd;
3113 cost += r;
3114 total_distortion += d;
3115 tot_rate_y += ry;
3116
Urvang Joshifeb925f2016-12-05 10:37:29 -08003117 mic->bmi[pred_block_idx].as_mode = best_mode;
3118 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3119 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3120 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3121 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003122
3123 if (total_rd >= best_rd) return INT64_MAX;
3124 }
3125 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003126 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003127
Yushin Cho7a428ba2017-01-12 16:28:49 -08003128#if CONFIG_DAALA_DIST
3129 {
3130 const struct macroblock_plane *p = &mb->plane[0];
3131 const struct macroblockd_plane *pd = &xd->plane[0];
3132 const int src_stride = p->src.stride;
3133 const int dst_stride = pd->dst.stride;
3134 uint8_t *src = p->src.buf;
3135 uint8_t *dst = pd->dst.buf;
3136 int use_activity_masking = 0;
3137 int qm = OD_HVS_QM;
3138
3139#if CONFIG_PVQ
3140 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003141#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003142 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho4483e3d2017-04-18 19:41:20 -07003143 total_distortion = av1_daala_dist(src, src_stride, dst, dst_stride, 8, 8,
Yushin Cho7a428ba2017-01-12 16:28:49 -08003144 qm, use_activity_masking, mb->qindex)
3145 << 4;
3146 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003147#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003149 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003150 int rate_tx_type = 0;
3151#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003152 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3153 1) {
3154 const int eset =
3155 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003156 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3157 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003158 }
3159#else
clang-format67948d32016-09-07 22:40:40 -07003160 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003161 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3162 [intra_mode_to_tx_type_context[mbmi->mode]]
3163 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003164#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003165 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 cost += rate_tx_type;
3167 tot_rate_y += rate_tx_type;
3168 }
3169
3170 *rate = cost;
3171 *rate_y = tot_rate_y;
3172 *distortion = total_distortion;
3173
3174 return RDCOST(mb->rdmult, mb->rddiv, cost, total_distortion);
3175}
3176
hui su5db97432016-10-14 16:10:14 -07003177#if CONFIG_FILTER_INTRA
3178// Return 1 if an filter intra mode is selected; return 0 otherwise.
3179static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3180 int *rate, int *rate_tokenonly,
3181 int64_t *distortion, int *skippable,
3182 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003183 int64_t *best_rd, int64_t *best_model_rd,
3184 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003185 MACROBLOCKD *const xd = &x->e_mbd;
3186 MODE_INFO *const mic = xd->mi[0];
3187 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003188 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003189 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003190 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003191 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003192 TX_TYPE best_tx_type;
3193
hui su5db97432016-10-14 16:10:14 -07003194 av1_zero(filter_intra_mode_info);
3195 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003196 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003197#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003198 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003199#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003200
3201 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003202 int this_rate;
3203 int64_t this_rd, this_model_rd;
3204 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003205 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003206 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003207 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3208 if (*best_model_rd != INT64_MAX &&
3209 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3210 continue;
3211 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003212 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3213 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003214 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003215 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003216 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003217 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003218
3219 if (this_rd < *best_rd) {
3220 *best_rd = this_rd;
3221 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003222 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003223 best_tx_type = mic->mbmi.tx_type;
3224 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003225 *rate_tokenonly = tokenonly_rd_stats.rate;
3226 *distortion = tokenonly_rd_stats.dist;
3227 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003228 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003229 }
3230 }
3231
hui su5db97432016-10-14 16:10:14 -07003232 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003233 mbmi->mode = DC_PRED;
3234 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003235 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3236 filter_intra_mode_info.use_filter_intra_mode[0];
3237 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3238 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003239 mbmi->tx_type = best_tx_type;
3240 return 1;
3241 } else {
3242 return 0;
3243 }
3244}
hui su5db97432016-10-14 16:10:14 -07003245#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003246
hui su5db97432016-10-14 16:10:14 -07003247#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003248// Run RD calculation with given luma intra prediction angle., and return
3249// the RD cost. Update the best mode info. if the RD cost is the best so far.
3250static int64_t calc_rd_given_intra_angle(
3251 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3252 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3253 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3254 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003255#if CONFIG_INTRA_INTERP
3256 INTRA_FILTER *best_filter,
3257#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003258 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003259 int this_rate;
3260 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003261 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003262 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003263 assert(!is_inter_block(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003264
hui su45dc5972016-12-08 17:42:50 -08003265 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003266 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3267 if (*best_model_rd != INT64_MAX &&
3268 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3269 return INT64_MAX;
3270 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003271 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3272 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3273
3274 this_rate = tokenonly_rd_stats.rate + mode_cost +
3275 write_uniform_cost(2 * max_angle_delta + 1,
3276 mbmi->angle_delta[0] + max_angle_delta);
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003277 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278
3279 if (this_rd < *best_rd) {
3280 *best_rd = this_rd;
3281 *best_angle_delta = mbmi->angle_delta[0];
3282 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003283#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003284 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003285#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003286 *best_tx_type = mbmi->tx_type;
3287 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003288 rd_stats->rate = tokenonly_rd_stats.rate;
3289 rd_stats->dist = tokenonly_rd_stats.dist;
3290 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003291 }
hui su45dc5972016-12-08 17:42:50 -08003292 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003293}
3294
hui su45dc5972016-12-08 17:42:50 -08003295// With given luma directional intra prediction mode, pick the best angle delta
3296// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003297static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003298 int *rate, RD_STATS *rd_stats,
3299 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003300 int64_t best_rd,
3301 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302 MACROBLOCKD *const xd = &x->e_mbd;
3303 MODE_INFO *const mic = xd->mi[0];
3304 MB_MODE_INFO *mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003305 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08003306 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003307 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003308#if CONFIG_INTRA_INTERP
3309 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003310 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003311 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003312#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003313 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003314 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3315 TX_TYPE best_tx_type = mbmi->tx_type;
3316
hui su0a6731f2017-04-26 15:23:47 -07003317 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318
hui su0a6731f2017-04-26 15:23:47 -07003319 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003320#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003321 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3322 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3323 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003324#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003325 for (i = 0; i < 2; ++i) {
3326 best_rd_in = (best_rd == INT64_MAX)
3327 ? INT64_MAX
3328 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3329 this_rd = calc_rd_given_intra_angle(
3330 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003331#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003332 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003333#else
hui su45dc5972016-12-08 17:42:50 -08003334 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003335#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003336 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003337 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003338#if CONFIG_INTRA_INTERP
3339 &best_filter,
3340#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003341 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003342 rd_cost[2 * angle_delta + i] = this_rd;
3343 if (first_try && this_rd == INT64_MAX) return best_rd;
3344 first_try = 0;
3345 if (angle_delta == 0) {
3346 rd_cost[1] = this_rd;
3347 break;
3348 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003349 }
hui su45dc5972016-12-08 17:42:50 -08003350#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003351 }
hui su45dc5972016-12-08 17:42:50 -08003352#endif // CONFIG_INTRA_INTERP
3353 }
3354
3355 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003356 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003357 int64_t rd_thresh;
3358#if CONFIG_INTRA_INTERP
3359 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3360 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3361 mic->mbmi.intra_filter = filter;
3362#endif // CONFIG_INTRA_INTERP
3363 for (i = 0; i < 2; ++i) {
3364 int skip_search = 0;
3365 rd_thresh = best_rd + (best_rd >> 5);
3366 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3367 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3368 skip_search = 1;
3369 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003370 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003371 cpi, x, bsize,
3372#if CONFIG_INTRA_INTERP
3373 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3374#else
3375 mode_cost,
3376#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003377 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003378 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3379#if CONFIG_INTRA_INTERP
3380 &best_filter,
3381#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003382 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003383 }
3384 }
3385#if CONFIG_INTRA_INTERP
3386 }
3387#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003388 }
3389
hui sueda3d762016-12-06 16:58:23 -08003390#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003391 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003392 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003393 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003394 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3395 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003396 this_rd = calc_rd_given_intra_angle(
3397 cpi, x, bsize,
3398 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003399 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003400 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003401 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003402 }
3403 }
3404 }
hui sueda3d762016-12-06 16:58:23 -08003405#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003406
3407 mbmi->tx_size = best_tx_size;
3408 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003409#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003410 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003411#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003412 mbmi->tx_type = best_tx_type;
3413 return best_rd;
3414}
3415
3416// Indices are sign, integer, and fractional part of the gradient value
3417static const uint8_t gradient_to_angle_bin[2][7][16] = {
3418 {
3419 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3420 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3421 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3422 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3423 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3424 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3425 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3426 },
3427 {
3428 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3429 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3430 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3431 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3432 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3433 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3434 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3435 },
3436};
3437
Yue Chen56e226e2017-05-02 16:21:40 -07003438/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003439static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3440 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003441#if CONFIG_ALT_INTRA
3442 0,
3443#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003444};
Yue Chen56e226e2017-05-02 16:21:40 -07003445/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003446
3447static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003448 int cols, BLOCK_SIZE bsize,
3449 uint8_t *directional_mode_skip_mask) {
3450 memset(directional_mode_skip_mask, 0,
3451 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3452 // Sub-8x8 blocks do not use extra directions.
3453 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003454 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003455 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3456 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003457 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003458 for (r = 1; r < rows; ++r) {
3459 for (c = 1; c < cols; ++c) {
3460 dx = src[c] - src[c - 1];
3461 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003462 int index;
3463 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003464 if (dy == 0) {
3465 index = 2;
3466 } else {
hui su9cc10652017-04-27 17:22:07 -07003467 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468 dx = abs(dx);
3469 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003470 const int remd = (dx % dy) * 16 / dy;
3471 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003472 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473 }
3474 hist[index] += temp;
3475 }
3476 src += src_stride;
3477 }
3478
hui su9cc10652017-04-27 17:22:07 -07003479 int i;
3480 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003481 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3482 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003483 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003484 const uint8_t angle_bin = mode_to_angle_bin[i];
3485 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003486 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003487 if (angle_bin > 0) {
3488 score += hist[angle_bin - 1];
3489 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003490 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003491 if (angle_bin < DIRECTIONAL_MODES - 1) {
3492 score += hist[angle_bin + 1];
3493 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003494 }
3495 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3496 directional_mode_skip_mask[i] = 1;
3497 }
3498 }
3499}
3500
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003501#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003502static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003503 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003504 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003505 memset(directional_mode_skip_mask, 0,
3506 INTRA_MODES * sizeof(*directional_mode_skip_mask));
3507 // Sub-8x8 blocks do not use extra directions.
3508 if (bsize < BLOCK_8X8) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003509 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003510 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003511 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3512 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003513 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003514 for (r = 1; r < rows; ++r) {
3515 for (c = 1; c < cols; ++c) {
3516 dx = src[c] - src[c - 1];
3517 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003518 int index;
3519 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 if (dy == 0) {
3521 index = 2;
3522 } else {
hui su9cc10652017-04-27 17:22:07 -07003523 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003524 dx = abs(dx);
3525 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003526 const int remd = (dx % dy) * 16 / dy;
3527 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003528 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529 }
3530 hist[index] += temp;
3531 }
3532 src += src_stride;
3533 }
3534
hui su9cc10652017-04-27 17:22:07 -07003535 int i;
3536 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003537 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3538 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003539 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003540 const uint8_t angle_bin = mode_to_angle_bin[i];
3541 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003542 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003543 if (angle_bin > 0) {
3544 score += hist[angle_bin - 1];
3545 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003546 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003547 if (angle_bin < DIRECTIONAL_MODES - 1) {
3548 score += hist[angle_bin + 1];
3549 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003550 }
3551 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3552 directional_mode_skip_mask[i] = 1;
3553 }
3554 }
3555}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003556#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003557#endif // CONFIG_EXT_INTRA
3558
3559// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003560static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3561 int *rate, int *rate_tokenonly,
3562 int64_t *distortion, int *skippable,
3563 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003564 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 MACROBLOCKD *const xd = &x->e_mbd;
3566 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003567 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003568 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08003569 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003570 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003571#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003572 const int rows = block_size_high[bsize];
3573 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003574#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003575 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003576#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003577 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003578 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003579 const int src_stride = x->plane[0].src.stride;
3580 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003581#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003582#if CONFIG_FILTER_INTRA
3583 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003584 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3585#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003586 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003587#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003588 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003589 uint8_t *best_palette_color_map =
3590 cpi->common.allow_screen_content_tools
3591 ? x->palette_buffer->best_palette_color_map
3592 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003593 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003594 const int try_palette =
3595 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003596#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003597 const MODE_INFO *above_mi = xd->above_mi;
3598 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003599 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3600 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003602#if CONFIG_PVQ
3603 od_rollback_buffer pre_buf, post_buf;
3604
3605 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3606 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003607#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003608 bmode_costs = cpi->y_mode_costs[A][L];
3609
3610#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003611 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003612#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003613 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003614 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003615 directional_mode_skip_mask);
3616 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003617#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003618 angle_estimation(src, src_stride, rows, cols, bsize,
3619 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003621#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003622 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003623#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003624#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003625 pmi->palette_size[0] = 0;
3626 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003627 palette_y_mode_ctx +=
3628 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003629 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003630 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003631#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632
3633 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3634 x->use_default_intra_tx_type = 1;
3635 else
3636 x->use_default_intra_tx_type = 0;
3637
3638 /* Y Search for intra prediction mode */
3639 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003640 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003641 int this_rate, this_rate_tokenonly, s;
3642 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003643 if (mode_idx == FINAL_MODE_SEARCH) {
3644 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003645 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003646 x->use_default_intra_tx_type = 0;
3647 } else {
hui sude0c70a2017-01-09 17:12:17 -08003648 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003650#if CONFIG_PVQ
3651 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003652#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003653#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003654 mbmi->angle_delta[0] = 0;
3655#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003656 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003657 if (best_model_rd != INT64_MAX &&
3658 this_model_rd > best_model_rd + (best_model_rd >> 1))
3659 continue;
3660 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3661#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003662 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3663 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003664 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08003665 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07003666 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
3667 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003668 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003669 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003670 }
3671#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003672 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08003673#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003674 this_rate_tokenonly = this_rd_stats.rate;
3675 this_distortion = this_rd_stats.dist;
3676 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677
3678 if (this_rate_tokenonly == INT_MAX) continue;
3679
hui sude0c70a2017-01-09 17:12:17 -08003680 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681
hui sude0c70a2017-01-09 17:12:17 -08003682 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003683 // super_block_yrd above includes the cost of the tx_size in the
3684 // tokenonly rate, but for intra blocks, tx_size is always coded
3685 // (prediction granularity), so we account for it in the full rate,
3686 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003687 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003688 }
Urvang Joshib100db72016-10-12 16:28:56 -07003689#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003690 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003691 this_rate +=
3692 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
3693 [palette_y_mode_ctx],
3694 0);
hui su9bc1d8d2017-03-24 12:36:03 -07003695 }
Urvang Joshib100db72016-10-12 16:28:56 -07003696#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07003697#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003698 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07003699 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
3700#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003701#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003702 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08003703#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003704 const int p_angle =
3705 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003706 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07003707 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08003708 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08003709#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003710 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
3711 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003712 }
3713#endif // CONFIG_EXT_INTRA
3714 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07003715#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07003716 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08003717 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003718 }
hui su5db97432016-10-14 16:10:14 -07003719#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720
3721 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08003722 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07003724#if CONFIG_FILTER_INTRA
3725 beat_best_rd = 1;
3726#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003727 *rate = this_rate;
3728 *rate_tokenonly = this_rate_tokenonly;
3729 *distortion = this_distortion;
3730 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003731#if CONFIG_PVQ
3732 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003733#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 }
3735 }
3736
Yushin Cho77bba8d2016-11-04 16:36:56 -07003737#if CONFIG_PVQ
3738 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003739#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003740
Luc Trudeaue3980282017-04-25 23:17:21 -04003741#if CONFIG_CFL
3742 // Perform one extra txfm_rd_in_plane() call, this time with the best value so
3743 // we can store reconstructed luma values
3744 RD_STATS this_rd_stats;
3745 x->cfl_store_y = 1;
3746 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, 0, bsize,
3747 mic->mbmi.tx_size, cpi->sf.use_fast_coef_costing);
3748 x->cfl_store_y = 0;
3749#endif
3750
Urvang Joshib100db72016-10-12 16:28:56 -07003751#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07003752 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08003753 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
3754 bmode_costs[DC_PRED], &best_mbmi,
3755 best_palette_color_map, &best_rd, &best_model_rd,
3756 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08003757 }
Urvang Joshib100db72016-10-12 16:28:56 -07003758#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003759
hui su5db97432016-10-14 16:10:14 -07003760#if CONFIG_FILTER_INTRA
3761 if (beat_best_rd) {
3762 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
3763 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08003764 &best_rd, &best_model_rd,
3765 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08003766 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003767 }
3768 }
hui su5db97432016-10-14 16:10:14 -07003769#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003770
hui sude0c70a2017-01-09 17:12:17 -08003771 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003772 return best_rd;
3773}
3774
Yue Chena1e48dc2016-08-29 17:29:33 -07003775// Return value 0: early termination triggered, no valid rd cost available;
3776// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08003777static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
3778 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3779 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003780 MACROBLOCKD *const xd = &x->e_mbd;
3781 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3782 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
3783 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07003784 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08003785 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003786
3787 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08003788
Jingning Han31b6a4f2017-02-23 11:05:53 -08003789#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003790 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07003791
3792 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
3793 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08003794#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08003795
Yushin Cho77bba8d2016-11-04 16:36:56 -07003796#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003797 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07003798 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
3799 av1_subtract_plane(x, bsize, plane);
3800 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003801#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07003802
Yushin Cho09de28b2016-06-21 14:51:23 -07003803 if (is_cost_valid) {
3804 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003805 RD_STATS pn_rd_stats;
3806 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
3807 uv_tx_size, cpi->sf.use_fast_coef_costing);
3808 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003809 is_cost_valid = 0;
3810 break;
3811 }
Angie Chiang284d7772016-11-08 11:06:45 -08003812 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
3813 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >
Angie Chiang7c2b7f22016-11-07 16:00:00 -08003814 ref_best_rd &&
Angie Chiang284d7772016-11-08 11:06:45 -08003815 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07003816 is_cost_valid = 0;
3817 break;
3818 }
Yue Chena1e48dc2016-08-29 17:29:33 -07003819 }
3820 }
3821
3822 if (!is_cost_valid) {
3823 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08003824 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07003825 }
3826
3827 return is_cost_valid;
3828}
3829
Yaowu Xuc27fc142016-08-22 16:08:15 -07003830#if CONFIG_VAR_TX
Alex Converse61f37b82017-03-29 15:26:03 -07003831// FIXME crop these calls
3832static uint64_t sum_squares_2d(const int16_t *diff, int diff_stride,
3833 TX_SIZE tx_size) {
3834 return aom_sum_squares_2d_i16(diff, diff_stride, tx_size_wide[tx_size],
3835 tx_size_high[tx_size]);
3836}
3837
Yaowu Xuf883b422016-08-30 14:01:10 -07003838void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
3839 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07003840 int plane_bsize, const ENTROPY_CONTEXT *a,
3841 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07003842 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003843 MACROBLOCKD *xd = &x->e_mbd;
3844 const struct macroblock_plane *const p = &x->plane[plane];
3845 struct macroblockd_plane *const pd = &xd->plane[plane];
3846 int64_t tmp;
3847 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05003848 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003849 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003850 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -07003851 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003852 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07003853 int bh = block_size_high[txm_bsize];
3854 int bw = block_size_wide[txm_bsize];
3855 int txb_h = tx_size_high_unit[tx_size];
3856 int txb_w = tx_size_wide_unit[tx_size];
3857
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08003859 uint8_t *src =
3860 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
3861 uint8_t *dst =
3862 &pd->dst
3863 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003864#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
3866 uint8_t *rec_buffer;
3867#else
3868 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003869#endif // CONFIG_HIGHBITDEPTH
Jingning Han9fdc4222016-10-27 21:32:19 -07003870 int max_blocks_high = block_size_high[plane_bsize];
3871 int max_blocks_wide = block_size_wide[plane_bsize];
3872 const int diff_stride = max_blocks_wide;
Jingning Han9ca05b72017-01-03 14:41:36 -08003873 const int16_t *diff =
3874 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07003875 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08003876
3877 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878
3879 if (xd->mb_to_bottom_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003880 max_blocks_high += xd->mb_to_bottom_edge >> (3 + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003881 if (xd->mb_to_right_edge < 0)
Jingning Han9fdc4222016-10-27 21:32:19 -07003882 max_blocks_wide += xd->mb_to_right_edge >> (3 + pd->subsampling_x);
3883
3884 max_blocks_high >>= tx_size_wide_log2[0];
3885 max_blocks_wide >>= tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886
Angie Chiang77368af2017-03-23 16:22:07 -07003887 int coeff_ctx = get_entropy_context(tx_size, a, l);
3888
Angie Chiangff6d8902016-10-21 11:02:09 -07003889 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08003890 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891
Angie Chiang3511c372017-05-31 12:47:07 -07003892 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003893
Angie Chiang808d8592017-04-06 18:36:55 -07003894// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003895#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003896 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
3897 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07003898 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003899 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003900 } else {
3901 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07003902 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07003903 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003904 }
3905#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003906 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07003907 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003908#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003909
Jingning Han9fdc4222016-10-27 21:32:19 -07003910 if (blk_row + txb_h > max_blocks_high || blk_col + txb_w > max_blocks_wide) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003911 int idx, idy;
Jingning Han9fdc4222016-10-27 21:32:19 -07003912 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3913 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003914 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003915 for (idy = 0; idy < blocks_height; ++idy) {
3916 for (idx = 0; idx < blocks_width; ++idx) {
3917 const int16_t *d =
3918 diff + ((idy * diff_stride + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003919 tmp += sum_squares_2d(d, diff_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003920 }
3921 }
3922 } else {
Jingning Han9fdc4222016-10-27 21:32:19 -07003923 tmp = sum_squares_2d(diff, diff_stride, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003924 }
3925
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003926#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003927 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3928 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003929#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07003930 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07003931 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003932
Angie Chiang41fffae2017-04-03 10:33:18 -07003933 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
3934 MAX_TX_SIZE, eob);
3935 if (eob > 0) {
Jingning Han4b47c932016-11-03 09:20:08 -07003936 if (txb_w + blk_col > max_blocks_wide ||
3937 txb_h + blk_row > max_blocks_high) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003938 int idx, idy;
3939 unsigned int this_dist;
Jingning Han9fdc4222016-10-27 21:32:19 -07003940 int blocks_height = AOMMIN(txb_h, max_blocks_high - blk_row);
3941 int blocks_width = AOMMIN(txb_w, max_blocks_wide - blk_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 tmp = 0;
Jingning Han9ca05b72017-01-03 14:41:36 -08003943 for (idy = 0; idy < blocks_height; ++idy) {
3944 for (idx = 0; idx < blocks_width; ++idx) {
3945 uint8_t *const s =
3946 src + ((idy * src_stride + idx) << tx_size_wide_log2[0]);
3947 uint8_t *const r =
3948 rec_buffer + ((idy * MAX_TX_SIZE + idx) << tx_size_wide_log2[0]);
Jingning Han6ae75642017-01-06 15:04:36 -08003949 cpi->fn_ptr[0].vf(s, src_stride, r, MAX_TX_SIZE, &this_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003950 tmp += this_dist;
3951 }
3952 }
3953 } else {
3954 uint32_t this_dist;
3955 cpi->fn_ptr[txm_bsize].vf(src, src_stride, rec_buffer, MAX_TX_SIZE,
3956 &this_dist);
3957 tmp = this_dist;
3958 }
3959 }
Angie Chiangb5dda482016-11-02 16:19:58 -07003960 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07003961 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07003962 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07003963 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07003964 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08003965
Angie Chiangd81fdb42016-11-03 12:20:58 -07003966#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08003967 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
3968 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08003969#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003970}
3971
Yaowu Xuf883b422016-08-30 14:01:10 -07003972static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08003973 int blk_col, int plane, int block, int block32,
3974 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07003975 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
3976 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07003977 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08003978 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979 MACROBLOCKD *const xd = &x->e_mbd;
3980 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
3981 struct macroblock_plane *const p = &x->plane[plane];
3982 struct macroblockd_plane *const pd = &xd->plane[plane];
3983 const int tx_row = blk_row >> (1 - pd->subsampling_y);
3984 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07003985 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986 [MAX_MIB_SIZE] =
3987 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07003988 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
3989 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07003990 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003991 int64_t this_rd = INT64_MAX;
3992 ENTROPY_CONTEXT *pta = ta + blk_col;
3993 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003994 int coeff_ctx, i;
Jingning Han331662e2017-05-30 17:03:32 -07003995 int ctx = txfm_partition_context(tx_above + blk_col, tx_left + blk_row,
3996 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003997 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003998 int tmp_eob = 0;
3999 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07004000 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08004001 const int tx_size_ctx = txsize_sqr_map[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004002
Jingning Han63cbf342016-11-09 15:37:48 -08004003 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08004004
Jingning Hand3fada82016-11-22 10:46:55 -08004005 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004006
4007 if (ref_best_rd < 0) {
4008 *is_cost_valid = 0;
4009 return;
4010 }
4011
Jingning Hance059e82016-10-31 16:27:28 -07004012 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004013
Angie Chiangc0feea82016-11-03 15:36:18 -07004014 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004015
4016 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4017
Jingning Han1c019f92016-11-21 12:53:32 -08004018 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4019 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004020
4021 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4022 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004023
4024 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4025 rd_stats_stack[block32].rate != INT_MAX) {
4026 *rd_stats = rd_stats_stack[block32];
4027 p->eobs[block] = !rd_stats->skip;
4028 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4029 } else {
4030 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004031 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004032 if (tx_size == TX_32X32) {
4033 rd_stats_stack[block32] = *rd_stats;
4034 }
4035 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004036
Angie Chiangb5dda482016-11-02 16:19:58 -07004037 if ((RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist) >=
4038 RDCOST(x->rdmult, x->rddiv, zero_blk_rate, rd_stats->sse) ||
4039 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004041#if CONFIG_RD_DEBUG
4042 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4043 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004044#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004045 rd_stats->rate = zero_blk_rate;
4046 rd_stats->dist = rd_stats->sse;
4047 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004048 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4049 p->eobs[block] = 0;
4050 } else {
4051 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004052 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004053 }
4054
Jingning Han571189c2016-10-24 10:38:43 -07004055 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004056 rd_stats->rate +=
4057 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
4058 this_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004059 tmp_eob = p->eobs[block];
4060 }
4061
Jingning Han571189c2016-10-24 10:38:43 -07004062 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004063 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4064 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004065 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004066 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004067 int this_cost_valid = 1;
4068 int64_t tmp_rd = 0;
4069
Angie Chiangd7246172016-11-03 11:49:15 -07004070 sum_rd_stats.rate =
4071 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004072
4073 assert(tx_size < TX_SIZES_ALL);
4074
Yaowu Xuc27fc142016-08-22 16:08:15 -07004075 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004076 int offsetr = blk_row + (i >> 1) * bsl;
4077 int offsetc = blk_col + (i & 0x01) * bsl;
4078
4079 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4080
Jingning Han63cbf342016-11-09 15:37:48 -08004081 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004082 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004083 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4084 rd_stats_stack);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004085
Angie Chiangc0feea82016-11-03 15:36:18 -07004086 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004087
Angie Chiangd7246172016-11-03 11:49:15 -07004088 tmp_rd =
4089 RDCOST(x->rdmult, x->rddiv, sum_rd_stats.rate, sum_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090 if (this_rd < tmp_rd) break;
Jingning Han98d6a1f2016-11-03 12:47:47 -07004091 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092 }
4093 if (this_cost_valid) sum_rd = tmp_rd;
4094 }
4095
4096 if (this_rd < sum_rd) {
4097 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004098 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4099 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Jingning Han331662e2017-05-30 17:03:32 -07004100 txfm_partition_update(tx_above + blk_col, tx_left + blk_row, tx_size,
4101 tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004102 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004103 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4104 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 inter_tx_size[idy][idx] = tx_size;
4106 mbmi->tx_size = tx_size;
4107 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004108 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004109 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004110 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004111 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4112 }
4113}
4114
Angie Chiangb5dda482016-11-02 16:19:58 -07004115static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4116 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004117 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004118 MACROBLOCKD *const xd = &x->e_mbd;
4119 int is_cost_valid = 1;
4120 int64_t this_rd = 0;
4121
4122 if (ref_best_rd < 0) is_cost_valid = 0;
4123
Angie Chiangc0feea82016-11-03 15:36:18 -07004124 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004125
4126 if (is_cost_valid) {
4127 const struct macroblockd_plane *const pd = &xd->plane[0];
4128 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004129 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4130 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004131 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004132 const int bh = tx_size_high_unit[max_tx_size];
4133 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004134 int idx, idy;
4135 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004136 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004137 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4139 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
Jingning Han331662e2017-05-30 17:03:32 -07004140 TXFM_CONTEXT tx_above[MAX_MIB_SIZE * 2];
4141 TXFM_CONTEXT tx_left[MAX_MIB_SIZE * 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142
Angie Chiangb5dda482016-11-02 16:19:58 -07004143 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004144 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004145
Jingning Han9ca05b72017-01-03 14:41:36 -08004146 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Jingning Han331662e2017-05-30 17:03:32 -07004147 memcpy(tx_above, xd->above_txfm_context, sizeof(TXFM_CONTEXT) * mi_width);
4148 memcpy(tx_left, xd->left_txfm_context, sizeof(TXFM_CONTEXT) * mi_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004149
4150 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004151 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004152 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004153 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004154 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004155 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004156 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Angie Chiangb5dda482016-11-02 16:19:58 -07004157 this_rd += AOMMIN(
4158 RDCOST(x->rdmult, x->rddiv, pn_rd_stats.rate, pn_rd_stats.dist),
4159 RDCOST(x->rdmult, x->rddiv, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004160 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004161 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004162 }
4163 }
4164 }
4165
Angie Chiangb5dda482016-11-02 16:19:58 -07004166 this_rd = AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4167 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168 if (this_rd > ref_best_rd) is_cost_valid = 0;
4169
4170 if (!is_cost_valid) {
4171 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004172 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173 }
4174}
4175
Yaowu Xuf883b422016-08-30 14:01:10 -07004176static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004177 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004178 int64_t ref_best_rd, TX_TYPE tx_type,
4179 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004180 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004181 MACROBLOCKD *const xd = &x->e_mbd;
4182 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004183 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004184 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4185 int s0 = av1_cost_bit(skip_prob, 0);
4186 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004187 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004188 int row, col;
4189 const int max_blocks_high = max_block_high(xd, bsize, 0);
4190 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191
4192 mbmi->tx_type = tx_type;
Jingning Han63cbf342016-11-09 15:37:48 -08004193 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Jingning Han70bd76e2017-05-30 10:53:00 -07004194 mbmi->min_tx_size = get_min_tx_size(mbmi->inter_tx_size[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004195
Angie Chiangb5dda482016-11-02 16:19:58 -07004196 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197
Jingning Hane67b38a2016-11-04 10:30:00 -07004198 for (row = 0; row < max_blocks_high / 2; ++row)
4199 for (col = 0; col < max_blocks_wide / 2; ++col)
4200 mbmi->min_tx_size = AOMMIN(
4201 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4202
Yaowu Xuc27fc142016-08-22 16:08:15 -07004203#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004204 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4205 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004206 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004207 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4208 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209 if (is_inter) {
4210 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004211 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004212 cpi->inter_tx_type_costs[ext_tx_set]
4213 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004214 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215 } else {
4216 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004217 rd_stats->rate +=
4218 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4219 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004220 }
4221 }
4222#else // CONFIG_EXT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07004223 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4224 rd_stats->rate +=
4225 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226#endif // CONFIG_EXT_TX
4227
Angie Chiangb5dda482016-11-02 16:19:58 -07004228 if (rd_stats->skip)
4229 rd = RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004230 else
Angie Chiangb5dda482016-11-02 16:19:58 -07004231 rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004232
Angie Chiangb5dda482016-11-02 16:19:58 -07004233 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4234 !(rd_stats->skip))
4235 rd = AOMMIN(rd, RDCOST(x->rdmult, x->rddiv, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236
4237 return rd;
4238}
4239
Angie Chiangb5dda482016-11-02 16:19:58 -07004240static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4241 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004242 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004243 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004244 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4245 MACROBLOCKD *const xd = &x->e_mbd;
4246 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4247 int64_t rd = INT64_MAX;
4248 int64_t best_rd = INT64_MAX;
4249 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4250 const int is_inter = is_inter_block(mbmi);
4251 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004252 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004253 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004254 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Angie Chiangf1cb0752017-04-10 16:01:20 -07004255 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004256 int idx, idy;
4257 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004258 const int count32 =
4259 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004260#if CONFIG_EXT_PARTITION
4261 RD_STATS rd_stats_stack[16];
4262#else
Jingning Han63cbf342016-11-09 15:37:48 -08004263 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004264#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004265#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004266 const int ext_tx_set =
4267 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004268#endif // CONFIG_EXT_TX
4269
4270 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4271#if CONFIG_EXT_TX
4272 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4273#else
4274 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004275#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004276
Angie Chiangc0feea82016-11-03 15:36:18 -07004277 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004278
Jingning Han89d648b2016-11-22 11:22:08 -08004279 for (idx = 0; idx < count32; ++idx)
4280 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004281
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004283 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004284 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004285#if CONFIG_EXT_TX
4286 if (is_inter) {
4287 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4288 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4289 if (!do_tx_type_search(tx_type, prune)) continue;
4290 }
4291 } else {
4292 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4293 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4294 }
4295 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4296 }
4297#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004298 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4299 !do_tx_type_search(tx_type, prune))
4300 continue;
4301#endif // CONFIG_EXT_TX
4302 if (is_inter && x->use_default_inter_tx_type &&
4303 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4304 continue;
4305
Jingning Hane67b38a2016-11-04 10:30:00 -07004306 if (xd->lossless[mbmi->segment_id])
4307 if (tx_type != DCT_DCT) continue;
4308
Angie Chiangb5dda482016-11-02 16:19:58 -07004309 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004310 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004311
4312 if (rd < best_rd) {
4313 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004314 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004315 best_tx_type = mbmi->tx_type;
4316 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004317 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004318 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4319 for (idy = 0; idy < xd->n8_h; ++idy)
4320 for (idx = 0; idx < xd->n8_w; ++idx)
4321 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4322 }
4323 }
4324
4325 mbmi->tx_type = best_tx_type;
4326 for (idy = 0; idy < xd->n8_h; ++idy)
4327 for (idx = 0; idx < xd->n8_w; ++idx)
4328 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4329 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004330 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004331 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4332}
4333
Yaowu Xuf883b422016-08-30 14:01:10 -07004334static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004335 int blk_col, int plane, int block, TX_SIZE tx_size,
4336 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004337 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004338 MACROBLOCKD *const xd = &x->e_mbd;
4339 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4340 struct macroblock_plane *const p = &x->plane[plane];
4341 struct macroblockd_plane *const pd = &xd->plane[plane];
4342 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4343 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4344 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4345 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004346 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4347 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348
Jingning Hand3fada82016-11-22 10:46:55 -08004349 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004350
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4352
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004353 plane_tx_size =
4354 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4355 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004356
4357 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004358 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004359 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4360 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004361 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004362 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004363
Jingning Han58224042016-10-27 16:35:32 -07004364 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004365 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004366 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004367 tl[i] = !(p->eobs[block] == 0);
4368 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004369 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4370 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004371 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004372 int i;
4373
4374 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004375
4376 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004377 int offsetr = blk_row + (i >> 1) * bsl;
4378 int offsetc = blk_col + (i & 0x01) * bsl;
4379
4380 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4381
4382 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4383 above_ctx, left_ctx, rd_stats);
4384 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385 }
4386 }
4387}
4388
4389// Return value 0: early termination triggered, no valid rd cost available;
4390// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004391static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4392 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4393 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004394 MACROBLOCKD *const xd = &x->e_mbd;
4395 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4396 int plane;
4397 int is_cost_valid = 1;
4398 int64_t this_rd;
4399
4400 if (ref_best_rd < 0) is_cost_valid = 0;
4401
Angie Chiangc0feea82016-11-03 15:36:18 -07004402 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004403
Jingning Han31b6a4f2017-02-23 11:05:53 -08004404#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004405 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han52d2b402017-05-19 09:31:17 -07004406 bsize = scale_chroma_bsize(mbmi->sb_type, xd->plane[1].subsampling_x,
4407 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08004408#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004409
Yue Chena1e48dc2016-08-29 17:29:33 -07004410#if CONFIG_EXT_TX && CONFIG_RECT_TX
4411 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004412 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004413 }
4414#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4415
Yaowu Xuc27fc142016-08-22 16:08:15 -07004416 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004418 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419 }
4420
Yaowu Xuc27fc142016-08-22 16:08:15 -07004421 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4422 const struct macroblockd_plane *const pd = &xd->plane[plane];
4423 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004424 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4425 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004426 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004427 const int bh = tx_size_high_unit[max_tx_size];
4428 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004429 int idx, idy;
4430 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004431 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004432 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4433 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004434 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004435 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004436
Jingning Han9ca05b72017-01-03 14:41:36 -08004437 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004438
4439 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004440 for (idx = 0; idx < mi_width; idx += bw) {
4441 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004442 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004443 block += step;
4444 }
4445 }
4446
Angie Chiangb5dda482016-11-02 16:19:58 -07004447 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004448 is_cost_valid = 0;
4449 break;
4450 }
4451
Angie Chiang628d7c92016-11-03 16:24:56 -07004452 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004453
Angie Chiangb5dda482016-11-02 16:19:58 -07004454 this_rd =
4455 AOMMIN(RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist),
4456 RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004457
4458 if (this_rd > ref_best_rd) {
4459 is_cost_valid = 0;
4460 break;
4461 }
4462 }
4463
4464 if (!is_cost_valid) {
4465 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004466 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004467 }
4468
4469 return is_cost_valid;
4470}
4471#endif // CONFIG_VAR_TX
4472
Urvang Joshib100db72016-10-12 16:28:56 -07004473#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004474static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4475 int dc_mode_cost,
4476 uint8_t *best_palette_color_map,
4477 MB_MODE_INFO *const best_mbmi,
4478 int64_t *best_rd, int *rate,
4479 int *rate_tokenonly, int64_t *distortion,
4480 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004481 MACROBLOCKD *const xd = &x->e_mbd;
4482 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004483 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08004484 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004485 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004486 int this_rate;
4487 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004488 int colors_u, colors_v, colors;
4489 const int src_stride = x->plane[1].src.stride;
4490 const uint8_t *const src_u = x->plane[1].src.buf;
4491 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004492 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004493 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004494 int plane_block_width, plane_block_height, rows, cols;
4495 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4496 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004497 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4498
hui su83c26632017-01-24 17:19:06 -08004499 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004500#if CONFIG_FILTER_INTRA
4501 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4502#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004503
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004504#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004505 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004506 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4507 cpi->common.bit_depth);
4508 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4509 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004510 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004511#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004512 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4513 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004514#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004515 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004516#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004517
hui su33567b22017-04-30 16:40:19 -07004518#if CONFIG_PALETTE_DELTA_ENCODING
4519 const MODE_INFO *above_mi = xd->above_mi;
4520 const MODE_INFO *left_mi = xd->left_mi;
4521 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
4522 const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
4523#endif // CONFIG_PALETTE_DELTA_ENCODING
4524
Yaowu Xuc27fc142016-08-22 16:08:15 -07004525 colors = colors_u > colors_v ? colors_u : colors_v;
4526 if (colors > 1 && colors <= 64) {
4527 int r, c, n, i, j;
4528 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004529 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004530 float lb_u, ub_u, val_u;
4531 float lb_v, ub_v, val_v;
4532 float *const data = x->palette_buffer->kmeans_data_buf;
4533 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004534
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004535#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004536 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4537 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4538 if (cpi->common.use_highbitdepth) {
4539 lb_u = src_u16[0];
4540 ub_u = src_u16[0];
4541 lb_v = src_v16[0];
4542 ub_v = src_v16[0];
4543 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004544#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004545 lb_u = src_u[0];
4546 ub_u = src_u[0];
4547 lb_v = src_v[0];
4548 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004549#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004550 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004551#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004552
Yaowu Xuc27fc142016-08-22 16:08:15 -07004553 for (r = 0; r < rows; ++r) {
4554 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004555#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004556 if (cpi->common.use_highbitdepth) {
4557 val_u = src_u16[r * src_stride + c];
4558 val_v = src_v16[r * src_stride + c];
4559 data[(r * cols + c) * 2] = val_u;
4560 data[(r * cols + c) * 2 + 1] = val_v;
4561 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004562#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004563 val_u = src_u[r * src_stride + c];
4564 val_v = src_v[r * src_stride + c];
4565 data[(r * cols + c) * 2] = val_u;
4566 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004567#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004568 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004569#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004570 if (val_u < lb_u)
4571 lb_u = val_u;
4572 else if (val_u > ub_u)
4573 ub_u = val_u;
4574 if (val_v < lb_v)
4575 lb_v = val_v;
4576 else if (val_v > ub_v)
4577 ub_v = val_v;
4578 }
4579 }
4580
4581 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
4582 --n) {
4583 for (i = 0; i < n; ++i) {
4584 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
4585 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
4586 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004587 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07004588#if CONFIG_PALETTE_DELTA_ENCODING
hui su33567b22017-04-30 16:40:19 -07004589 optimize_palette_colors(color_cache, n_cache, n, 2, centroids);
hui sud13c24a2017-04-07 16:13:07 -07004590 // Sort the U channel colors in ascending order.
4591 for (i = 0; i < 2 * (n - 1); i += 2) {
4592 int min_idx = i;
4593 float min_val = centroids[i];
4594 for (j = i + 2; j < 2 * n; j += 2)
4595 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
4596 if (min_idx != i) {
4597 float temp_u = centroids[i], temp_v = centroids[i + 1];
4598 centroids[i] = centroids[min_idx];
4599 centroids[i + 1] = centroids[min_idx + 1];
4600 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
4601 }
4602 }
4603 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
4604#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004605 extend_palette_color_map(color_map, cols, rows, plane_block_width,
4606 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004607 pmi->palette_size[1] = n;
4608 for (i = 1; i < 3; ++i) {
4609 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004610#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004611 if (cpi->common.use_highbitdepth)
4612 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
4613 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
4614 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004615#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
4617 clip_pixel((int)centroids[j * 2 + i - 1]);
4618 }
4619 }
4620
Angie Chiang284d7772016-11-08 11:06:45 -08004621 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
4622 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004623 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08004624 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08004625 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004626 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07004627 av1_cost_bit(
4628 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui su33567b22017-04-30 16:40:19 -07004629 this_rate += av1_palette_color_cost_uv(pmi,
4630#if CONFIG_PALETTE_DELTA_ENCODING
4631 color_cache, n_cache,
4632#endif // CONFIG_PALETTE_DELTA_ENCODING
4633 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004634 for (i = 0; i < rows; ++i) {
4635 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07004636 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08004637 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08004638 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004639 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08004640 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
4641 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004642 }
4643 }
4644
Angie Chiang284d7772016-11-08 11:06:45 -08004645 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004646 if (this_rd < *best_rd) {
4647 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08004648 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004650 plane_block_width * plane_block_height *
4651 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004652 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004653 *distortion = tokenonly_rd_stats.dist;
4654 *rate_tokenonly = tokenonly_rd_stats.rate;
4655 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004656 }
4657 }
4658 }
hui su83c26632017-01-24 17:19:06 -08004659 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08004660 memcpy(color_map, best_palette_color_map,
4661 rows * cols * sizeof(best_palette_color_map[0]));
4662 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663}
Urvang Joshib100db72016-10-12 16:28:56 -07004664#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004665
hui su5db97432016-10-14 16:10:14 -07004666#if CONFIG_FILTER_INTRA
4667// Return 1 if an filter intra mode is selected; return 0 otherwise.
4668static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4669 int *rate, int *rate_tokenonly,
4670 int64_t *distortion, int *skippable,
4671 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 MACROBLOCKD *const xd = &x->e_mbd;
4673 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07004674 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08004675 int this_rate;
4676 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07004677 FILTER_INTRA_MODE mode;
4678 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08004679 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004680
hui su5db97432016-10-14 16:10:14 -07004681 av1_zero(filter_intra_mode_info);
4682 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004683 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07004684#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004685 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07004686#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687
4688 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07004689 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08004690 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004691 continue;
4692
Angie Chiang284d7772016-11-08 11:06:45 -08004693 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07004694 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004695 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
4696 write_uniform_cost(FILTER_INTRA_MODES, mode);
Angie Chiang284d7772016-11-08 11:06:45 -08004697 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 if (this_rd < *best_rd) {
4699 *best_rd = this_rd;
4700 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004701 *rate_tokenonly = tokenonly_rd_stats.rate;
4702 *distortion = tokenonly_rd_stats.dist;
4703 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07004704 filter_intra_mode_info = mbmi->filter_intra_mode_info;
4705 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004706 }
4707 }
4708
hui su5db97432016-10-14 16:10:14 -07004709 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004711 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
4712 filter_intra_mode_info.use_filter_intra_mode[1];
4713 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
4714 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004715 return 1;
4716 } else {
4717 return 0;
4718 }
4719}
hui su5db97432016-10-14 16:10:14 -07004720#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004721
hui su5db97432016-10-14 16:10:14 -07004722#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004723// Run RD calculation with given chroma intra prediction angle., and return
4724// the RD cost. Update the best mode info. if the RD cost is the best so far.
4725static int64_t pick_intra_angle_routine_sbuv(
4726 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
4727 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
4728 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004729 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004730 assert(!is_inter_block(mbmi));
Angie Chiang284d7772016-11-08 11:06:45 -08004731 int this_rate;
4732 int64_t this_rd;
4733 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004734
hui su45dc5972016-12-08 17:42:50 -08004735 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
4736 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08004737 this_rate = tokenonly_rd_stats.rate + rate_overhead;
4738 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004739 if (this_rd < *best_rd) {
4740 *best_rd = this_rd;
4741 *best_angle_delta = mbmi->angle_delta[1];
4742 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08004743 rd_stats->rate = tokenonly_rd_stats.rate;
4744 rd_stats->dist = tokenonly_rd_stats.dist;
4745 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004746 }
hui su45dc5972016-12-08 17:42:50 -08004747 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004748}
4749
hui su45dc5972016-12-08 17:42:50 -08004750// With given chroma directional intra prediction mode, pick the best angle
4751// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07004752static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07004753 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08004754 int64_t best_rd, int *rate,
4755 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004756 MACROBLOCKD *const xd = &x->e_mbd;
4757 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004758 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08004759 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07004760 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004761
hui su45dc5972016-12-08 17:42:50 -08004762 rd_stats->rate = INT_MAX;
4763 rd_stats->skip = 0;
4764 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07004765 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766
hui su0a6731f2017-04-26 15:23:47 -07004767 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004768 for (i = 0; i < 2; ++i) {
4769 best_rd_in = (best_rd == INT64_MAX)
4770 ? INT64_MAX
4771 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
4772 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
4773 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
4774 best_rd_in, rate, rd_stats,
4775 &best_angle_delta, &best_rd);
4776 rd_cost[2 * angle_delta + i] = this_rd;
4777 if (angle_delta == 0) {
4778 if (this_rd == INT64_MAX) return 0;
4779 rd_cost[1] = this_rd;
4780 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004781 }
4782 }
hui su45dc5972016-12-08 17:42:50 -08004783 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004784
hui su45dc5972016-12-08 17:42:50 -08004785 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07004786 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08004787 int64_t rd_thresh;
4788 for (i = 0; i < 2; ++i) {
4789 int skip_search = 0;
4790 rd_thresh = best_rd + (best_rd >> 5);
4791 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
4792 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
4793 skip_search = 1;
4794 if (!skip_search) {
4795 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07004796 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4797 rate, rd_stats, &best_angle_delta,
4798 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004799 }
4800 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004801 }
4802
4803 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08004804 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004805}
4806#endif // CONFIG_EXT_INTRA
4807
hui sueaddeee2017-05-30 12:19:38 -07004808static void init_sbuv_mode(MB_MODE_INFO *const mbmi) {
4809 mbmi->uv_mode = DC_PRED;
4810#if CONFIG_PALETTE
4811 mbmi->palette_mode_info.palette_size[1] = 0;
4812#endif // CONFIG_PALETTE
4813#if CONFIG_FILTER_INTRA
4814 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4815#endif // CONFIG_FILTER_INTRA
4816}
4817
Urvang Joshi52648442016-10-13 17:27:51 -07004818static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
4819 int *rate, int *rate_tokenonly,
4820 int64_t *distortion, int *skippable,
4821 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004822 MACROBLOCKD *xd = &x->e_mbd;
4823 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004824 assert(!is_inter_block(mbmi));
hui su83c26632017-01-24 17:19:06 -08004825 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004826 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004827 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08004828 int this_rate;
4829 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004830#if CONFIG_PVQ
4831 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004832 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004833#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07004834#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08004835 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004836 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07004837#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004838
Yaowu Xuc27fc142016-08-22 16:08:15 -07004839 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08004840#if CONFIG_EXT_INTRA
4841 const int is_directional_mode =
4842 av1_is_directional_mode(mode, mbmi->sb_type);
4843#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08004844 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
4845 (1 << mode)))
4846 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004847
4848 mbmi->uv_mode = mode;
4849#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004850 mbmi->angle_delta[1] = 0;
hui su0c628e62016-11-30 15:20:48 -08004851 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004852 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
4853 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08004854 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
4855 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004856 continue;
4857 } else {
hui su83c26632017-01-24 17:19:06 -08004858#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004859 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004860#if CONFIG_PVQ
4861 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004862#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004863 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004864 }
hui su83c26632017-01-24 17:19:06 -08004865#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 }
hui su83c26632017-01-24 17:19:06 -08004867#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08004868 this_rate =
4869 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08004870
4871#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08004872 if (is_directional_mode) {
hui su0a6731f2017-04-26 15:23:47 -07004873 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4874 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08004875 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004876#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07004877#if CONFIG_FILTER_INTRA
4878 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
4879 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
4880#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07004881#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004882 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
4883 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07004884 this_rate += av1_cost_bit(
4885 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07004886#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004887
Yushin Cho77bba8d2016-11-04 16:36:56 -07004888#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004889 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004890#endif // CONFIG_PVQ
Yushin Cho5c207292017-02-16 15:01:33 -08004891 this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004892
4893 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08004894 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004895 best_rd = this_rd;
4896 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08004897 *rate_tokenonly = tokenonly_rd_stats.rate;
4898 *distortion = tokenonly_rd_stats.dist;
4899 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004900 }
4901 }
4902
Urvang Joshib100db72016-10-12 16:28:56 -07004903#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004904 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
4905 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08004906 rd_pick_palette_intra_sbuv(cpi, x,
4907 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
4908 best_palette_color_map, &best_mbmi, &best_rd,
4909 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004910 }
Urvang Joshib100db72016-10-12 16:28:56 -07004911#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004912
hui su5db97432016-10-14 16:10:14 -07004913#if CONFIG_FILTER_INTRA
4914 if (mbmi->sb_type >= BLOCK_8X8) {
4915 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08004916 skippable, bsize, &best_rd))
4917 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004918 }
hui su5db97432016-10-14 16:10:14 -07004919#endif // CONFIG_FILTER_INTRA
4920
hui su83c26632017-01-24 17:19:06 -08004921 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08004922 // Make sure we actually chose a mode
4923 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004924 return best_rd;
4925}
4926
Urvang Joshi52648442016-10-13 17:27:51 -07004927static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004928 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
4929 TX_SIZE max_tx_size, int *rate_uv,
4930 int *rate_uv_tokenonly, int64_t *dist_uv,
4931 int *skip_uv, PREDICTION_MODE *mode_uv) {
4932 // Use an estimated rd for uv_intra based on DC_PRED if the
4933 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07004934 (void)ctx;
hui sueaddeee2017-05-30 12:19:38 -07004935 init_sbuv_mode(&x->e_mbd.mi[0]->mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08004936#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08004937#if CONFIG_CHROMA_2X2
4938 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4939 bsize, max_tx_size);
4940#else
Jingning Han9ce464c2017-02-20 15:36:30 -08004941 if (x->skip_chroma_rd) {
4942 *rate_uv = 0;
4943 *rate_uv_tokenonly = 0;
4944 *dist_uv = 0;
4945 *skip_uv = 1;
4946 *mode_uv = DC_PRED;
4947 return;
4948 }
Jingning Han65113f32017-04-12 10:06:58 -07004949 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
4950 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07004951 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07004952 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08004953#endif // CONFIG_CHROMA_2X2
4954#else
4955 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
4956 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
4957#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07004958 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
4959}
4960
Urvang Joshi52648442016-10-13 17:27:51 -07004961static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004962 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004963#if CONFIG_EXT_INTER
4964 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08004965 return cpi
4966 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004967 }
David Barkercb03dc32017-04-07 13:05:09 +01004968#endif
4969
David Barkercb03dc32017-04-07 13:05:09 +01004970 int mode_cost = 0;
4971 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
4972 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
4973
4974 assert(is_inter_mode(mode));
4975
4976 if (mode == NEWMV) {
4977 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
4978 return mode_cost;
4979 } else {
4980 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
4981 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
4982
4983 if (is_all_zero_mv) return mode_cost;
4984
4985 if (mode == ZEROMV) {
4986 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
4987 return mode_cost;
4988 } else {
4989 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
4990 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
4991
4992 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
4993 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
4994 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
4995
4996 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
4997 return mode_cost;
4998 }
4999 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005000}
5001
Yue Chen5e606542017-05-24 17:03:17 -07005002#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005003static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
5004 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005005 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08005006 switch (comp_type) {
5007 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005008#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08005009 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005010#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08005011#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08005012 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08005013#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08005014 default: assert(0); return 0;
5015 }
5016}
Yue Chen5e606542017-05-24 17:03:17 -07005017#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005018
Yaowu Xuc27fc142016-08-22 16:08:15 -07005019typedef struct {
5020 int eobs;
5021 int brate;
5022 int byrate;
5023 int64_t bdist;
5024 int64_t bsse;
5025 int64_t brdcost;
5026 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005027 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005028#if CONFIG_EXT_INTER
5029 int_mv ref_mv[2];
5030#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005031
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005032#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08005033 ENTROPY_CONTEXT ta[4];
5034 ENTROPY_CONTEXT tl[4];
5035#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005036 ENTROPY_CONTEXT ta[2];
5037 ENTROPY_CONTEXT tl[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005038#endif // CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -07005039} SEG_RDSTAT;
5040
5041typedef struct {
5042 int_mv *ref_mv[2];
5043 int_mv mvp;
5044
5045 int64_t segment_rd;
5046 int r;
5047 int64_t d;
5048 int64_t sse;
5049 int segment_yrate;
5050 PREDICTION_MODE modes[4];
5051#if CONFIG_EXT_INTER
5052 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
5053#else
5054 SEG_RDSTAT rdstat[4][INTER_MODES];
5055#endif // CONFIG_EXT_INTER
5056 int mvthresh;
5057} BEST_SEG_INFO;
5058
Alex Converse0fa0f422017-04-24 12:51:14 -07005059static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5060 return (mv->row >> 3) < mv_limits->row_min ||
5061 (mv->row >> 3) > mv_limits->row_max ||
5062 (mv->col >> 3) < mv_limits->col_min ||
5063 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005064}
5065
Yaowu Xuc27fc142016-08-22 16:08:15 -07005066// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5067// TODO(aconverse): Find out if this is still productive then clean up or remove
5068static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005069 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005070#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005071 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005072#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005073 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005074 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5075 int mi_row, int mi_col) {
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005076 int_mv zeromv[2] = { {.as_int = 0 } };
Sarah Parkerc2d38712017-01-24 15:15:41 -08005077 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
David Barker45390c12017-02-20 14:44:40 +00005078 (void)mi_row;
5079 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005080#if CONFIG_GLOBAL_MOTION
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005081 if (this_mode == ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005082#if CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005083 || this_mode == ZERO_ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005084#endif // CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005085 ) {
5086 for (int cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005087 zeromv[cur_frm].as_int =
5088 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005089 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005090 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005091 .as_int;
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005092 }
Sarah Parkerc2d38712017-01-24 15:15:41 -08005093 }
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005094#endif // CONFIG_GLOBAL_MOTION
5095
Yaowu Xuc27fc142016-08-22 16:08:15 -07005096#if !CONFIG_EXT_INTER
5097 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005098#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005099 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005100 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005101 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005102 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005103 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005104 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005105 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5106 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5107 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108
Yaowu Xuc27fc142016-08-22 16:08:15 -07005109 if (this_mode == NEARMV) {
5110 if (c1 > c3) return 0;
5111 } else if (this_mode == NEARESTMV) {
5112 if (c2 > c3) return 0;
5113 } else {
5114 assert(this_mode == ZEROMV);
5115 if (ref_frames[1] <= INTRA_FRAME) {
5116 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5117 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5118 return 0;
5119 } else {
5120 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5121 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5122 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5123 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5124 return 0;
5125 }
5126 }
5127 }
5128#if CONFIG_EXT_INTER
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005129 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005130 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005131 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5132 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005133 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005134 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5135 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005138 if (this_mode == NEAREST_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005139 if (c2 > c3) return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005140 } else if (this_mode == NEAR_NEARMV) {
5141 if (c5 > c3) return 0;
5142 } else {
5143 assert(this_mode == ZERO_ZEROMV);
5144 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5145 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005147 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148 return 0;
5149 }
5150 }
5151#endif // CONFIG_EXT_INTER
5152 return 1;
5153}
5154
Urvang Joshi52648442016-10-13 17:27:51 -07005155static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
5156 BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
5157 int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005158#if CONFIG_EXT_INTER
David Barkerc155e012017-05-11 13:54:54 +01005159 int_mv *ref_mv_sub8x8[2], const uint8_t *mask,
5160 int mask_stride,
Fergus Simpson4063a682017-02-28 16:52:22 -08005161#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005162 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005163 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005164 const int pw = block_size_wide[bsize];
5165 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005166 MACROBLOCKD *xd = &x->e_mbd;
5167 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005168 // This function should only ever be called for compound modes
5169 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005170 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005171 int_mv ref_mv[2];
5172 int ite, ref;
5173#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07005174 InterpFilter interp_filter[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005175 mbmi->interp_filter[0], mbmi->interp_filter[1], mbmi->interp_filter[2],
5176 mbmi->interp_filter[3],
5177 };
5178#else
James Zern7b9407a2016-05-18 23:48:05 -07005179 const InterpFilter interp_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08005180#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005181 struct scale_factors sf;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005182 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005183#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005184 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5185 const int ic = block & 1;
5186 const int ir = (block - ic) >> 1;
5187 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5188 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005189#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005190 int is_global[2];
5191 for (ref = 0; ref < 2; ++ref) {
5192 WarpedMotionParams *const wm =
5193 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5194 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5195 }
5196#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005197#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198
5199 // Do joint motion search in compound mode to get more accurate mv.
5200 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5201 int last_besterr[2] = { INT_MAX, INT_MAX };
5202 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005203 av1_get_scaled_ref_frame(cpi, refs[0]),
5204 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 };
5206
5207// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005208#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005209 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5210 uint8_t *second_pred;
5211#else
5212 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005213#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005214
Jingning Han61418bb2017-01-23 17:12:48 -08005215#if CONFIG_EXT_INTER && CONFIG_CB4X4
5216 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005217#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005218
Yaowu Xuc27fc142016-08-22 16:08:15 -07005219 for (ref = 0; ref < 2; ++ref) {
Jingning Han61418bb2017-01-23 17:12:48 -08005220#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005221 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5222 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5223 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005224#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005225 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5226
5227 if (scaled_ref_frame[ref]) {
5228 int i;
5229 // Swap out the reference frame for a version that's been scaled to
5230 // match the resolution of the current frame, allowing the existing
5231 // motion search code to be used without additional modifications.
5232 for (i = 0; i < MAX_MB_PLANE; i++)
5233 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005234 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5235 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005237 }
5238
5239// Since we have scaled the reference frames to match the size of the current
5240// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005241#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005242 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5243 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005244#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005245 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5246 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005247#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005248
5249 // Allow joint search multiple times iteratively for each reference frame
5250 // and break out of the search loop if it couldn't find a better mv.
5251 for (ite = 0; ite < 4; ite++) {
5252 struct buf_2d ref_yv12[2];
5253 int bestsme = INT_MAX;
5254 int sadpb = x->sadperbit16;
5255 MV *const best_mv = &x->best_mv.as_mv;
5256 int search_range = 3;
5257
Alex Converse0fa0f422017-04-24 12:51:14 -07005258 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005259 int id = ite % 2; // Even iterations search in the first reference frame,
5260 // odd iterations search in the second. The predictor
5261 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005262 const int plane = 0;
5263 ConvolveParams conv_params = get_conv_params(0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005264#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5265 WarpTypesAllowed warp_types;
5266#if CONFIG_GLOBAL_MOTION
5267 warp_types.global_warp_allowed = is_global[!id];
5268#endif // CONFIG_GLOBAL_MOTION
5269#if CONFIG_WARPED_MOTION
5270 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5271#endif // CONFIG_WARPED_MOTION
5272#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005273
5274 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005275 ref_yv12[0] = xd->plane[plane].pre[0];
5276 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005277
5278#if CONFIG_DUAL_FILTER
5279 // reload the filter types
5280 interp_filter[0] =
5281 (id == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0];
5282 interp_filter[1] =
5283 (id == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1];
Fergus Simpson4063a682017-02-28 16:52:22 -08005284#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005285
5286// Get the prediction block from the 'other' reference frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005287#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005288 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5289 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005290 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005291 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5292 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, 0, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005293#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5294 &warp_types, p_col, p_row,
5295#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005296 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297 } else {
5298 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005299#endif // CONFIG_HIGHBITDEPTH
Angie Chiang9f45bc42017-01-13 16:27:54 -08005300 av1_build_inter_predictor(
5301 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5302 &frame_mv[refs[!id]].as_mv, &sf, pw, ph, &conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005303#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5304 &warp_types, p_col, p_row, plane, !id,
5305#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005306 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005307#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005309#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310
5311 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005312 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005313 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005314
5315 // Use the mv result from the single mode as mv predictor.
5316 *best_mv = frame_mv[refs[id]].as_mv;
5317
5318 best_mv->col >>= 3;
5319 best_mv->row >>= 3;
5320
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005321 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005322
5323 // Small-range full-pixel motion search.
5324 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005325 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
David Barkerc155e012017-05-11 13:54:54 +01005326#if CONFIG_EXT_INTER
5327 mask, mask_stride, id,
5328#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005329 &ref_mv[id].as_mv, second_pred);
David Barkerc155e012017-05-11 13:54:54 +01005330 if (bestsme < INT_MAX) {
5331#if CONFIG_EXT_INTER
5332 if (mask)
5333 bestsme = av1_get_mvpred_mask_var(x, best_mv, &ref_mv[id].as_mv,
5334 second_pred, mask, mask_stride, id,
5335 &cpi->fn_ptr[bsize], 1);
5336 else
5337#endif
5338 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5339 second_pred, &cpi->fn_ptr[bsize], 1);
5340 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005341
Alex Converse0fa0f422017-04-24 12:51:14 -07005342 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005343
5344 if (bestsme < INT_MAX) {
5345 int dis; /* TODO: use dis in distortion calculation later. */
5346 unsigned int sse;
5347 if (cpi->sf.use_upsampled_references) {
5348 // Use up-sampled reference frames.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005349 struct buf_2d backup_pred = pd->pre[0];
5350 const YV12_BUFFER_CONFIG *upsampled_ref =
5351 get_upsampled_ref(cpi, refs[id]);
5352
5353 // Set pred for Y plane
Jingning Han91d9a792017-04-18 12:01:52 -07005354 setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 upsampled_ref->y_crop_width,
5356 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
5357 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
5358 pd->subsampling_y);
5359
Jingning Han271bb2c2016-12-14 12:34:46 -08005360// If bsize < BLOCK_8X8, adjust pred pointer for this block
5361#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005362 if (bsize < BLOCK_8X8)
5363 pd->pre[0].buf =
Yaowu Xuf883b422016-08-30 14:01:10 -07005364 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
5365 pd->pre[0].stride))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005366 << 3];
Fergus Simpson4063a682017-02-28 16:52:22 -08005367#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368
5369 bestsme = cpi->find_fractional_mv_step(
5370 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5371 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5372 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01005373 &dis, &sse, second_pred,
5374#if CONFIG_EXT_INTER
5375 mask, mask_stride, id,
5376#endif
5377 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005378
5379 // Restore the reference frames.
5380 pd->pre[0] = backup_pred;
5381 } else {
5382 (void)block;
5383 bestsme = cpi->find_fractional_mv_step(
5384 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5385 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5386 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01005387 &dis, &sse, second_pred,
5388#if CONFIG_EXT_INTER
5389 mask, mask_stride, id,
5390#endif
5391 pw, ph, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005392 }
5393 }
5394
5395 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005396 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005397
5398 if (bestsme < last_besterr[id]) {
5399 frame_mv[refs[id]].as_mv = *best_mv;
5400 last_besterr[id] = bestsme;
5401 } else {
5402 break;
5403 }
5404 }
5405
5406 *rate_mv = 0;
5407
5408 for (ref = 0; ref < 2; ++ref) {
5409 if (scaled_ref_frame[ref]) {
5410 // Restore the prediction frame pointers to their unscaled versions.
5411 int i;
5412 for (i = 0; i < MAX_MB_PLANE; i++)
5413 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5414 }
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005415 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
Jingning Han61418bb2017-01-23 17:12:48 -08005416#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005418#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuf883b422016-08-30 14:01:10 -07005419 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5420 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5421 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
Jingning Han61418bb2017-01-23 17:12:48 -08005422#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005423 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005424 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5425 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5426 x->mvcost, MV_COST_WEIGHT);
Fergus Simpson4063a682017-02-28 16:52:22 -08005427#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005428 }
5429}
5430
Yaowu Xuf883b422016-08-30 14:01:10 -07005431static void estimate_ref_frame_costs(const AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005432 const MACROBLOCKD *xd, int segment_id,
5433 unsigned int *ref_costs_single,
5434 unsigned int *ref_costs_comp,
Yaowu Xuf883b422016-08-30 14:01:10 -07005435 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436 int seg_ref_active =
5437 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5438 if (seg_ref_active) {
5439 memset(ref_costs_single, 0,
5440 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
5441 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
5442 *comp_mode_p = 128;
5443 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005444 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5445 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005446
5447 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005448 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005449 *comp_mode_p = comp_inter_p;
5450 } else {
5451 *comp_mode_p = 128;
5452 }
5453
Yaowu Xuf883b422016-08-30 14:01:10 -07005454 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005455
5456 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005457 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5458 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005459#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005460 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5461 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5462 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005463#endif // CONFIG_EXT_REFS
5464
Yaowu Xuf883b422016-08-30 14:01:10 -07005465 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005466
5467 ref_costs_single[LAST_FRAME] =
5468#if CONFIG_EXT_REFS
5469 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
5470 ref_costs_single[BWDREF_FRAME] =
5471#endif // CONFIG_EXT_REFS
5472 ref_costs_single[GOLDEN_FRAME] =
5473 ref_costs_single[ALTREF_FRAME] = base_cost;
5474
5475#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005476 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5477 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
5478 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
5479 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
5480 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
5481 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005482
Yaowu Xuf883b422016-08-30 14:01:10 -07005483 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
5484 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
5485 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
5486 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005487
Yaowu Xuf883b422016-08-30 14:01:10 -07005488 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
5489 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005490
Yaowu Xuf883b422016-08-30 14:01:10 -07005491 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
5492 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493
Yaowu Xuf883b422016-08-30 14:01:10 -07005494 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
5495 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005497 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
5498 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
5499 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005500
Yaowu Xuf883b422016-08-30 14:01:10 -07005501 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
5502 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503#endif // CONFIG_EXT_REFS
5504 } else {
5505 ref_costs_single[LAST_FRAME] = 512;
5506#if CONFIG_EXT_REFS
5507 ref_costs_single[LAST2_FRAME] = 512;
5508 ref_costs_single[LAST3_FRAME] = 512;
5509 ref_costs_single[BWDREF_FRAME] = 512;
5510#endif // CONFIG_EXT_REFS
5511 ref_costs_single[GOLDEN_FRAME] = 512;
5512 ref_costs_single[ALTREF_FRAME] = 512;
5513 }
5514
5515 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005516 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005518 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
5519 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
5520 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005521#endif // CONFIG_EXT_REFS
5522
Yaowu Xuf883b422016-08-30 14:01:10 -07005523 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005524
5525 ref_costs_comp[LAST_FRAME] =
5526#if CONFIG_EXT_REFS
5527 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
5528#endif // CONFIG_EXT_REFS
5529 ref_costs_comp[GOLDEN_FRAME] = base_cost;
5530
5531#if CONFIG_EXT_REFS
5532 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
5533#endif // CONFIG_EXT_REFS
5534
5535#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005536 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5537 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
5538 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
5539 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005540
Yaowu Xuf883b422016-08-30 14:01:10 -07005541 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
5542 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543
Yaowu Xuf883b422016-08-30 14:01:10 -07005544 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
5545 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005546
5547 // NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
5548 // more bit.
Yaowu Xuf883b422016-08-30 14:01:10 -07005549 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
5550 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005552 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
5553 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005554#endif // CONFIG_EXT_REFS
5555 } else {
5556 ref_costs_comp[LAST_FRAME] = 512;
5557#if CONFIG_EXT_REFS
5558 ref_costs_comp[LAST2_FRAME] = 512;
5559 ref_costs_comp[LAST3_FRAME] = 512;
5560 ref_costs_comp[BWDREF_FRAME] = 512;
5561 ref_costs_comp[ALTREF_FRAME] = 512;
5562#endif // CONFIG_EXT_REFS
5563 ref_costs_comp[GOLDEN_FRAME] = 512;
5564 }
5565 }
5566}
5567
5568static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
5569 int mode_index,
5570 int64_t comp_pred_diff[REFERENCE_MODES],
5571 int skippable) {
5572 MACROBLOCKD *const xd = &x->e_mbd;
5573
5574 // Take a snapshot of the coding context so it can be
5575 // restored if we decide to encode this way
5576 ctx->skip = x->skip;
5577 ctx->skippable = skippable;
5578 ctx->best_mode_index = mode_index;
5579 ctx->mic = *xd->mi[0];
5580 ctx->mbmi_ext = *x->mbmi_ext;
5581 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
5582 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
5583 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
5584}
5585
clang-format55ce9e02017-02-15 22:27:12 -08005586static void setup_buffer_inter(
5587 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
5588 BLOCK_SIZE block_size, int mi_row, int mi_col,
5589 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
5590 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
5591 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005592 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
5594 MACROBLOCKD *const xd = &x->e_mbd;
5595 MODE_INFO *const mi = xd->mi[0];
5596 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
5597 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
5598 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
5599
5600 assert(yv12 != NULL);
5601
5602 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
5603 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07005604 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605
5606 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005607 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
5608 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005610 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005612 candidates, mi_row, mi_col, NULL, NULL,
5613 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614
5615 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07005616 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
5617 &frame_nearest_mv[ref_frame],
5618 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005619
Jingning Han271bb2c2016-12-14 12:34:46 -08005620// Further refinement that is encode side only to test the top few candidates
5621// in full and choose the best as the centre point for subsequent searches.
5622// The current implementation doesn't support scaling.
5623#if CONFIG_CB4X4
5624 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
5625 block_size);
5626#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005627 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
5628 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
5629 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08005630#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005631}
5632
Urvang Joshi52648442016-10-13 17:27:51 -07005633static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
5634 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005636 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637#endif // CONFIG_EXT_INTER
5638 int *rate_mv) {
5639 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07005640 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005641 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5642 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
5643 int bestsme = INT_MAX;
5644 int step_param;
5645 int sadpb = x->sadperbit16;
5646 MV mvp_full;
5647#if CONFIG_EXT_INTER
5648 int ref = mbmi->ref_frame[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005649#else
5650 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 int ref_idx = 0;
5652#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07005653 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005654
Alex Converse0fa0f422017-04-24 12:51:14 -07005655 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005656 int cost_list[5];
5657
5658 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07005659 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005660
5661 MV pred_mv[3];
5662 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
5663 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
5664 pred_mv[2] = x->pred_mv[ref];
5665
Yaowu Xuc27fc142016-08-22 16:08:15 -07005666 if (scaled_ref_frame) {
5667 int i;
5668 // Swap out the reference frame for a version that's been scaled to
5669 // match the resolution of the current frame, allowing the existing
5670 // motion search code to be used without additional modifications.
5671 for (i = 0; i < MAX_MB_PLANE; i++)
5672 backup_yv12[i] = xd->plane[i].pre[ref_idx];
5673
Yaowu Xuf883b422016-08-30 14:01:10 -07005674 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 }
5676
Alex Converse0fa0f422017-04-24 12:51:14 -07005677 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005678
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005679 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07005680
Yaowu Xuc27fc142016-08-22 16:08:15 -07005681 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07005682 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07005683 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
5684 // Take wtd average of the step_params based on the last frame's
5685 // max mv magnitude and that based on the best ref mvs of the current
5686 // block for the given reference.
5687 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07005688 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07005689 2;
5690 } else {
5691 step_param = cpi->mv_step_param;
5692 }
5693
5694 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
5695 int boffset =
5696 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07005697 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
5698 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005699 }
5700
5701 if (cpi->sf.adaptive_motion_search) {
5702 int bwl = b_width_log2_lookup[bsize];
5703 int bhl = b_height_log2_lookup[bsize];
5704 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
5705
5706 if (tlevel < 5) step_param += 2;
5707
5708 // prev_mv_sad is not setup for dynamically scaled frames.
5709 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
5710 int i;
5711 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
5712 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
5713 x->pred_mv[ref].row = 0;
5714 x->pred_mv[ref].col = 0;
5715 x->best_mv.as_int = INVALID_MV;
5716
5717 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07005718 int j;
5719 for (j = 0; j < MAX_MB_PLANE; ++j)
5720 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005721 }
5722 return;
5723 }
5724 }
5725 }
5726 }
5727
Alex Converse0fa0f422017-04-24 12:51:14 -07005728 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005729
Yue Chene9638cc2016-10-10 12:37:54 -07005730#if CONFIG_MOTION_VAR
5731 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
5732 mvp_full = mbmi->mv[0].as_mv;
5733 else
5734#endif // CONFIG_MOTION_VAR
5735 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005736
5737 mvp_full.col >>= 3;
5738 mvp_full.row >>= 3;
5739
5740 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
5741
Yue Chene9638cc2016-10-10 12:37:54 -07005742#if CONFIG_MOTION_VAR
5743 switch (mbmi->motion_mode) {
5744 case SIMPLE_TRANSLATION:
5745#endif // CONFIG_MOTION_VAR
5746 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
5747 sadpb, cond_cost_list(cpi, cost_list),
5748 &ref_mv, INT_MAX, 1);
5749#if CONFIG_MOTION_VAR
5750 break;
5751 case OBMC_CAUSAL:
5752 bestsme = av1_obmc_full_pixel_diamond(
5753 cpi, x, &mvp_full, step_param, sadpb,
5754 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
5755 &(x->best_mv.as_mv), 0);
5756 break;
5757 default: assert("Invalid motion mode!\n");
5758 }
5759#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005760
Alex Converse0fa0f422017-04-24 12:51:14 -07005761 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005762
5763 if (bestsme < INT_MAX) {
5764 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07005765#if CONFIG_MOTION_VAR
5766 switch (mbmi->motion_mode) {
5767 case SIMPLE_TRANSLATION:
5768#endif // CONFIG_MOTION_VAR
5769 if (cpi->sf.use_upsampled_references) {
5770 int best_mv_var;
5771 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
5772 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005773 const int pw = block_size_wide[bsize];
5774 const int ph = block_size_high[bsize];
Yue Chene9638cc2016-10-10 12:37:54 -07005775 // Use up-sampled reference frames.
5776 struct macroblockd_plane *const pd = &xd->plane[0];
5777 struct buf_2d backup_pred = pd->pre[ref_idx];
5778 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779
Yue Chene9638cc2016-10-10 12:37:54 -07005780 // Set pred for Y plane
5781 setup_pred_plane(
Jingning Han91d9a792017-04-18 12:01:52 -07005782 &pd->pre[ref_idx], bsize, upsampled_ref->y_buffer,
Yue Chene9638cc2016-10-10 12:37:54 -07005783 upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
5784 upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
5785 pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005786
Yue Chene9638cc2016-10-10 12:37:54 -07005787 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
5789 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
5790 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01005791 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
5792#if CONFIG_EXT_INTER
5793 NULL, 0, 0,
5794#endif
5795 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005796
Yue Chene9638cc2016-10-10 12:37:54 -07005797 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07005798 const int minc =
5799 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
5800 const int maxc =
5801 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
5802 const int minr =
5803 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
5804 const int maxr =
5805 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07005806 int this_var;
5807 MV best_mv = x->best_mv.as_mv;
5808
5809 x->best_mv = x->second_best_mv;
5810 if (x->best_mv.as_mv.row * 8 <= maxr &&
5811 x->best_mv.as_mv.row * 8 >= minr &&
5812 x->best_mv.as_mv.col * 8 <= maxc &&
5813 x->best_mv.as_mv.col * 8 >= minc) {
5814 this_var = cpi->find_fractional_mv_step(
5815 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
5816 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
5817 cpi->sf.mv.subpel_iters_per_step,
5818 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01005819 &dis, &x->pred_sse[ref], NULL,
5820#if CONFIG_EXT_INTER
5821 NULL, 0, 0,
5822#endif
5823 pw, ph, 1);
Yue Chene9638cc2016-10-10 12:37:54 -07005824 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
5825 x->best_mv.as_mv = best_mv;
5826 }
5827 }
5828
5829 // Restore the reference frames.
5830 pd->pre[ref_idx] = backup_pred;
5831 } else {
5832 cpi->find_fractional_mv_step(
5833 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
5834 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
5835 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01005836 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
5837#if CONFIG_EXT_INTER
5838 NULL, 0, 0,
5839#endif
5840 0, 0, 0);
Yue Chene9638cc2016-10-10 12:37:54 -07005841 }
5842#if CONFIG_MOTION_VAR
5843 break;
5844 case OBMC_CAUSAL:
5845 av1_find_best_obmc_sub_pixel_tree_up(
5846 cpi, x, mi_row, mi_col, &x->best_mv.as_mv, &ref_mv,
5847 cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
5848 cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
5849 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], 0,
5850 cpi->sf.use_upsampled_references);
5851 break;
5852 default: assert("Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07005853 }
Yue Chene9638cc2016-10-10 12:37:54 -07005854#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005855 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005856 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
5857 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005858
Yue Chene9638cc2016-10-10 12:37:54 -07005859#if CONFIG_MOTION_VAR
5860 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
5861#else
5862 if (cpi->sf.adaptive_motion_search)
5863#endif // CONFIG_MOTION_VAR
5864 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005865
5866 if (scaled_ref_frame) {
5867 int i;
5868 for (i = 0; i < MAX_MB_PLANE; i++)
5869 xd->plane[i].pre[ref_idx] = backup_yv12[i];
5870 }
5871}
5872
David Barkerac37fa32016-12-02 12:30:21 +00005873static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005874 int i;
5875 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00005876 xd->plane[i].dst.buf = dst.plane[i];
5877 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005878 }
5879}
5880
Yaowu Xuc27fc142016-08-22 16:08:15 -07005881#if CONFIG_EXT_INTER
David Barker8dd9b572017-05-12 16:31:38 +01005882static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x,
David Barkerf19f35f2017-05-22 16:33:22 +01005883 BLOCK_SIZE bsize, const MV *other_mv,
David Barker8dd9b572017-05-12 16:31:38 +01005884 int mi_row, int mi_col, const int block,
5885 int ref_idx, uint8_t *second_pred) {
5886 const AV1_COMMON *const cm = &cpi->common;
5887 const int pw = block_size_wide[bsize];
5888 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005889 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005890 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
David Barker8dd9b572017-05-12 16:31:38 +01005891 const int other_ref = mbmi->ref_frame[!ref_idx];
5892#if CONFIG_DUAL_FILTER
5893 InterpFilter interp_filter[2] = {
5894 (ref_idx == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0],
5895 (ref_idx == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1]
5896 };
5897#else
5898 const InterpFilter interp_filter = mbmi->interp_filter;
5899#endif // CONFIG_DUAL_FILTER
5900 struct scale_factors sf;
5901#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5902 struct macroblockd_plane *const pd = &xd->plane[0];
5903 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5904 const int ic = block & 1;
5905 const int ir = (block - ic) >> 1;
5906 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5907 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
5908#if CONFIG_GLOBAL_MOTION
5909 WarpedMotionParams *const wm = &xd->global_motion[other_ref];
5910 int is_global = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5911#endif // CONFIG_GLOBAL_MOTION
5912#else
5913 (void)block;
5914#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005915
David Barker8dd9b572017-05-12 16:31:38 +01005916 // This function should only ever be called for compound modes
5917 assert(has_second_ref(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918
David Barker8dd9b572017-05-12 16:31:38 +01005919 struct buf_2d backup_yv12[MAX_MB_PLANE];
5920 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
5921 av1_get_scaled_ref_frame(cpi, other_ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005922
5923 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01005924 int i;
5925 // Swap out the reference frame for a version that's been scaled to
5926 // match the resolution of the current frame, allowing the existing
5927 // motion search code to be used without additional modifications.
5928 for (i = 0; i < MAX_MB_PLANE; i++)
5929 backup_yv12[i] = xd->plane[i].pre[!ref_idx];
5930 av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
5931 }
5932
5933// Since we have scaled the reference frames to match the size of the current
5934// frame we must use a unit scaling factor during mode selection.
5935#if CONFIG_HIGHBITDEPTH
5936 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5937 cm->height, cm->use_highbitdepth);
5938#else
5939 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5940 cm->height);
5941#endif // CONFIG_HIGHBITDEPTH
5942
5943 struct buf_2d ref_yv12;
5944
5945 const int plane = 0;
5946 ConvolveParams conv_params = get_conv_params(0, plane);
5947#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5948 WarpTypesAllowed warp_types;
5949#if CONFIG_GLOBAL_MOTION
5950 warp_types.global_warp_allowed = is_global;
5951#endif // CONFIG_GLOBAL_MOTION
5952#if CONFIG_WARPED_MOTION
5953 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5954#endif // CONFIG_WARPED_MOTION
5955#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5956
5957 // Initialized here because of compiler problem in Visual Studio.
5958 ref_yv12 = xd->plane[plane].pre[!ref_idx];
5959
5960// Get the prediction block from the 'other' reference frame.
5961#if CONFIG_HIGHBITDEPTH
5962 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5963 av1_highbd_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01005964 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
5965 0, interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01005966#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5967 &warp_types, p_col, p_row,
5968#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5969 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
5970 } else {
5971#endif // CONFIG_HIGHBITDEPTH
5972 av1_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01005973 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
5974 &conv_params, interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01005975#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5976 &warp_types, p_col, p_row, plane, !ref_idx,
5977#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5978 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
5979#if CONFIG_HIGHBITDEPTH
5980 }
5981#endif // CONFIG_HIGHBITDEPTH
5982
5983 if (scaled_ref_frame) {
5984 // Restore the prediction frame pointers to their unscaled versions.
5985 int i;
5986 for (i = 0; i < MAX_MB_PLANE; i++)
5987 xd->plane[i].pre[!ref_idx] = backup_yv12[i];
5988 }
5989}
5990
5991// Search for the best mv for one component of a compound,
5992// given that the other component is fixed.
5993static void compound_single_motion_search(
David Barkerf19f35f2017-05-22 16:33:22 +01005994 const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, MV *this_mv,
5995 int mi_row, int mi_col, const uint8_t *second_pred, const uint8_t *mask,
5996 int mask_stride, int *rate_mv, const int block, int ref_idx) {
David Barker8dd9b572017-05-12 16:31:38 +01005997 const int pw = block_size_wide[bsize];
5998 const int ph = block_size_high[bsize];
5999 MACROBLOCKD *xd = &x->e_mbd;
6000 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6001 const int ref = mbmi->ref_frame[ref_idx];
David Barkerf19f35f2017-05-22 16:33:22 +01006002 int_mv ref_mv = x->mbmi_ext->ref_mvs[ref][0];
David Barker8dd9b572017-05-12 16:31:38 +01006003 struct macroblockd_plane *const pd = &xd->plane[0];
6004
6005 struct buf_2d backup_yv12[MAX_MB_PLANE];
David Barker8dd9b572017-05-12 16:31:38 +01006006 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
6007 av1_get_scaled_ref_frame(cpi, ref);
6008
David Barker8dd9b572017-05-12 16:31:38 +01006009 // Check that this is either an interinter or an interintra block
6010 assert(has_second_ref(mbmi) ||
6011 (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
6012
David Barker8dd9b572017-05-12 16:31:38 +01006013 if (scaled_ref_frame) {
6014 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015 // Swap out the reference frame for a version that's been scaled to
6016 // match the resolution of the current frame, allowing the existing
6017 // motion search code to be used without additional modifications.
6018 for (i = 0; i < MAX_MB_PLANE; i++)
6019 backup_yv12[i] = xd->plane[i].pre[ref_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -07006020 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021 }
6022
David Barker8dd9b572017-05-12 16:31:38 +01006023 struct buf_2d orig_yv12;
6024 int bestsme = INT_MAX;
6025 int sadpb = x->sadperbit16;
6026 MV *const best_mv = &x->best_mv.as_mv;
6027 int search_range = 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006028
David Barker8dd9b572017-05-12 16:31:38 +01006029 MvLimits tmp_mv_limits = x->mv_limits;
David Barker8dd9b572017-05-12 16:31:38 +01006030
6031 // Initialized here because of compiler problem in Visual Studio.
6032 if (ref_idx) {
David Barkerf19f35f2017-05-22 16:33:22 +01006033 orig_yv12 = pd->pre[0];
6034 pd->pre[0] = pd->pre[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006035 }
6036
David Barker8dd9b572017-05-12 16:31:38 +01006037 // Do compound motion search on the current reference frame.
6038 av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
6039
6040 // Use the mv result from the single mode as mv predictor.
David Barkerf19f35f2017-05-22 16:33:22 +01006041 *best_mv = *this_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006042
6043 best_mv->col >>= 3;
6044 best_mv->row >>= 3;
6045
6046 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
6047
6048 // Small-range full-pixel motion search.
6049 bestsme = av1_refining_search_8p_c(x, sadpb, search_range,
6050 &cpi->fn_ptr[bsize], mask, mask_stride,
6051 ref_idx, &ref_mv.as_mv, second_pred);
6052 if (bestsme < INT_MAX) {
6053 if (mask)
6054 bestsme =
6055 av1_get_mvpred_mask_var(x, best_mv, &ref_mv.as_mv, second_pred, mask,
6056 mask_stride, ref_idx, &cpi->fn_ptr[bsize], 1);
6057 else
6058 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv.as_mv, second_pred,
6059 &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 }
6061
Alex Converse0fa0f422017-04-24 12:51:14 -07006062 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006063
6064 if (bestsme < INT_MAX) {
6065 int dis; /* TODO: use dis in distortion calculation later. */
David Barker8dd9b572017-05-12 16:31:38 +01006066 unsigned int sse;
6067 if (cpi->sf.use_upsampled_references) {
6068 // Use up-sampled reference frames.
6069 struct buf_2d backup_pred = pd->pre[0];
6070 const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006071
David Barker8dd9b572017-05-12 16:31:38 +01006072 // Set pred for Y plane
6073 setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
6074 upsampled_ref->y_crop_width,
6075 upsampled_ref->y_crop_height, upsampled_ref->y_stride,
6076 (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
6077 pd->subsampling_y);
6078
6079// If bsize < BLOCK_8X8, adjust pred pointer for this block
6080#if !CONFIG_CB4X4
6081 if (bsize < BLOCK_8X8)
6082 pd->pre[0].buf =
6083 &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
6084 pd->pre[0].stride))
6085 << 3];
6086#endif // !CONFIG_CB4X4
6087
6088 bestsme = cpi->find_fractional_mv_step(
6089 x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
6090 &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
6091 x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask,
6092 mask_stride, ref_idx, pw, ph, 1);
6093
6094 // Restore the reference frames.
6095 pd->pre[0] = backup_pred;
6096 } else {
6097 (void)block;
6098 bestsme = cpi->find_fractional_mv_step(
6099 x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
6100 &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
6101 x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask,
6102 mask_stride, ref_idx, pw, ph, 0);
6103 }
6104 }
6105
6106 // Restore the pointer to the first (possibly scaled) prediction buffer.
David Barkerf19f35f2017-05-22 16:33:22 +01006107 if (ref_idx) pd->pre[0] = orig_yv12;
David Barker8dd9b572017-05-12 16:31:38 +01006108
Yue Chenf03907a2017-05-31 12:04:04 -07006109 if (bestsme < INT_MAX) *this_mv = *best_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006110
6111 *rate_mv = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006112
6113 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01006114 // Restore the prediction frame pointers to their unscaled versions.
6115 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006116 for (i = 0; i < MAX_MB_PLANE; i++)
6117 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6118 }
David Barker8dd9b572017-05-12 16:31:38 +01006119
6120 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
David Barkerf19f35f2017-05-22 16:33:22 +01006121 *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmvjointcost,
6122 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123}
6124
David Barker8dd9b572017-05-12 16:31:38 +01006125// Wrapper for compound_single_motion_search, for the common case
6126// where the second prediction is also an inter mode.
6127static void compound_single_motion_search_interinter(
6128 const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *frame_mv,
David Barkerf19f35f2017-05-22 16:33:22 +01006129 int mi_row, int mi_col, const uint8_t *mask, int mask_stride, int *rate_mv,
6130 const int block, int ref_idx) {
6131 MACROBLOCKD *xd = &x->e_mbd;
6132 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6133
David Barker8dd9b572017-05-12 16:31:38 +01006134 // This function should only ever be called for compound modes
David Barkerf19f35f2017-05-22 16:33:22 +01006135 assert(has_second_ref(mbmi));
David Barker8dd9b572017-05-12 16:31:38 +01006136
6137// Prediction buffer from second frame.
6138#if CONFIG_HIGHBITDEPTH
David Barker8dd9b572017-05-12 16:31:38 +01006139 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
6140 uint8_t *second_pred;
6141 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6142 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
6143 else
6144 second_pred = (uint8_t *)second_pred_alloc_16;
6145#else
6146 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
6147#endif // CONFIG_HIGHBITDEPTH
6148
David Barkerf19f35f2017-05-22 16:33:22 +01006149 MV *this_mv = &frame_mv[mbmi->ref_frame[ref_idx]].as_mv;
6150 const MV *other_mv = &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv;
6151
6152 build_second_inter_pred(cpi, x, bsize, other_mv, mi_row, mi_col, block,
David Barker8dd9b572017-05-12 16:31:38 +01006153 ref_idx, second_pred);
6154
David Barkerf19f35f2017-05-22 16:33:22 +01006155 compound_single_motion_search(cpi, x, bsize, this_mv, mi_row, mi_col,
6156 second_pred, mask, mask_stride, rate_mv, block,
6157 ref_idx);
David Barker8dd9b572017-05-12 16:31:38 +01006158}
6159
6160#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08006161static void do_masked_motion_search_indexed(
David Barkerc155e012017-05-11 13:54:54 +01006162 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006163 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006164 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6166 MACROBLOCKD *xd = &x->e_mbd;
6167 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6168 BLOCK_SIZE sb_type = mbmi->sb_type;
6169 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006170 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08006171
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006172 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006173
David Barker8dd9b572017-05-12 16:31:38 +01006174 int_mv frame_mv[TOTAL_REFS_PER_FRAME];
6175 MV_REFERENCE_FRAME rf[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
6176 assert(bsize >= BLOCK_8X8 || CONFIG_CB4X4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006177
David Barker8dd9b572017-05-12 16:31:38 +01006178 frame_mv[rf[0]].as_int = cur_mv[0].as_int;
6179 frame_mv[rf[1]].as_int = cur_mv[1].as_int;
David Barkerf19f35f2017-05-22 16:33:22 +01006180 if (which == 0 || which == 1) {
6181 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv, mi_row,
6182 mi_col, mask, mask_stride, rate_mv,
6183 0, which);
6184 } else if (which == 2) {
David Barkerc155e012017-05-11 13:54:54 +01006185 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, mask,
6186 mask_stride, rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006187 }
David Barker8dd9b572017-05-12 16:31:38 +01006188 tmp_mv[0].as_int = frame_mv[rf[0]].as_int;
6189 tmp_mv[1].as_int = frame_mv[rf[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006191#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192#endif // CONFIG_EXT_INTER
6193
6194// In some situations we want to discount tha pparent cost of a new motion
6195// vector. Where there is a subtle motion field and especially where there is
6196// low spatial complexity then it can be hard to cover the cost of a new motion
6197// vector in a single block, even if that motion vector reduces distortion.
6198// However, once established that vector may be usable through the nearest and
6199// near mv modes to reduce distortion in subsequent blocks and also improve
6200// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006201static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 int_mv this_mv,
6203 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6204 int ref_frame) {
6205 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6206 (this_mv.as_int != 0) &&
6207 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6208 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6209 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6210 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6211}
6212
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006213#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6214#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006215
6216// TODO(jingning): this mv clamping function should be block size dependent.
6217static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6218 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6219 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6220 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6221 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6222}
6223
6224#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006225#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07006226static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 const BLOCK_SIZE bsize, const uint8_t *pred0,
6228 int stride0, const uint8_t *pred1, int stride1) {
6229 const struct macroblock_plane *const p = &x->plane[0];
6230 const uint8_t *src = p->src.buf;
6231 int src_stride = p->src.stride;
6232 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08006233 const int bw = block_size_wide[bsize];
6234 const int bh = block_size_high[bsize];
Yue Chenf03907a2017-05-31 12:04:04 -07006235 uint32_t esq[2][4];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006236 int64_t tl, br;
6237
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006238#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006239 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6240 pred0 = CONVERT_TO_BYTEPTR(pred0);
6241 pred1 = CONVERT_TO_BYTEPTR(pred1);
6242 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006243#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006244
Yue Chenf03907a2017-05-31 12:04:04 -07006245 cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6246 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2, stride0,
6247 &esq[0][1]);
6248 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6249 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6250 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6251 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6252 &esq[0][3]);
6253 cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6254 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2, stride1,
6255 &esq[1][1]);
6256 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6257 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6258 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6259 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6260 &esq[1][3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006261
6262 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6263 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6264 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6265 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6266 return (tl + br > 0);
6267}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006268#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006269#endif // CONFIG_EXT_INTER
6270
6271#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006272static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006273 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006274 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006275 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6276 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006277 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006278 const MACROBLOCKD *xd = &x->e_mbd;
6279 int bsl = mi_width_log2_lookup[bsize];
6280 int pred_filter_search =
6281 cpi->sf.cb_pred_filter_search
6282 ? (((mi_row + mi_col) >> bsl) +
6283 get_chessboard_index(cm->current_video_frame)) &
6284 0x1
6285 : 0;
6286 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6287 const int is_comp_pred = has_second_ref(mbmi);
6288 const int this_mode = mbmi->mode;
6289 int refs[2] = { mbmi->ref_frame[0],
6290 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006291 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006292 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6294 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6295
6296#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006297 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006298#else
6299 if ((this_mode != NEWMV) || (af == lf))
6300#endif // CONFIG_EXT_INTER
6301 best_filter = af;
6302 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006303 if (is_comp_pred) {
6304 if (cpi->sf.adaptive_mode_search) {
6305#if CONFIG_EXT_INTER
6306 switch (this_mode) {
6307 case NEAREST_NEARESTMV:
6308 if (single_filter[NEARESTMV][refs[0]] ==
6309 single_filter[NEARESTMV][refs[1]])
6310 best_filter = single_filter[NEARESTMV][refs[0]];
6311 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006312 case NEAR_NEARMV:
6313 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6314 best_filter = single_filter[NEARMV][refs[0]];
6315 break;
6316 case ZERO_ZEROMV:
6317 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
6318 best_filter = single_filter[ZEROMV][refs[0]];
6319 break;
6320 case NEW_NEWMV:
6321 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
6322 best_filter = single_filter[NEWMV][refs[0]];
6323 break;
6324 case NEAREST_NEWMV:
6325 if (single_filter[NEARESTMV][refs[0]] ==
6326 single_filter[NEWMV][refs[1]])
6327 best_filter = single_filter[NEARESTMV][refs[0]];
6328 break;
6329 case NEAR_NEWMV:
6330 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
6331 best_filter = single_filter[NEARMV][refs[0]];
6332 break;
6333 case NEW_NEARESTMV:
6334 if (single_filter[NEWMV][refs[0]] ==
6335 single_filter[NEARESTMV][refs[1]])
6336 best_filter = single_filter[NEWMV][refs[0]];
6337 break;
6338 case NEW_NEARMV:
6339 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
6340 best_filter = single_filter[NEWMV][refs[0]];
6341 break;
6342 default:
6343 if (single_filter[this_mode][refs[0]] ==
6344 single_filter[this_mode][refs[1]])
6345 best_filter = single_filter[this_mode][refs[0]];
6346 break;
6347 }
6348#else
6349 if (single_filter[this_mode][refs[0]] ==
6350 single_filter[this_mode][refs[1]])
6351 best_filter = single_filter[this_mode][refs[0]];
6352#endif // CONFIG_EXT_INTER
6353 }
6354 }
Angie Chiang75c22092016-10-25 12:19:16 -07006355 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
6356 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006357 }
6358 return best_filter;
6359}
Fergus Simpson4063a682017-02-28 16:52:22 -08006360#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006361
6362#if CONFIG_EXT_INTER
6363// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006364#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07006365static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006366 const BLOCK_SIZE bsize, const uint8_t *const p0,
6367 const uint8_t *const p1, int *const best_wedge_sign,
6368 int *const best_wedge_index) {
6369 const MACROBLOCKD *const xd = &x->e_mbd;
6370 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006371 const int bw = block_size_wide[bsize];
6372 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006373 const int N = bw * bh;
6374 int rate;
6375 int64_t dist;
6376 int64_t rd, best_rd = INT64_MAX;
6377 int wedge_index;
6378 int wedge_sign;
6379 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6380 const uint8_t *mask;
6381 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006382#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6384 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6385#else
6386 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006387#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006388
6389 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6390 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6391 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6392 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
6393
6394 int64_t sign_limit;
6395
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006396#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006397 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006398 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006399 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006400 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006401 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006402 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006403 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6404 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006405#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006406 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006407 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6408 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6409 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006410 }
6411
Yaowu Xuf883b422016-08-30 14:01:10 -07006412 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
6413 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07006414 (1 << WEDGE_WEIGHT_BITS) / 2;
6415
Jingning Han61418bb2017-01-23 17:12:48 -08006416 if (N < 64)
6417 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
6418 else
6419 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006420
6421 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006422 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08006423
6424 // TODO(jingning): Make sse2 functions support N = 16 case
6425 if (N < 64)
6426 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
6427 else
6428 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429
Yaowu Xuf883b422016-08-30 14:01:10 -07006430 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08006431 if (N < 64)
6432 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
6433 else
6434 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006435 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6436
6437 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6438 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6439
6440 if (rd < best_rd) {
6441 *best_wedge_index = wedge_index;
6442 *best_wedge_sign = wedge_sign;
6443 best_rd = rd;
6444 }
6445 }
6446
6447 return best_rd;
6448}
6449
6450// Choose the best wedge index the specified sign
6451static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07006452 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006453 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
6454 const int wedge_sign, int *const best_wedge_index) {
6455 const MACROBLOCKD *const xd = &x->e_mbd;
6456 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006457 const int bw = block_size_wide[bsize];
6458 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006459 const int N = bw * bh;
6460 int rate;
6461 int64_t dist;
6462 int64_t rd, best_rd = INT64_MAX;
6463 int wedge_index;
6464 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
6465 const uint8_t *mask;
6466 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006467#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006468 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6469 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6470#else
6471 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006472#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006473
6474 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6475 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6476
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006477#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006478 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006479 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006480 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07006481 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006482 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6483 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006484#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006485 {
Yaowu Xuf883b422016-08-30 14:01:10 -07006486 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6487 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006488 }
6489
6490 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006491 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08006492 if (N < 64)
6493 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
6494 else
6495 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006496 sse = ROUND_POWER_OF_TWO(sse, bd_round);
6497
6498 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6499 rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
6500
6501 if (rd < best_rd) {
6502 *best_wedge_index = wedge_index;
6503 best_rd = rd;
6504 }
6505 }
6506
6507 return best_rd;
6508}
6509
Yaowu Xuf883b422016-08-30 14:01:10 -07006510static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006511 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006512 const BLOCK_SIZE bsize,
6513 const uint8_t *const p0,
6514 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006515 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006516 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006517 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006518
6519 int64_t rd;
6520 int wedge_index = -1;
6521 int wedge_sign = 0;
6522
Sarah Parker42d96102017-01-31 21:05:27 -08006523 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07006524 assert(cpi->common.allow_masked_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006525
6526 if (cpi->sf.fast_wedge_sign_estimate) {
6527 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
6528 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
6529 } else {
6530 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
6531 }
6532
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006533 mbmi->wedge_sign = wedge_sign;
6534 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006535 return rd;
6536}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006537#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006538
Sarah Parker569edda2016-12-14 14:57:38 -08006539#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07006540static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006541 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07006542 const uint8_t *const p0,
6543 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006544 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08006545 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6546 const struct buf_2d *const src = &x->plane[0].src;
6547 const int bw = block_size_wide[bsize];
6548 const int bh = block_size_high[bsize];
6549 const int N = bw * bh;
6550 int rate;
6551 uint64_t sse;
6552 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07006553 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006554 SEG_MASK_TYPE cur_mask_type;
6555 int64_t best_rd = INT64_MAX;
6556 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006557#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08006558 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
6559 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
6560#else
6561 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006562#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08006563 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
6564 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
6565 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
6566
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006567#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08006568 if (hbd) {
6569 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
6570 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6571 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
6572 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
6573 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
6574 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
6575 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006576#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08006577 {
6578 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
6579 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
6580 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
6581 }
6582
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006583 // try each mask type and its inverse
6584 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08006585// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006586#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08006587 if (hbd)
6588 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006589 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08006590 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
6591 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006592#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006593 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
6594 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08006595
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006596 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006597 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006598 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08006599
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006600 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
6601 rd0 = RDCOST(x->rdmult, x->rddiv, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08006602
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006603 if (rd0 < best_rd) {
6604 best_mask_type = cur_mask_type;
6605 best_rd = rd0;
6606 }
6607 }
Sarah Parker569edda2016-12-14 14:57:38 -08006608
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006609 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006610 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006611#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08006612 if (hbd)
6613 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006614 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08006615 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
6616 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006617#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006618 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
6619 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08006620
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006621 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08006622}
6623#endif // CONFIG_COMPOUND_SEGMENT
6624
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006625#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07006626static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006627 const MACROBLOCK *const x,
6628 const BLOCK_SIZE bsize,
6629 const uint8_t *const p0,
6630 const uint8_t *const p1) {
6631 const MACROBLOCKD *const xd = &x->e_mbd;
6632 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6633
6634 int64_t rd;
6635 int wedge_index = -1;
6636
6637 assert(is_interintra_wedge_used(bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07006638 assert(cpi->common.allow_interintra_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006639
6640 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
6641
6642 mbmi->interintra_wedge_sign = 0;
6643 mbmi->interintra_wedge_index = wedge_index;
6644 return rd;
6645}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006646#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08006647
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006648#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006649static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07006650 const BLOCK_SIZE bsize,
6651 const uint8_t *const p0,
6652 const uint8_t *const p1) {
6653 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006654 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07006655 switch (compound_type) {
6656#if CONFIG_WEDGE
6657 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
6658#endif // CONFIG_WEDGE
6659#if CONFIG_COMPOUND_SEGMENT
6660 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
6661#endif // CONFIG_COMPOUND_SEGMENT
6662 default: assert(0); return 0;
6663 }
6664}
6665
David Barkerc155e012017-05-11 13:54:54 +01006666static int interinter_compound_motion_search(
6667 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
6668 const BLOCK_SIZE bsize, const int this_mode, int mi_row, int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006669 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08006670 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6671 int_mv tmp_mv[2];
David Barkerc155e012017-05-11 13:54:54 +01006672 int tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006673 const INTERINTER_COMPOUND_DATA compound_data = {
6674#if CONFIG_WEDGE
6675 mbmi->wedge_index,
6676 mbmi->wedge_sign,
6677#endif // CONFIG_WEDGE
6678#if CONFIG_COMPOUND_SEGMENT
6679 mbmi->mask_type,
6680 xd->seg_mask,
6681#endif // CONFIG_COMPOUND_SEGMENT
6682 mbmi->interinter_compound_type
6683 };
Sarah Parker6fdc8532016-11-16 17:47:13 -08006684 if (this_mode == NEW_NEWMV) {
David Barkerc155e012017-05-11 13:54:54 +01006685 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
6686 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006687 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6688 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6689 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
David Barkerc155e012017-05-11 13:54:54 +01006690 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
6691 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006692 mbmi->mv[0].as_int = tmp_mv[0].as_int;
6693 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
David Barkerc155e012017-05-11 13:54:54 +01006694 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
6695 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006696 mbmi->mv[1].as_int = tmp_mv[1].as_int;
6697 }
6698 return tmp_rate_mv;
6699}
6700
Sarah Parkerddcea392017-04-25 15:57:22 -07006701static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08006702 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
6703 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
6704 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
6705 int *strides, int mi_row, int mi_col) {
Debargha Mukherjeead8be032017-05-09 15:28:45 -07006706 const AV1_COMMON *const cm = &cpi->common;
Sarah Parker569edda2016-12-14 14:57:38 -08006707 MACROBLOCKD *xd = &x->e_mbd;
6708 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6709 int rate_sum;
6710 int64_t dist_sum;
6711 int64_t best_rd_cur = INT64_MAX;
6712 int64_t rd = INT64_MAX;
6713 int tmp_skip_txfm_sb;
6714 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00006715 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08006716
Sarah Parkerddcea392017-04-25 15:57:22 -07006717 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Sarah Parker569edda2016-12-14 14:57:38 -08006718 best_rd_cur += RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv, 0);
6719
Sarah Parker2e604882017-01-17 17:31:25 -08006720 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07006721 use_masked_motion_search(compound_type)) {
David Barkerc155e012017-05-11 13:54:54 +01006722 *out_rate_mv = interinter_compound_motion_search(cpi, x, cur_mv, bsize,
6723 this_mode, mi_row, mi_col);
Debargha Mukherjeead8be032017-05-09 15:28:45 -07006724 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006725 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
6726 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
6727 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08006728 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08006729 mbmi->mv[0].as_int = cur_mv[0].as_int;
6730 mbmi->mv[1].as_int = cur_mv[1].as_int;
6731 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00006732 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
6733#if CONFIG_SUPERTX
6734 0, 0,
6735#endif // CONFIG_SUPERTX
6736 preds0, strides, preds1,
6737 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006738 }
6739 av1_subtract_plane(x, bsize, 0);
6740 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6741 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6742 if (rd != INT64_MAX)
6743 rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
6744 best_rd_cur = rd;
6745
6746 } else {
David Barker426a9972017-01-27 11:03:11 +00006747 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
6748#if CONFIG_SUPERTX
6749 0, 0,
6750#endif // CONFIG_SUPERTX
6751 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08006752 av1_subtract_plane(x, bsize, 0);
6753 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
6754 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
6755 if (rd != INT64_MAX)
6756 rd = RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
6757 best_rd_cur = rd;
6758 }
6759 return best_rd_cur;
6760}
Sarah Parkerddcea392017-04-25 15:57:22 -07006761#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006762#endif // CONFIG_EXT_INTER
6763
Fergus Simpson073c6f32017-02-17 12:13:48 -08006764typedef struct {
6765#if CONFIG_MOTION_VAR
6766 // Inter prediction buffers and respective strides
6767 uint8_t *above_pred_buf[MAX_MB_PLANE];
6768 int above_pred_stride[MAX_MB_PLANE];
6769 uint8_t *left_pred_buf[MAX_MB_PLANE];
6770 int left_pred_stride[MAX_MB_PLANE];
6771#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006772 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08006773#if CONFIG_EXT_INTER
6774 // Pointer to array of motion vectors to use for each ref and their rates
6775 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006776 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08006777 // Pointer to array of predicted rate-distortion
6778 // Should point to first of 2 arrays in 2D array
6779 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08006780#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08006781 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08006782} HandleInterModeArgs;
6783
Fergus Simpson45509632017-02-22 15:30:50 -08006784static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
6785 const BLOCK_SIZE bsize,
6786 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
6787 const int mi_row, const int mi_col,
6788 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08006789 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08006790 const MACROBLOCKD *const xd = &x->e_mbd;
6791 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6792 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6793 const int is_comp_pred = has_second_ref(mbmi);
6794 const PREDICTION_MODE this_mode = mbmi->mode;
6795#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08006796 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
6797#endif // CONFIG_EXT_INTER
6798 int_mv *const frame_mv = mode_mv[this_mode];
6799 const int refs[2] = { mbmi->ref_frame[0],
6800 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
6801 int i;
6802
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08006803 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08006804
6805 if (is_comp_pred) {
6806#if CONFIG_EXT_INTER
6807 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006808 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08006809 }
6810
6811 if (this_mode == NEW_NEWMV) {
6812 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6813 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6814
6815 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
David Barkerc155e012017-05-11 13:54:54 +01006816 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, NULL,
6817 0, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08006818 } else {
6819 *rate_mv = 0;
6820 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07006821 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08006822 *rate_mv += av1_mv_bit_cost(
6823 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
6824 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6825 }
6826 }
6827 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
6828 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01006829 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6830 frame_mv[refs[0]].as_int =
6831 mode_mv[compound_ref0_mode(this_mode)][refs[0]].as_int;
David Barkerf19f35f2017-05-22 16:33:22 +01006832 compound_single_motion_search_interinter(
6833 cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, 0, rate_mv, 0, 1);
David Barker8dd9b572017-05-12 16:31:38 +01006834 } else {
6835 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
6836 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
6837 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
6838 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6839 }
Fergus Simpson45509632017-02-22 15:30:50 -08006840 } else {
David Barkercb03dc32017-04-07 13:05:09 +01006841 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08006842 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01006843 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
6844 frame_mv[refs[1]].as_int =
6845 mode_mv[compound_ref1_mode(this_mode)][refs[1]].as_int;
David Barkerf19f35f2017-05-22 16:33:22 +01006846 compound_single_motion_search_interinter(
6847 cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, 0, rate_mv, 0, 0);
David Barker8dd9b572017-05-12 16:31:38 +01006848 } else {
6849 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
6850 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
6851 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
6852 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6853 }
Fergus Simpson45509632017-02-22 15:30:50 -08006854 }
6855#else
6856 // Initialize mv using single prediction mode result.
6857 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
6858 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
6859
6860 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07006861 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08006862 } else {
6863 *rate_mv = 0;
6864 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07006865 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08006866 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
6867 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
6868 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
6869 }
6870 }
6871#endif // CONFIG_EXT_INTER
6872 } else {
6873#if CONFIG_EXT_INTER
6874 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006875 x->best_mv = args->single_newmv[refs[0]];
6876 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08006877 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006878 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
6879 args->single_newmv[refs[0]] = x->best_mv;
6880 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08006881 }
6882#else
6883 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
6884 single_newmv[refs[0]] = x->best_mv;
6885#endif // CONFIG_EXT_INTER
6886
6887 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
6888
6889 frame_mv[refs[0]] = x->best_mv;
6890 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
6891
6892 // Estimate the rate implications of a new mv but discount this
6893 // under certain circumstances where we want to help initiate a weak
6894 // motion field, where the distortion gain for a single block may not
6895 // be enough to overcome the cost of a new mv.
6896 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
6897 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
6898 }
6899 }
6900
6901 return 0;
6902}
6903
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006904int64_t interpolation_filter_search(
6905 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
6906 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
6907 BUFFER_SET *const orig_dst,
6908 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
6909 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
6910 int64_t *const skip_sse_sb) {
6911 const AV1_COMMON *cm = &cpi->common;
6912 MACROBLOCKD *const xd = &x->e_mbd;
6913 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
6914 int i;
6915 int tmp_rate;
6916 int64_t tmp_dist;
6917
6918 (void)single_filter;
6919
6920 InterpFilter assign_filter = SWITCHABLE;
6921
6922 if (cm->interp_filter == SWITCHABLE) {
6923#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07006924 assign_filter = av1_is_interp_needed(xd)
6925 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
6926 single_filter)
6927 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006928#endif // !CONFIG_DUAL_FILTER
6929 } else {
6930 assign_filter = cm->interp_filter;
6931 }
6932
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07006933 set_default_interp_filters(mbmi, assign_filter);
6934
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006935 *switchable_rate = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07006936 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006937 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
6938 skip_txfm_sb, skip_sse_sb);
6939 *rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
6940
6941 if (assign_filter == SWITCHABLE) {
6942 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07006943 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006944#if CONFIG_DUAL_FILTER
6945 const int filter_set_size = DUAL_FILTER_SET_SIZE;
6946#else
6947 const int filter_set_size = SWITCHABLE_FILTERS;
6948#endif // CONFIG_DUAL_FILTER
6949 int best_in_temp = 0;
6950#if CONFIG_DUAL_FILTER
6951 InterpFilter best_filter[4];
6952 av1_copy(best_filter, mbmi->interp_filter);
6953#else
6954 InterpFilter best_filter = mbmi->interp_filter;
6955#endif // CONFIG_DUAL_FILTER
6956 restore_dst_buf(xd, *tmp_dst);
6957 // EIGHTTAP_REGULAR mode is calculated beforehand
6958 for (i = 1; i < filter_set_size; ++i) {
6959 int tmp_skip_sb = 0;
6960 int64_t tmp_skip_sse = INT64_MAX;
6961 int tmp_rs;
6962 int64_t tmp_rd;
6963#if CONFIG_DUAL_FILTER
6964 mbmi->interp_filter[0] = filter_sets[i][0];
6965 mbmi->interp_filter[1] = filter_sets[i][1];
6966 mbmi->interp_filter[2] = filter_sets[i][0];
6967 mbmi->interp_filter[3] = filter_sets[i][1];
6968#else
6969 mbmi->interp_filter = (InterpFilter)i;
6970#endif // CONFIG_DUAL_FILTER
6971 tmp_rs = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07006972 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08006973 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
6974 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
6975 tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
6976
6977 if (tmp_rd < *rd) {
6978 *rd = tmp_rd;
6979 *switchable_rate = av1_get_switchable_rate(cpi, xd);
6980#if CONFIG_DUAL_FILTER
6981 av1_copy(best_filter, mbmi->interp_filter);
6982#else
6983 best_filter = mbmi->interp_filter;
6984#endif // CONFIG_DUAL_FILTER
6985 *skip_txfm_sb = tmp_skip_sb;
6986 *skip_sse_sb = tmp_skip_sse;
6987 best_in_temp = !best_in_temp;
6988 if (best_in_temp) {
6989 restore_dst_buf(xd, *orig_dst);
6990 } else {
6991 restore_dst_buf(xd, *tmp_dst);
6992 }
6993 }
6994 }
6995 if (best_in_temp) {
6996 restore_dst_buf(xd, *tmp_dst);
6997 } else {
6998 restore_dst_buf(xd, *orig_dst);
6999 }
7000#if CONFIG_DUAL_FILTER
7001 av1_copy(mbmi->interp_filter, best_filter);
7002#else
7003 mbmi->interp_filter = best_filter;
7004#endif // CONFIG_DUAL_FILTER
7005 } else {
7006#if CONFIG_DUAL_FILTER
7007 for (i = 0; i < 4; ++i)
7008 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
7009#else
7010 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
7011#endif // CONFIG_DUAL_FILTER
7012 }
7013 }
7014
7015 return 0;
7016}
7017
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007018// TODO(afergs): Refactor the MBMI references in here - there's four
7019// TODO(afergs): Refactor optional args - add them to a struct or remove
7020static int64_t motion_mode_rd(
7021 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
7022 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
7023 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
7024 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
7025 const int *refs, int rate_mv,
7026#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007027 int_mv *const single_newmv,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007028#if CONFIG_EXT_INTER
7029 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
7030#if CONFIG_MOTION_VAR
7031 int rate_mv_bmc,
7032#endif // CONFIG_MOTION_VAR
7033#endif // CONFIG_EXT_INTER
7034#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7035 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
7036 const AV1_COMMON *const cm = &cpi->common;
7037 MACROBLOCKD *xd = &x->e_mbd;
7038 MODE_INFO *mi = xd->mi[0];
7039 MB_MODE_INFO *mbmi = &mi->mbmi;
7040 const int is_comp_pred = has_second_ref(mbmi);
7041 const PREDICTION_MODE this_mode = mbmi->mode;
7042
7043 (void)mode_mv;
7044 (void)mi_row;
7045 (void)mi_col;
7046 (void)args;
7047 (void)refs;
7048 (void)rate_mv;
7049 (void)is_comp_pred;
7050 (void)this_mode;
7051
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007052#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7053 MOTION_MODE motion_mode, last_motion_mode_allowed;
7054 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7055 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
7056 MB_MODE_INFO base_mbmi, best_mbmi;
7057#if CONFIG_VAR_TX
7058 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7059#endif // CONFIG_VAR_TX
7060#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7061
7062#if CONFIG_WARPED_MOTION
7063 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
7064#endif // CONFIG_WARPED_MOTION
7065
7066#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7067 av1_invalid_rd_stats(&best_rd_stats);
7068#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7069
7070 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
7071#if CONFIG_WARPED_MOTION
7072 aom_clear_system_state();
7073 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
7074#if CONFIG_EXT_INTER
7075 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
7076#endif // CONFIG_EXT_INTER
7077#endif // CONFIG_WARPED_MOTION
7078#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7079 rate2_nocoeff = rd_stats->rate;
7080 last_motion_mode_allowed = motion_mode_allowed(
7081#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7082 0, xd->global_motion,
7083#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7084 mi);
7085 base_mbmi = *mbmi;
7086#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7087
7088#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7089 int64_t best_rd = INT64_MAX;
7090 for (motion_mode = SIMPLE_TRANSLATION;
7091 motion_mode <= last_motion_mode_allowed; motion_mode++) {
7092 int64_t tmp_rd = INT64_MAX;
7093 int tmp_rate;
7094 int64_t tmp_dist;
7095#if CONFIG_EXT_INTER
7096 int tmp_rate2 =
7097 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
7098#else
7099 int tmp_rate2 = rate2_nocoeff;
7100#endif // CONFIG_EXT_INTER
7101
7102 *mbmi = base_mbmi;
7103 mbmi->motion_mode = motion_mode;
7104#if CONFIG_MOTION_VAR
7105 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007106#if CONFIG_EXT_INTER
7107 *mbmi = *best_bmc_mbmi;
7108 mbmi->motion_mode = OBMC_CAUSAL;
7109#endif // CONFIG_EXT_INTER
7110 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
7111 int tmp_rate_mv = 0;
7112
7113 single_motion_search(cpi, x, bsize, mi_row, mi_col,
7114#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07007115 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007116#endif // CONFIG_EXT_INTER
7117 &tmp_rate_mv);
7118 mbmi->mv[0].as_int = x->best_mv.as_int;
7119 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7120 refs[0])) {
7121 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7122 }
7123#if CONFIG_EXT_INTER
7124 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7125#else
7126 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7127#endif // CONFIG_EXT_INTER
7128#if CONFIG_DUAL_FILTER
7129 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7130 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7131 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7132 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7133#endif // CONFIG_DUAL_FILTER
Jingning Hanc44009c2017-05-06 11:36:49 -07007134 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007135#if CONFIG_EXT_INTER
7136 } else {
Jingning Hanc44009c2017-05-06 11:36:49 -07007137 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007138#endif // CONFIG_EXT_INTER
7139 }
7140 av1_build_obmc_inter_prediction(
7141 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
7142 args->left_pred_buf, args->left_pred_stride);
7143 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7144 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7145 }
7146#endif // CONFIG_MOTION_VAR
7147
7148#if CONFIG_WARPED_MOTION
7149 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007150#if CONFIG_EXT_INTER
7151 *mbmi = *best_bmc_mbmi;
7152 mbmi->motion_mode = WARPED_CAUSAL;
7153#endif // CONFIG_EXT_INTER
7154 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
7155#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07007156 for (int dir = 0; dir < 4; ++dir)
7157 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
7158 ? EIGHTTAP_REGULAR
7159 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007160#else
7161 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
7162 : cm->interp_filter;
7163#endif // CONFIG_DUAL_FILTER
7164
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007165 if (!find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
7166 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
7167 &mbmi->wm_params[0], mi_row, mi_col)) {
7168 // Refine MV for NEWMV mode
7169 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
7170 int tmp_rate_mv = 0;
7171 const int_mv mv0 = mbmi->mv[0];
7172 WarpedMotionParams wm_params0 = mbmi->wm_params[0];
7173
7174 // Refine MV in a small range.
7175 av1_refine_warped_mv(cpi, x, bsize, mi_row, mi_col, pts, pts_inref);
7176
7177 // Keep the refined MV and WM parameters.
7178 if (mv0.as_int != mbmi->mv[0].as_int) {
7179 const int ref = refs[0];
7180 const MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7181
7182 tmp_rate_mv =
7183 av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv, x->nmvjointcost,
7184 x->mvcost, MV_COST_WEIGHT);
7185
7186 if (cpi->sf.adaptive_motion_search)
7187 x->pred_mv[ref] = mbmi->mv[0].as_mv;
7188
7189 single_newmv[ref] = mbmi->mv[0];
7190
7191 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7192 refs[0])) {
7193 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7194 }
7195#if CONFIG_EXT_INTER
7196 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7197#else
7198 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7199#endif // CONFIG_EXT_INTER
7200#if CONFIG_DUAL_FILTER
7201 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7202 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7203 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7204 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7205#endif // CONFIG_DUAL_FILTER
7206 } else {
7207 // Restore the old MV and WM parameters.
7208 mbmi->mv[0] = mv0;
7209 mbmi->wm_params[0] = wm_params0;
7210 }
7211 }
7212
Jingning Hanc44009c2017-05-06 11:36:49 -07007213 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007214 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7215 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7216 } else {
7217 continue;
7218 }
7219 }
7220#endif // CONFIG_WARPED_MOTION
7221 x->skip = 0;
7222
7223 rd_stats->dist = 0;
7224 rd_stats->sse = 0;
7225 rd_stats->skip = 1;
7226 rd_stats->rate = tmp_rate2;
7227 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
7228#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7229 if (last_motion_mode_allowed == WARPED_CAUSAL)
7230#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7231 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7232#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7233 else
7234 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
7235#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7236 }
7237#if CONFIG_WARPED_MOTION
7238 if (mbmi->motion_mode == WARPED_CAUSAL) {
7239 rd_stats->rate -= rs;
7240 }
7241#endif // CONFIG_WARPED_MOTION
7242#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7243 if (!*skip_txfm_sb) {
7244 int64_t rdcosty = INT64_MAX;
7245 int is_cost_valid_uv = 0;
7246
7247 // cost and distortion
7248 av1_subtract_plane(x, bsize, 0);
7249#if CONFIG_VAR_TX
7250 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
7251 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
7252 } else {
7253 int idx, idy;
7254 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
7255 for (idy = 0; idy < xd->n8_h; ++idy)
7256 for (idx = 0; idx < xd->n8_w; ++idx)
7257 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
7258 memset(x->blk_skip[0], rd_stats_y->skip,
7259 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7260 }
7261#else
7262 /* clang-format off */
7263 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
7264/* clang-format on */
7265#endif // CONFIG_VAR_TX
7266
7267 if (rd_stats_y->rate == INT_MAX) {
7268 av1_invalid_rd_stats(rd_stats);
7269#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7270 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
7271 continue;
7272 } else {
7273#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7274 restore_dst_buf(xd, *orig_dst);
7275 return INT64_MAX;
7276#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7277 }
7278#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7279 }
7280
7281 av1_merge_rd_stats(rd_stats, rd_stats_y);
7282
7283 rdcosty = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7284 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, rd_stats->sse));
7285/* clang-format off */
7286#if CONFIG_VAR_TX
7287 is_cost_valid_uv =
7288 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
7289#else
7290 is_cost_valid_uv =
7291 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
7292#endif // CONFIG_VAR_TX
7293 if (!is_cost_valid_uv) {
7294#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7295 continue;
7296#else
7297 restore_dst_buf(xd, *orig_dst);
7298 return INT64_MAX;
7299#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7300 }
7301 /* clang-format on */
7302 av1_merge_rd_stats(rd_stats, rd_stats_uv);
7303#if CONFIG_RD_DEBUG
7304 // record transform block coefficient cost
7305 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
7306 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
7307 // here because we already collect the coefficient cost. Move this part to
7308 // other place when we need to compare non-coefficient cost.
7309 mbmi->rd_stats = *rd_stats;
7310#endif // CONFIG_RD_DEBUG
7311#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7312 if (rd_stats->skip) {
7313 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7314 rd_stats_y->rate = 0;
7315 rd_stats_uv->rate = 0;
7316 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7317 mbmi->skip = 0;
7318 // here mbmi->skip temporarily plays a role as what this_skip2 does
7319 } else if (!xd->lossless[mbmi->segment_id] &&
7320 (RDCOST(x->rdmult, x->rddiv,
7321 rd_stats_y->rate + rd_stats_uv->rate +
7322 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
7323 rd_stats->dist) >=
7324 RDCOST(x->rdmult, x->rddiv,
7325 av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
7326 rd_stats->sse))) {
7327 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
7328 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7329 rd_stats->dist = rd_stats->sse;
7330 rd_stats_y->rate = 0;
7331 rd_stats_uv->rate = 0;
7332 mbmi->skip = 1;
7333 } else {
7334 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
7335 mbmi->skip = 0;
7336 }
7337 *disable_skip = 0;
7338#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7339 } else {
7340 x->skip = 1;
7341 *disable_skip = 1;
7342 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
7343
7344// The cost of skip bit needs to be added.
7345#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7346 mbmi->skip = 0;
7347#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7348 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7349
7350 rd_stats->dist = *skip_sse_sb;
7351 rd_stats->sse = *skip_sse_sb;
7352 rd_stats_y->rate = 0;
7353 rd_stats_uv->rate = 0;
7354 rd_stats->skip = 1;
7355 }
7356
7357#if CONFIG_GLOBAL_MOTION
7358 if (this_mode == ZEROMV
7359#if CONFIG_EXT_INTER
7360 || this_mode == ZERO_ZEROMV
7361#endif // CONFIG_EXT_INTER
7362 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007363 if (is_nontrans_global_motion(xd)) {
7364 rd_stats->rate -= rs;
7365#if CONFIG_DUAL_FILTER
7366 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
7367 ? EIGHTTAP_REGULAR
7368 : cm->interp_filter;
7369 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
7370 ? EIGHTTAP_REGULAR
7371 : cm->interp_filter;
7372#else
7373 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
7374 ? EIGHTTAP_REGULAR
7375 : cm->interp_filter;
7376#endif // CONFIG_DUAL_FILTER
7377 }
7378 }
7379#endif // CONFIG_GLOBAL_MOTION
7380
7381#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7382 tmp_rd = RDCOST(x->rdmult, x->rddiv, rd_stats->rate, rd_stats->dist);
7383 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
7384 best_mbmi = *mbmi;
7385 best_rd = tmp_rd;
7386 best_rd_stats = *rd_stats;
7387 best_rd_stats_y = *rd_stats_y;
7388 best_rd_stats_uv = *rd_stats_uv;
7389#if CONFIG_VAR_TX
7390 for (int i = 0; i < MAX_MB_PLANE; ++i)
7391 memcpy(best_blk_skip[i], x->blk_skip[i],
7392 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7393#endif // CONFIG_VAR_TX
7394 best_xskip = x->skip;
7395 best_disable_skip = *disable_skip;
7396 }
7397 }
7398
7399 if (best_rd == INT64_MAX) {
7400 av1_invalid_rd_stats(rd_stats);
7401 restore_dst_buf(xd, *orig_dst);
7402 return INT64_MAX;
7403 }
7404 *mbmi = best_mbmi;
7405 *rd_stats = best_rd_stats;
7406 *rd_stats_y = best_rd_stats_y;
7407 *rd_stats_uv = best_rd_stats_uv;
7408#if CONFIG_VAR_TX
7409 for (int i = 0; i < MAX_MB_PLANE; ++i)
7410 memcpy(x->blk_skip[i], best_blk_skip[i],
7411 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
7412#endif // CONFIG_VAR_TX
7413 x->skip = best_xskip;
7414 *disable_skip = best_disable_skip;
7415#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7416
7417 restore_dst_buf(xd, *orig_dst);
7418 return 0;
7419}
7420
Yaowu Xuc27fc142016-08-22 16:08:15 -07007421static int64_t handle_inter_mode(
Angie Chiang76159122016-11-09 12:13:22 -08007422 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
7423 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007424 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007425 int mi_col, HandleInterModeArgs *args, const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07007426 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007427 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007428 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08007429 MODE_INFO *mi = xd->mi[0];
7430 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007431 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7432 const int is_comp_pred = has_second_ref(mbmi);
7433 const int this_mode = mbmi->mode;
7434 int_mv *frame_mv = mode_mv[this_mode];
7435 int i;
7436 int refs[2] = { mbmi->ref_frame[0],
7437 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
7438 int_mv cur_mv[2];
7439 int rate_mv = 0;
7440#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07007441 int pred_exists = 1;
Yue Chen5e606542017-05-24 17:03:17 -07007442#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Jingning Hanae5cfde2016-11-30 12:01:44 -08007443 const int bw = block_size_wide[bsize];
Yue Chen5e606542017-05-24 17:03:17 -07007444#endif // ONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007445 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007446#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007447 const unsigned int *const interintra_mode_cost =
7448 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007449#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007450 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07007451 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08007452#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007453 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007454#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007455#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007456 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
7457#else
7458 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007459#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007460 uint8_t *tmp_buf;
7461
Yue Chencb60b182016-10-13 15:18:22 -07007462#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007463#if CONFIG_EXT_INTER
7464 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007465 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07007466#if CONFIG_MOTION_VAR
7467 int rate_mv_bmc;
7468#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07007469#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07007470#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07007471 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00007472 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007473 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007474
7475 int skip_txfm_sb = 0;
7476 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08007477 int16_t mode_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007478
7479#if CONFIG_EXT_INTER
Yue Chen5e606542017-05-24 17:03:17 -07007480#if CONFIG_INTERINTRA
7481 int compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007482 mbmi->use_wedge_interintra = 0;
Yue Chen5e606542017-05-24 17:03:17 -07007483#endif
7484#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
7485 int compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007486 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yue Chen5e606542017-05-24 17:03:17 -07007487#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07007488
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007489#if CONFIG_INTERINTRA
7490 if (!cm->allow_interintra_compound && is_comp_interintra_pred)
7491 return INT64_MAX;
7492#endif // CONFIG_INTERINTRA
7493
Yaowu Xuc27fc142016-08-22 16:08:15 -07007494 // is_comp_interintra_pred implies !is_comp_pred
7495 assert(!is_comp_interintra_pred || (!is_comp_pred));
7496 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
7497 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
7498#endif // CONFIG_EXT_INTER
7499
Yaowu Xuc27fc142016-08-22 16:08:15 -07007500#if CONFIG_EXT_INTER
7501 if (is_comp_pred)
7502 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
7503 else
7504#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07007505 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
7506 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007507
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007508#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007509 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7510 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
7511 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007512#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007513 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00007514 // Make sure that we didn't leave the plane destination buffers set
7515 // to tmp_buf at the end of the last iteration
7516 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007517
Yue Chen69f18e12016-09-08 14:48:15 -07007518#if CONFIG_WARPED_MOTION
7519 mbmi->num_proj_ref[0] = 0;
7520 mbmi->num_proj_ref[1] = 0;
7521#endif // CONFIG_WARPED_MOTION
7522
Yaowu Xuc27fc142016-08-22 16:08:15 -07007523 if (is_comp_pred) {
7524 if (frame_mv[refs[0]].as_int == INVALID_MV ||
7525 frame_mv[refs[1]].as_int == INVALID_MV)
7526 return INT64_MAX;
7527 }
7528
Yue Chene9638cc2016-10-10 12:37:54 -07007529 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007530 if (have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson45509632017-02-22 15:30:50 -08007531 const int64_t ret_val = handle_newmv(cpi, x, bsize, mode_mv, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007532 &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08007533 if (ret_val != 0)
7534 return ret_val;
7535 else
7536 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007537 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007538 for (i = 0; i < is_comp_pred + 1; ++i) {
7539 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07007540 // Clip "next_nearest" so that it does not extend to far out of image
7541 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007542 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007543 mbmi->mv[i].as_int = cur_mv[i].as_int;
7544 }
7545
Yaowu Xuc27fc142016-08-22 16:08:15 -07007546#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007547 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007548#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08007549 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07007550#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08007551 {
7552#if !CONFIG_EXT_INTER
7553 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08007554#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007555 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
7556 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7557 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7558
7559 for (i = 0; i < 2; ++i) {
7560 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007561 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007562 mbmi->mv[i].as_int = cur_mv[i].as_int;
7563 }
7564 }
7565 }
7566
7567#if CONFIG_EXT_INTER
7568 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07007569 if (this_mode == NEAREST_NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007570 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
7571
7572 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7573 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007574 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007575 mbmi->mv[0].as_int = cur_mv[0].as_int;
7576 }
7577
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07007578 if (this_mode == NEW_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007579 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
7580
7581 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7582 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007583 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007584 mbmi->mv[1].as_int = cur_mv[1].as_int;
7585 }
7586 }
7587
7588 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01007589 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07007590 if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01007591 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007592
7593 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
7594 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007595 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007596 mbmi->mv[0].as_int = cur_mv[0].as_int;
7597 }
7598
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07007599 if (this_mode == NEW_NEARMV || this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01007600 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007601
7602 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
7603 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007604 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007605 mbmi->mv[1].as_int = cur_mv[1].as_int;
7606 }
7607 }
7608#else
7609 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007610 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007611 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
7612 int ref_mv_idx = mbmi->ref_mv_idx + 1;
7613 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
7614 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
7615
7616 for (i = 0; i < 2; ++i) {
7617 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07007618 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007619 mbmi->mv[i].as_int = cur_mv[i].as_int;
7620 }
7621 }
7622 }
7623#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007624
7625 // do first prediction into the destination buffer. Do the next
7626 // prediction into a temporary buffer. Then keep track of which one
7627 // of these currently holds the best predictor, and use the other
7628 // one for future predictions. In the end, copy from tmp_buf to
7629 // dst if necessary.
7630 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007631 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
7632 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07007633 }
7634 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00007635 orig_dst.plane[i] = xd->plane[i].dst.buf;
7636 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007637 }
7638
7639 // We don't include the cost of the second reference here, because there
7640 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
7641 // words if you present them in that order, the second one is always known
7642 // if the first is known.
7643 //
7644 // Under some circumstances we discount the cost of new mv mode to encourage
7645 // initiation of a motion field.
7646 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
7647 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01007648#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08007649 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01007650 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7651 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
7652 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007653#else
Angie Chiang76159122016-11-09 12:13:22 -08007654 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
7655 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02007656#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007657 } else {
Angie Chiang76159122016-11-09 12:13:22 -08007658 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007659 }
7660
Angie Chiang76159122016-11-09 12:13:22 -08007661 if (RDCOST(x->rdmult, x->rddiv, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07007662#if CONFIG_EXT_INTER
7663 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
7664#else
7665 mbmi->mode != NEARESTMV
7666#endif // CONFIG_EXT_INTER
7667 )
7668 return INT64_MAX;
7669
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007670 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007671 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
7672 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007673 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007674
Yaowu Xuc27fc142016-08-22 16:08:15 -07007675#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07007676#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007677 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08007678 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007679 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07007680#if CONFIG_MOTION_VAR
7681 rate_mv_bmc = rate_mv;
Yue Chencb60b182016-10-13 15:18:22 -07007682#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07007683#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07007684
Yue Chen5e606542017-05-24 17:03:17 -07007685#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08007686 if (is_comp_pred) {
Urvang Joshi368fbc92016-10-17 16:31:34 -07007687 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007688 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007689 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
7690 INTERINTER_COMPOUND_DATA best_compound_data;
7691 int_mv best_mv[2];
7692 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007693 int tmp_skip_txfm_sb;
7694 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07007695 int compound_type_cost[COMPOUND_TYPES];
Sarah Parker6fdc8532016-11-16 17:47:13 -08007696 uint8_t pred0[2 * MAX_SB_SQUARE];
7697 uint8_t pred1[2 * MAX_SB_SQUARE];
7698 uint8_t *preds0[1] = { pred0 };
7699 uint8_t *preds1[1] = { pred1 };
7700 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08007701 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08007702 int masked_compound_used = is_any_masked_compound_used(bsize);
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007703#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
7704 masked_compound_used = masked_compound_used && cm->allow_masked_compound;
7705#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08007706 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007707
Sarah Parker6fdc8532016-11-16 17:47:13 -08007708 best_mv[0].as_int = cur_mv[0].as_int;
7709 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007710 memset(&best_compound_data, 0, sizeof(best_compound_data));
7711#if CONFIG_COMPOUND_SEGMENT
7712 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
7713 best_compound_data.seg_mask = tmp_mask_buf;
7714#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007715
Sarah Parker42d96102017-01-31 21:05:27 -08007716 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07007717 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
7718 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007719 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07007720 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007721 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07007722 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007723 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007724 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007725
Sarah Parker6fdc8532016-11-16 17:47:13 -08007726 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007727 if (cur_type != COMPOUND_AVERAGE && !masked_compound_used) break;
Yue Chene2518252017-06-05 12:36:46 -07007728 if (!is_interinter_compound_used(cur_type, bsize)) continue;
Sarah Parker2e604882017-01-17 17:31:25 -08007729 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007730 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007731 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007732 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007733 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08007734 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007735 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08007736 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007737
Sarah Parker6fdc8532016-11-16 17:47:13 -08007738 switch (cur_type) {
7739 case COMPOUND_AVERAGE:
Jingning Hanc44009c2017-05-06 11:36:49 -07007740 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
7741 bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007742 av1_subtract_plane(x, bsize, 0);
7743 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7744 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
7745 INT64_MAX);
7746 if (rd != INT64_MAX)
Sarah Parker2e604882017-01-17 17:31:25 -08007747 best_rd_cur =
Sarah Parker6fdc8532016-11-16 17:47:13 -08007748 RDCOST(x->rdmult, x->rddiv, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08007749 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007750 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007751#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08007752 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08007753 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7754 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07007755 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00007756 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
7757 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007758 }
7759 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007760#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08007761#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08007762 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08007763 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
7764 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07007765 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007766 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
7767 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08007768 }
7769 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08007770#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08007771 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007772 }
Sarah Parker2e604882017-01-17 17:31:25 -08007773
7774 if (best_rd_cur < best_rd_compound) {
7775 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007776#if CONFIG_WEDGE
7777 best_compound_data.wedge_index = mbmi->wedge_index;
7778 best_compound_data.wedge_sign = mbmi->wedge_sign;
7779#endif // CONFIG_WEDGE
7780#if CONFIG_COMPOUND_SEGMENT
7781 best_compound_data.mask_type = mbmi->mask_type;
7782 memcpy(best_compound_data.seg_mask, xd->seg_mask,
7783 2 * MAX_SB_SQUARE * sizeof(uint8_t));
7784#endif // CONFIG_COMPOUND_SEGMENT
7785 best_compound_data.interinter_compound_type =
7786 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08007787 if (have_newmv_in_inter_mode(this_mode)) {
7788 if (use_masked_motion_search(cur_type)) {
7789 best_tmp_rate_mv = tmp_rate_mv;
7790 best_mv[0].as_int = mbmi->mv[0].as_int;
7791 best_mv[1].as_int = mbmi->mv[1].as_int;
7792 } else {
7793 best_mv[0].as_int = cur_mv[0].as_int;
7794 best_mv[1].as_int = cur_mv[1].as_int;
7795 }
7796 }
7797 }
7798 // reset to original mvs for next iteration
7799 mbmi->mv[0].as_int = cur_mv[0].as_int;
7800 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007801 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007802#if CONFIG_WEDGE
7803 mbmi->wedge_index = best_compound_data.wedge_index;
7804 mbmi->wedge_sign = best_compound_data.wedge_sign;
7805#endif // CONFIG_WEDGE
7806#if CONFIG_COMPOUND_SEGMENT
7807 mbmi->mask_type = best_compound_data.mask_type;
7808 memcpy(xd->seg_mask, best_compound_data.seg_mask,
7809 2 * MAX_SB_SQUARE * sizeof(uint8_t));
7810#endif // CONFIG_COMPOUND_SEGMENT
7811 mbmi->interinter_compound_type =
7812 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007813 if (have_newmv_in_inter_mode(this_mode)) {
7814 mbmi->mv[0].as_int = best_mv[0].as_int;
7815 mbmi->mv[1].as_int = best_mv[1].as_int;
7816 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
7817 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007818 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007819 rd_stats->rate += best_tmp_rate_mv - rate_mv;
7820 rate_mv = best_tmp_rate_mv;
7821 }
7822 }
7823
7824 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00007825 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007826 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00007827 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07007828
7829 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007830
Yue Chen5e606542017-05-24 17:03:17 -07007831 compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08007832 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007833 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01007834 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007835 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01007836 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007837 }
Yue Chen5e606542017-05-24 17:03:17 -07007838#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07007839
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007840#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007841 if (is_comp_interintra_pred) {
7842 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
7843 int64_t best_interintra_rd = INT64_MAX;
7844 int rmode, rate_sum;
7845 int64_t dist_sum;
7846 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007847 int tmp_rate_mv = 0;
7848 int tmp_skip_txfm_sb;
7849 int64_t tmp_skip_sse_sb;
7850 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
7851 uint8_t *intrapred;
7852
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007853#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007854 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
7855 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
7856 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007857#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007858 intrapred = intrapred_;
7859
Emil Keyder01770b32017-01-20 18:03:11 -05007860 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007861 for (j = 0; j < MAX_MB_PLANE; j++) {
7862 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
7863 xd->plane[j].dst.stride = bw;
7864 }
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007865 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst, bsize);
David Barkerac37fa32016-12-02 12:30:21 +00007866 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007867 mbmi->ref_frame[1] = INTRA_FRAME;
7868 mbmi->use_wedge_interintra = 0;
7869
7870 for (j = 0; j < INTERINTRA_MODES; ++j) {
7871 mbmi->interintra_mode = (INTERINTRA_MODE)j;
7872 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00007873 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
7874 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07007875 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007876 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7877 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Yue Chenf03907a2017-05-31 12:04:04 -07007878 rd =
7879 RDCOST(x->rdmult, x->rddiv, tmp_rate_mv + rate_sum + rmode, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007880 if (rd < best_interintra_rd) {
7881 best_interintra_rd = rd;
7882 best_interintra_mode = mbmi->interintra_mode;
7883 }
7884 }
7885 mbmi->interintra_mode = best_interintra_mode;
7886 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00007887 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
7888 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07007889 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
7890 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007891 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7892 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7893 if (rd != INT64_MAX)
7894 rd = RDCOST(x->rdmult, x->rddiv, rate_mv + rmode + rate_sum, dist_sum);
7895 best_interintra_rd = rd;
7896
7897 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00007898 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07007899 return INT64_MAX;
7900 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007901#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007902 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007903 int64_t best_interintra_rd_nowedge = INT64_MAX;
7904 int64_t best_interintra_rd_wedge = INT64_MAX;
7905 int_mv tmp_mv;
7906 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007907 if (rd != INT64_MAX)
7908 rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
7909 dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07007910 best_interintra_rd_nowedge = best_interintra_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007911
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007912 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07007913 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
7914 mbmi->use_wedge_interintra = 1;
7915
Yaowu Xuf883b422016-08-30 14:01:10 -07007916 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
7917 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007918
7919 best_interintra_rd_wedge =
7920 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
7921
7922 best_interintra_rd_wedge +=
7923 RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge, 0);
7924 // Refine motion vector.
7925 if (have_newmv_in_inter_mode(this_mode)) {
7926 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07007927 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007928 mbmi->interintra_wedge_index, 1, bsize);
David Barkerf19f35f2017-05-22 16:33:22 +01007929 tmp_mv.as_int = x->mbmi_ext->ref_mvs[refs[0]][0].as_int;
7930 compound_single_motion_search(cpi, x, bsize, &tmp_mv.as_mv, mi_row,
7931 mi_col, intrapred, mask, bw,
David Barker8dd9b572017-05-12 16:31:38 +01007932 &tmp_rate_mv, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007933 mbmi->mv[0].as_int = tmp_mv.as_int;
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007934 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
7935 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007936 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7937 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
7938 rd = RDCOST(x->rdmult, x->rddiv,
7939 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07007940 if (rd >= best_interintra_rd_wedge) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007941 tmp_mv.as_int = cur_mv[0].as_int;
7942 tmp_rate_mv = rate_mv;
7943 }
7944 } else {
7945 tmp_mv.as_int = cur_mv[0].as_int;
7946 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07007947 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007948 }
7949 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07007950 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007951 rd =
7952 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7953 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7954 if (rd != INT64_MAX)
7955 rd = RDCOST(x->rdmult, x->rddiv,
7956 rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
7957 best_interintra_rd_wedge = rd;
7958 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
7959 mbmi->use_wedge_interintra = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007960 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08007961 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007962 rate_mv = tmp_rate_mv;
7963 } else {
7964 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007965 mbmi->mv[0].as_int = cur_mv[0].as_int;
7966 }
7967 } else {
7968 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007969 }
7970 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007971#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007972
7973 pred_exists = 0;
Yue Chen5e606542017-05-24 17:03:17 -07007974 compmode_interintra_cost =
7975 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1) +
Fergus Simpson073c6f32017-02-17 12:13:48 -08007976 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007977 if (is_interintra_wedge_used(bsize)) {
Yue Chen5e606542017-05-24 17:03:17 -07007978 compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07007979 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
7980 if (mbmi->use_wedge_interintra) {
Yue Chen5e606542017-05-24 17:03:17 -07007981 compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07007982 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07007983 }
7984 }
7985 } else if (is_interintra_allowed(mbmi)) {
Yue Chen5e606542017-05-24 17:03:17 -07007986 compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07007987 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007988 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007989#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07007990
Angie Chiang75c22092016-10-25 12:19:16 -07007991 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07007992 int tmp_rate;
7993 int64_t tmp_dist;
Jingning Hanc44009c2017-05-06 11:36:49 -07007994 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007995 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7996 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
7997 rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
7998 }
Angie Chiang75c22092016-10-25 12:19:16 -07007999#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008000
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008001 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008002#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008003 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008004#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008005 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008006#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008007
8008#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008009 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008010 if (is_comp_pred) {
8011 const int mode0 = compound_ref0_mode(this_mode);
8012 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008013 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8014 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008015 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008016 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008017 return INT64_MAX;
8018 }
8019 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008020 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008021 }
8022 }
8023#endif // CONFIG_EXT_INTER
8024
8025 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8026 // if current pred_error modeled rd is substantially more than the best
8027 // so far, do not bother doing full rd
8028 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008029 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008030 return INT64_MAX;
8031 }
8032 }
8033
Yue Chen5e606542017-05-24 17:03:17 -07008034#if CONFIG_EXT_INTER
8035#if CONFIG_INTERINTRA
8036 rd_stats->rate += compmode_interintra_cost;
8037#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8038 rate2_bmc_nocoeff += compmode_interintra_cost;
8039#endif
8040#endif
8041#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
8042 rd_stats->rate += compmode_interinter_cost;
8043#endif
8044#endif
8045
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008046 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
8047 disable_skip, mode_mv, mi_row, mi_col, args,
8048 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07008049#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07008050 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008051#if CONFIG_EXT_INTER
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008052 rate2_bmc_nocoeff, &best_bmc_mbmi,
Yue Chencb60b182016-10-13 15:18:22 -07008053#if CONFIG_MOTION_VAR
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008054 rate_mv_bmc,
Yue Chencb60b182016-10-13 15:18:22 -07008055#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -07008056#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008057#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008058 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
8059 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08008060
Yaowu Xuc27fc142016-08-22 16:08:15 -07008061 return 0; // The rate-distortion cost will be re-calculated by caller.
8062}
8063
Alex Converse28744302017-04-13 14:46:22 -07008064#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07008065static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008066 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07008067 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07008068 const AV1_COMMON *const cm = &cpi->common;
8069 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
8070
Alex Converse28744302017-04-13 14:46:22 -07008071 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07008072 const TileInfo *tile = &xd->tile;
Alex Converse7c412ea2017-06-01 15:16:22 -07008073#if CONFIG_EC_ADAPT
8074 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
8075#else
8076 FRAME_CONTEXT *const ec_ctx = cm->fc;
8077#endif // CONFIG_EC_ADAPT
Alex Converse3d8adf32017-04-24 12:35:42 -07008078 MODE_INFO *const mi = xd->mi[0];
8079 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
8080 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
8081 const int w = block_size_wide[bsize];
8082 const int h = block_size_high[bsize];
8083 const int sb_row = mi_row / MAX_MIB_SIZE;
Alex Converse861d7072017-05-15 14:19:53 -07008084 const int sb_col = mi_col / MAX_MIB_SIZE;
Alex Converse3d8adf32017-04-24 12:35:42 -07008085
Alex Converse44c2bad2017-05-11 09:36:10 -07008086 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8087 MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
8088 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8089 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8090 mbmi_ext->ref_mv_stack[ref_frame],
8091#if CONFIG_EXT_INTER
8092 mbmi_ext->compound_mode_context,
8093#endif // CONFIG_EXT_INTER
8094 candidates, mi_row, mi_col, NULL, NULL,
8095 mbmi_ext->mode_context);
8096
8097 int_mv nearestmv, nearmv;
8098 av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
8099
8100 int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
8101 if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
8102 mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
Alex Converse3d8adf32017-04-24 12:35:42 -07008103
Alex Converse3d8adf32017-04-24 12:35:42 -07008104 struct buf_2d yv12_mb[MAX_MB_PLANE];
8105 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
8106 for (int i = 0; i < MAX_MB_PLANE; ++i) {
8107 xd->plane[i].pre[0] = yv12_mb[i];
8108 }
8109
Alex Converse861d7072017-05-15 14:19:53 -07008110 enum IntrabcMotionDirection {
8111 IBC_MOTION_ABOVE,
8112 IBC_MOTION_LEFT,
8113 IBC_MOTION_DIRECTIONS
8114 };
Alex Converse3d8adf32017-04-24 12:35:42 -07008115
Alex Converse3d8adf32017-04-24 12:35:42 -07008116 MB_MODE_INFO *mbmi = &mi->mbmi;
8117 MB_MODE_INFO best_mbmi = *mbmi;
8118 RD_STATS best_rdcost = *rd_cost;
8119 int best_skip = x->skip;
Alex Converse861d7072017-05-15 14:19:53 -07008120
8121 for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
8122 dir < IBC_MOTION_DIRECTIONS; ++dir) {
8123 const MvLimits tmp_mv_limits = x->mv_limits;
8124 switch (dir) {
8125 case IBC_MOTION_ABOVE:
8126 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8127 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
8128 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8129 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
8130 break;
8131 case IBC_MOTION_LEFT:
8132 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8133 x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
8134 // TODO(aconverse@google.com): Minimize the overlap between above and
8135 // left areas.
8136 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8137 int bottom_coded_mi_edge =
8138 AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
8139 x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
8140 break;
8141 default: assert(0);
8142 }
8143 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
8144 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
8145 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
8146 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
8147 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
8148
8149 if (x->mv_limits.col_max < x->mv_limits.col_min ||
8150 x->mv_limits.row_max < x->mv_limits.row_min) {
8151 x->mv_limits = tmp_mv_limits;
8152 continue;
8153 }
8154
8155 int step_param = cpi->mv_step_param;
8156 MV mvp_full = dv_ref.as_mv;
8157 mvp_full.col >>= 3;
8158 mvp_full.row >>= 3;
8159 int sadpb = x->sadperbit16;
8160 int cost_list[5];
8161 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
8162 sadpb, cond_cost_list(cpi, cost_list),
8163 &dv_ref.as_mv, INT_MAX, 1);
8164
8165 x->mv_limits = tmp_mv_limits;
8166 if (bestsme == INT_MAX) continue;
8167 mvp_full = x->best_mv.as_mv;
8168 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
8169 if (mv_check_bounds(&x->mv_limits, &dv)) continue;
8170 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
8171
Alex Converse3d8adf32017-04-24 12:35:42 -07008172#if CONFIG_PALETTE
Alex Converse861d7072017-05-15 14:19:53 -07008173 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
Alex Converse3d8adf32017-04-24 12:35:42 -07008174#endif
Alex Converse861d7072017-05-15 14:19:53 -07008175 mbmi->use_intrabc = 1;
8176 mbmi->mode = DC_PRED;
8177 mbmi->uv_mode = DC_PRED;
8178 mbmi->mv[0].as_mv = dv;
Alex Converse3d8adf32017-04-24 12:35:42 -07008179#if CONFIG_DUAL_FILTER
Alex Converse861d7072017-05-15 14:19:53 -07008180 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07008181#else
Alex Converse861d7072017-05-15 14:19:53 -07008182 mbmi->interp_filter = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07008183#endif
Alex Converse861d7072017-05-15 14:19:53 -07008184 mbmi->skip = 0;
8185 x->skip = 0;
8186 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Alex Converse3d8adf32017-04-24 12:35:42 -07008187
Alex Conversed5d9b6c2017-05-23 15:23:45 -07008188 assert(x->mvcost == x->mv_cost_stack[0]);
8189 // TODO(aconverse@google.com): The full motion field defining discount
8190 // in MV_COST_WEIGHT is too large. Explore other values.
Alex Converse861d7072017-05-15 14:19:53 -07008191 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
Alex Conversed5d9b6c2017-05-23 15:23:45 -07008192 x->mvcost, MV_COST_WEIGHT_SUB);
8193 const int rate_mode = av1_cost_bit(ec_ctx->intrabc_prob, 1);
Alex Converse3d8adf32017-04-24 12:35:42 -07008194
Alex Converse861d7072017-05-15 14:19:53 -07008195 RD_STATS rd_stats, rd_stats_uv;
8196 av1_subtract_plane(x, bsize, 0);
8197 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
8198 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
8199 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
Alex Converse3d8adf32017-04-24 12:35:42 -07008200#if CONFIG_RD_DEBUG
Alex Converse861d7072017-05-15 14:19:53 -07008201 mbmi->rd_stats = rd_stats;
Alex Converse3d8adf32017-04-24 12:35:42 -07008202#endif
8203
Alex Conversee16b2662017-05-24 14:00:00 -07008204#if CONFIG_VAR_TX
8205 // TODO(aconverse@google.com): Evaluate allowing VAR TX on intrabc blocks
8206 const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
8207 const int height = block_size_high[bsize] >> tx_size_high_log2[0];
8208 int idx, idy;
8209 for (idy = 0; idy < height; ++idy)
8210 for (idx = 0; idx < width; ++idx)
8211 mbmi->inter_tx_size[idy >> 1][idx >> 1] = mbmi->tx_size;
8212 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
8213#endif // CONFIG_VAR_TX
8214
Alex Converse861d7072017-05-15 14:19:53 -07008215 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Alex Converse3d8adf32017-04-24 12:35:42 -07008216
Alex Converse861d7072017-05-15 14:19:53 -07008217 RD_STATS rdc_noskip;
8218 av1_init_rd_stats(&rdc_noskip);
8219 rdc_noskip.rate =
8220 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
8221 rdc_noskip.dist = rd_stats.dist;
8222 rdc_noskip.rdcost =
8223 RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
8224 if (rdc_noskip.rdcost < best_rd) {
8225 best_rd = rdc_noskip.rdcost;
8226 best_mbmi = *mbmi;
8227 best_skip = x->skip;
8228 best_rdcost = rdc_noskip;
8229 }
Alex Converse3d8adf32017-04-24 12:35:42 -07008230
Alex Converse861d7072017-05-15 14:19:53 -07008231 x->skip = 1;
8232 mbmi->skip = 1;
8233 RD_STATS rdc_skip;
8234 av1_init_rd_stats(&rdc_skip);
8235 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
8236 rdc_skip.dist = rd_stats.sse;
8237 rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
8238 if (rdc_skip.rdcost < best_rd) {
8239 best_rd = rdc_skip.rdcost;
8240 best_mbmi = *mbmi;
8241 best_skip = x->skip;
8242 best_rdcost = rdc_skip;
8243 }
Alex Converse3d8adf32017-04-24 12:35:42 -07008244 }
8245 *mbmi = best_mbmi;
8246 *rd_cost = best_rdcost;
8247 x->skip = best_skip;
8248 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07008249}
8250#endif // CONFIG_INTRABC
8251
Urvang Joshi52648442016-10-13 17:27:51 -07008252void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008253 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07008254 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
8255 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008256 MACROBLOCKD *const xd = &x->e_mbd;
8257 struct macroblockd_plane *const pd = xd->plane;
8258 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
8259 int y_skip = 0, uv_skip = 0;
8260 int64_t dist_y = 0, dist_uv = 0;
8261 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08008262 const int unify_bsize = CONFIG_CB4X4;
8263
Yaowu Xuc27fc142016-08-22 16:08:15 -07008264 ctx->skip = 0;
8265 xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05008266 xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07008267#if CONFIG_INTRABC
8268 xd->mi[0]->mbmi.use_intrabc = 0;
Alex Converse44c2bad2017-05-11 09:36:10 -07008269 xd->mi[0]->mbmi.mv[0].as_int = 0;
Alex Converse28744302017-04-13 14:46:22 -07008270#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07008271
Alex Conversed1b6fad2017-04-26 15:39:37 -07008272 const int64_t intra_yrd =
8273 (bsize >= BLOCK_8X8 || unify_bsize)
8274 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
8275 &y_skip, bsize, best_rd)
8276 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
8277 &dist_y, &y_skip, best_rd);
8278
8279 if (intra_yrd < best_rd) {
8280 max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
8281 [pd[1].subsampling_x][pd[1].subsampling_y];
hui sueaddeee2017-05-30 12:19:38 -07008282 init_sbuv_mode(&xd->mi[0]->mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08008283#if CONFIG_CB4X4
Alex Conversed1b6fad2017-04-26 15:39:37 -07008284 if (!x->skip_chroma_rd)
8285 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
8286 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08008287#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07008288 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
8289 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08008290#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07008291
Alex Conversed1b6fad2017-04-26 15:39:37 -07008292 if (y_skip && uv_skip) {
8293 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
8294 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8295 rd_cost->dist = dist_y + dist_uv;
8296 } else {
8297 rd_cost->rate =
8298 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8299 rd_cost->dist = dist_y + dist_uv;
8300 }
8301 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Yushin Cho63927c42017-05-23 15:41:05 -07008302#if CONFIG_DAALA_DIST && CONFIG_CB4X4
8303 rd_cost->dist_y = dist_y;
8304#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008305 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07008306 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008307 }
8308
Alex Converse28744302017-04-13 14:46:22 -07008309#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07008310 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
8311 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07008312 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
8313 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07008314 assert(rd_cost->rate != INT_MAX);
8315 rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07008316 }
8317#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07008318 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07008319
Yaowu Xuc27fc142016-08-22 16:08:15 -07008320 ctx->mic = *xd->mi[0];
8321 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008322}
8323
Yaowu Xuc27fc142016-08-22 16:08:15 -07008324// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07008325int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008326 return (cpi->oxcf.pass == 2) &&
8327 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
8328 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
8329}
8330
8331// Checks to see if a super block is on a horizontal image edge.
8332// In most cases this is the "real" edge unless there are formatting
8333// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008334int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008335 int top_edge = 0;
8336 int bottom_edge = cpi->common.mi_rows;
8337 int is_active_h_edge = 0;
8338
8339 // For two pass account for any formatting bars detected.
8340 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008341 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008342
8343 // The inactive region is specified in MBs not mi units.
8344 // The image edge is in the following MB row.
8345 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
8346
8347 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008348 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008349 }
8350
8351 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
8352 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
8353 is_active_h_edge = 1;
8354 }
8355 return is_active_h_edge;
8356}
8357
8358// Checks to see if a super block is on a vertical image edge.
8359// In most cases this is the "real" edge unless there are formatting
8360// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008361int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008362 int left_edge = 0;
8363 int right_edge = cpi->common.mi_cols;
8364 int is_active_v_edge = 0;
8365
8366 // For two pass account for any formatting bars detected.
8367 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07008368 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008369
8370 // The inactive region is specified in MBs not mi units.
8371 // The image edge is in the following MB row.
8372 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
8373
8374 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07008375 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008376 }
8377
8378 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
8379 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
8380 is_active_v_edge = 1;
8381 }
8382 return is_active_v_edge;
8383}
8384
8385// Checks to see if a super block is at the edge of the active image.
8386// In most cases this is the "real" edge unless there are formatting
8387// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07008388int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008389 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
8390 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008391}
8392
Urvang Joshib100db72016-10-12 16:28:56 -07008393#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07008394static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008395 MACROBLOCKD *const xd = &x->e_mbd;
8396 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
8397 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
8398 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008399 int src_stride = x->plane[1].src.stride;
8400 const uint8_t *const src_u = x->plane[1].src.buf;
8401 const uint8_t *const src_v = x->plane[2].src.buf;
8402 float *const data = x->palette_buffer->kmeans_data_buf;
8403 float centroids[2 * PALETTE_MAX_SIZE];
8404 uint8_t *const color_map = xd->plane[1].color_index_map;
8405 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008406#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008407 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
8408 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008409#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08008410 int plane_block_width, plane_block_height, rows, cols;
8411 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
8412 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008413 (void)cpi;
8414
8415 for (r = 0; r < rows; ++r) {
8416 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008417#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008418 if (cpi->common.use_highbitdepth) {
8419 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
8420 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
8421 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008422#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008423 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
8424 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008425#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008426 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008427#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008428 }
8429 }
8430
8431 for (r = 1; r < 3; ++r) {
8432 for (c = 0; c < pmi->palette_size[1]; ++c) {
8433 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
8434 }
8435 }
8436
Yaowu Xuf883b422016-08-30 14:01:10 -07008437 av1_calc_indices(data, centroids, color_map, rows * cols,
8438 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08008439 extend_palette_color_map(color_map, cols, rows, plane_block_width,
8440 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008441}
Urvang Joshib100db72016-10-12 16:28:56 -07008442#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008443
hui su5db97432016-10-14 16:10:14 -07008444#if CONFIG_FILTER_INTRA
8445static void pick_filter_intra_interframe(
8446 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08008447 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
8448 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
8449 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07008450#if CONFIG_EXT_INTRA
8451 int8_t *uv_angle_delta,
8452#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07008453#if CONFIG_PALETTE
8454 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
8455#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008456 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
8457 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
8458 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
8459#if CONFIG_SUPERTX
8460 int *returnrate_nocoef,
8461#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008462 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07008463 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008464 MACROBLOCKD *const xd = &x->e_mbd;
8465 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008466#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008468#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008469 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
8470 int dc_mode_index;
8471 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08008472 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
8473 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008474 TX_SIZE uv_tx;
8475
8476 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008477 if (av1_mode_order[i].mode == DC_PRED &&
8478 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008479 break;
8480 dc_mode_index = i;
8481 assert(i < MAX_MODES);
8482
8483 // TODO(huisu): use skip_mask for further speedup.
8484 (void)skip_mask;
8485 mbmi->mode = DC_PRED;
8486 mbmi->uv_mode = DC_PRED;
8487 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05008488 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07008489 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
8490 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08008491 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008492 return;
hui su5db97432016-10-14 16:10:14 -07008493 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008494 if (rate_y == INT_MAX) return;
8495
Debargha Mukherjee2f123402016-08-30 17:43:38 -07008496 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
8497 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008498 if (rate_uv_intra[uv_tx] == INT_MAX) {
8499 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
8500 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
8501 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07008502#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008503 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008504#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008505 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
8506#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008507 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07008508#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008509 }
8510
8511 rate_uv = rate_uv_tokenonly[uv_tx];
8512 distortion_uv = dist_uv[uv_tx];
8513 skippable = skippable && skip_uv[uv_tx];
8514 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07008515#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008516 if (cm->allow_screen_content_tools) {
8517 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
8518 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
8519 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
8520 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
8521 }
Urvang Joshib100db72016-10-12 16:28:56 -07008522#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07008523#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008524 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07008525#endif // CONFIG_EXT_INTRA
8526 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
8527 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
8528 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
8529 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
8530 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008531 }
8532
8533 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
8534 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07008535#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07008536 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
8537 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07008538 rate2 += av1_cost_bit(
8539 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07008540#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008541
8542 if (!xd->lossless[mbmi->segment_id]) {
8543 // super_block_yrd above includes the cost of the tx_size in the
8544 // tokenonly rate, but for intra blocks, tx_size is always coded
8545 // (prediction granularity), so we account for it in the full rate,
8546 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08008547 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008548 }
8549
hui su5db97432016-10-14 16:10:14 -07008550 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
8551 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
8552 rate2 += write_uniform_cost(
8553 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
8554#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08008555 if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07008556 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
8557 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008558 }
hui su5db97432016-10-14 16:10:14 -07008559#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008560 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07008561 rate2 +=
8562 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
8563 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
8564 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
8565 rate2 +=
8566 write_uniform_cost(FILTER_INTRA_MODES,
8567 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008568 }
8569 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08008570 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
8571 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008572
8573 rate2 += ref_costs_single[INTRA_FRAME];
8574
8575 if (skippable) {
8576 rate2 -= (rate_y + rate_uv);
8577 rate_y = 0;
8578 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008579 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008580 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07008581 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008582 }
8583 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008584
8585 if (this_rd < *best_intra_rd) {
8586 *best_intra_rd = this_rd;
8587 *best_intra_mode = mbmi->mode;
8588 }
8589 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07008590 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008591
8592 if (this_rd < *best_rd) {
8593 *best_mode_index = dc_mode_index;
8594 mbmi->mv[0].as_int = 0;
8595 rd_cost->rate = rate2;
8596#if CONFIG_SUPERTX
8597 if (x->skip)
8598 *returnrate_nocoef = rate2;
8599 else
8600 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008601 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
8602 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
8603 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008604#endif // CONFIG_SUPERTX
8605 rd_cost->dist = distortion2;
8606 rd_cost->rdcost = this_rd;
8607 *best_rd = this_rd;
8608 *best_mbmode = *mbmi;
8609 *best_skip2 = 0;
8610 *best_mode_skippable = skippable;
8611 }
8612}
hui su5db97432016-10-14 16:10:14 -07008613#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008614
Yue Chencb60b182016-10-13 15:18:22 -07008615#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07008616static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
8617 const MACROBLOCKD *xd, int mi_row,
8618 int mi_col, const uint8_t *above,
8619 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07008620 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07008621#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008622
Urvang Joshi52648442016-10-13 17:27:51 -07008623void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07008624 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008625 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008626#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008627 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008628#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07008629 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
8630 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07008631 const AV1_COMMON *const cm = &cpi->common;
8632 const RD_OPT *const rd_opt = &cpi->rd;
8633 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008634 MACROBLOCKD *const xd = &x->e_mbd;
8635 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07008636#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07008637 const int try_palette =
8638 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008639 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07008640#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008641 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8642 const struct segmentation *const seg = &cm->seg;
8643 PREDICTION_MODE this_mode;
8644 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
8645 unsigned char segment_id = mbmi->segment_id;
8646 int comp_pred, i, k;
8647 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
8648 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008649 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07008650#if CONFIG_EXT_INTER
8651 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
8652 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008653#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008654 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
8655 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07008656 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008657#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008658 AOM_LAST2_FLAG,
8659 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008661 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008662#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008663 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008664#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07008665 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07008666 };
8667 int64_t best_rd = best_rd_so_far;
8668 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
8669 int64_t best_pred_diff[REFERENCE_MODES];
8670 int64_t best_pred_rd[REFERENCE_MODES];
8671 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07008672 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8673 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008674 int best_mode_skippable = 0;
8675 int midx, best_mode_index = -1;
8676 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
8677 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -07008678 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008679 int64_t best_intra_rd = INT64_MAX;
8680 unsigned int best_pred_sse = UINT_MAX;
8681 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08008682 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
8683 int64_t dist_uvs[TX_SIZES_ALL];
8684 int skip_uvs[TX_SIZES_ALL];
8685 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07008686#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08008687 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07008688#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008689#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08008690 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008691 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008692 uint8_t directional_mode_skip_mask[INTRA_MODES];
8693#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07008694#if CONFIG_FILTER_INTRA
8695 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08008696 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07008697#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07008698 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008699 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
8700 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
8701 int best_skip2 = 0;
8702 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07008703 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Yue Chen4d26acb2017-05-01 12:28:34 -07008704#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008705 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
8706 int64_t best_single_inter_rd = INT64_MAX;
Yue Chen4d26acb2017-05-01 12:28:34 -07008707#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008708 int mode_skip_start = sf->mode_skip_start + 1;
8709 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
8710 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
8711 int64_t mode_threshold[MAX_MODES];
8712 int *mode_map = tile_data->mode_map[bsize];
8713 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07008714#if CONFIG_PVQ
8715 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08008716#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07008717
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008718 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08008719#if CONFIG_MOTION_VAR
8720 { NULL },
8721 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
8722 { NULL },
8723 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
8724#endif // CONFIG_MOTION_VAR
8725#if CONFIG_EXT_INTER
8726 NULL,
8727 NULL,
8728 NULL,
Fergus Simpson073c6f32017-02-17 12:13:48 -08008729#else // CONFIG_EXT_INTER
8730 NULL,
8731#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008732 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08008733 };
8734
Urvang Joshib100db72016-10-12 16:28:56 -07008735#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08008736 const int rows = block_size_high[bsize];
8737 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07008738#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
8739#if CONFIG_PALETTE
8740 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008741 const MODE_INFO *above_mi = xd->above_mi;
8742 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07008743#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07008744#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008745 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8746 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8747 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
8748 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07008749
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008750#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008751 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
8752 int len = sizeof(uint16_t);
Jingning Hand064cf02017-06-01 10:00:39 -07008753 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(x->above_pred_buf);
8754 args.above_pred_buf[1] =
8755 CONVERT_TO_BYTEPTR(x->above_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008756 args.above_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07008757 CONVERT_TO_BYTEPTR(x->above_pred_buf + 2 * MAX_SB_SQUARE * len);
8758 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(x->left_pred_buf);
8759 args.left_pred_buf[1] =
8760 CONVERT_TO_BYTEPTR(x->left_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008761 args.left_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07008762 CONVERT_TO_BYTEPTR(x->left_pred_buf + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008763 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008764#endif // CONFIG_HIGHBITDEPTH
Jingning Hand064cf02017-06-01 10:00:39 -07008765 args.above_pred_buf[0] = x->above_pred_buf;
8766 args.above_pred_buf[1] = x->above_pred_buf + MAX_SB_SQUARE;
8767 args.above_pred_buf[2] = x->above_pred_buf + 2 * MAX_SB_SQUARE;
8768 args.left_pred_buf[0] = x->left_pred_buf;
8769 args.left_pred_buf[1] = x->left_pred_buf + MAX_SB_SQUARE;
8770 args.left_pred_buf[2] = x->left_pred_buf + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008771#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008772 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008773#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07008774#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008775
Yaowu Xuf883b422016-08-30 14:01:10 -07008776 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008777
Urvang Joshib100db72016-10-12 16:28:56 -07008778#if CONFIG_PALETTE
8779 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07008780 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 if (above_mi)
8782 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8783 if (left_mi)
8784 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
8785 }
Urvang Joshib100db72016-10-12 16:28:56 -07008786#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008787
Yaowu Xuc27fc142016-08-22 16:08:15 -07008788 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
8789 &comp_mode_p);
8790
8791 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08008792 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008793 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
8794 for (i = 0; i < MB_MODE_COUNT; ++i) {
8795 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008796 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008797 }
8798 }
8799
8800 rd_cost->rate = INT_MAX;
8801#if CONFIG_SUPERTX
8802 *returnrate_nocoef = INT_MAX;
8803#endif // CONFIG_SUPERTX
8804
8805 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8806 x->pred_mv_sad[ref_frame] = INT_MAX;
8807 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008808#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008809 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008810#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008811 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
8812 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
8813 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
8814 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
8815 }
8816 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07008817#if CONFIG_GLOBAL_MOTION
8818 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08008819 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08008820 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
8821 0)
David Barkercdcac6d2016-12-01 17:04:16 +00008822 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008823#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07008825#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008826#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008827 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkerc2d38712017-01-24 15:15:41 -08008828#if CONFIG_GLOBAL_MOTION
8829 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08008830 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08008831 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
8832 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08008833 .as_int;
8834#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008835 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08008836#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008837#endif // CONFIG_EXT_INTER
8838 }
8839
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
8841 MODE_INFO *const mi = xd->mi[0];
8842 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8843 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07008844 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8845 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07008846#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008847 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008848#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008849 candidates, mi_row, mi_col, NULL, NULL,
8850 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08008851 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
8852 MV_REFERENCE_FRAME rf[2];
8853 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00008854 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
8855 frame_mv[ZEROMV][rf[0]].as_int ||
8856 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
8857 frame_mv[ZEROMV][rf[0]].as_int ||
8858 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
8859 frame_mv[ZEROMV][rf[1]].as_int ||
8860 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08008861 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
8862 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008863 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008864
Yue Chencb60b182016-10-13 15:18:22 -07008865#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08008866 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Jingning Hanad586b92017-05-23 10:24:57 -07008867
Yue Chenf7ba6472017-04-19 11:08:58 -07008868 if (check_num_overlappable_neighbors(mbmi) &&
8869 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008870 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
8871 args.above_pred_buf, dst_width1,
8872 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08008873 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008874 args.left_pred_buf, dst_width2,
8875 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07008876 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
8877 mi_col);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008878 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
8879 args.above_pred_stride[0], args.left_pred_buf[0],
8880 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08008881 }
Yue Chencb60b182016-10-13 15:18:22 -07008882#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07008883
8884 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
8885 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
8886// Skip checking missing references in both single and compound reference
8887// modes. Note that a mode will be skipped iff both reference frames
8888// are masked out.
8889#if CONFIG_EXT_REFS
8890 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
8891 ref_frame_skip_mask[0] |= (1 << ref_frame);
8892 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
8893 } else {
8894#endif // CONFIG_EXT_REFS
8895 ref_frame_skip_mask[0] |= (1 << ref_frame);
8896 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8897#if CONFIG_EXT_REFS
8898 }
8899#endif // CONFIG_EXT_REFS
8900 } else {
8901 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
8902 // Skip fixed mv modes for poor references
8903 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
8904 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
8905 break;
8906 }
8907 }
8908 }
8909 // If the segment reference frame feature is enabled....
8910 // then do nothing if the current ref frame is not allowed..
8911 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
8912 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
8913 ref_frame_skip_mask[0] |= (1 << ref_frame);
8914 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
8915 }
8916 }
8917
8918 // Disable this drop out case if the ref frame
8919 // segment level feature is enabled for this segment. This is to
8920 // prevent the possibility that we end up unable to pick any mode.
8921 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
8922 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
8923 // unless ARNR filtering is enabled in which case we want
8924 // an unfiltered alternative. We allow near/nearest as well
8925 // because they may result in zero-zero MVs but be cheaper.
8926 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07008927 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008928 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
8929#if CONFIG_EXT_REFS
8930 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
8931 (1 << BWDREF_FRAME) |
8932#endif // CONFIG_EXT_REFS
8933 (1 << GOLDEN_FRAME);
8934 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8935 // TODO(zoeliu): To further explore whether following needs to be done for
8936 // BWDREF_FRAME as well.
8937 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07008938#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00008939 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08008940 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08008941 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00008942 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07008943#else
8944 zeromv.as_int = 0;
8945#endif // CONFIG_GLOBAL_MOTION
8946 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008947 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008948 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008949 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
8950#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07008951 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008952 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07008953 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008954 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
8955#endif // CONFIG_EXT_INTER
8956 }
8957 }
8958
8959 if (cpi->rc.is_src_frame_alt_ref) {
8960 if (sf->alt_ref_search_fp) {
8961 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
8962 mode_skip_mask[ALTREF_FRAME] = 0;
8963 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
8964 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
8965 }
8966 }
8967
8968 if (sf->alt_ref_search_fp)
8969 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
8970 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
8971 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
8972
8973 if (sf->adaptive_mode_search) {
8974 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
8975 cpi->rc.frames_since_golden >= 3)
Yaowu Xu36bad472017-05-16 18:29:53 -07008976 if ((x->pred_mv_sad[GOLDEN_FRAME] >> 1) > x->pred_mv_sad[LAST_FRAME])
Yaowu Xuc27fc142016-08-22 16:08:15 -07008977 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
8978 }
8979
8980 if (bsize > sf->max_intra_bsize) {
8981 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
8982 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
8983 }
8984
8985 mode_skip_mask[INTRA_FRAME] |=
8986 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
8987
8988 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
8989 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
8990 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
8991
8992 midx = sf->schedule_mode_search ? mode_skip_start : 0;
8993 while (midx > 4) {
8994 uint8_t end_pos = 0;
8995 for (i = 5; i < midx; ++i) {
8996 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
8997 uint8_t tmp = mode_map[i];
8998 mode_map[i] = mode_map[i - 1];
8999 mode_map[i - 1] = tmp;
9000 end_pos = i;
9001 }
9002 }
9003 midx = end_pos;
9004 }
9005
9006 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9007 x->use_default_intra_tx_type = 1;
9008 else
9009 x->use_default_intra_tx_type = 0;
9010
9011 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9012 x->use_default_inter_tx_type = 1;
9013 else
9014 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009015#if CONFIG_PVQ
9016 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009017#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009018#if CONFIG_EXT_INTER
9019 for (i = 0; i < MB_MODE_COUNT; ++i)
9020 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9021 modelled_rd[i][ref_frame] = INT64_MAX;
9022#endif // CONFIG_EXT_INTER
9023
9024 for (midx = 0; midx < MAX_MODES; ++midx) {
9025 int mode_index;
9026 int mode_excluded = 0;
9027 int64_t this_rd = INT64_MAX;
9028 int disable_skip = 0;
9029 int compmode_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009030 int rate2 = 0, rate_y = 0, rate_uv = 0;
9031 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -07009032#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9033 int64_t distortion2_y = 0;
9034 int64_t total_sse_y = INT64_MAX;
9035#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009036 int skippable = 0;
9037 int this_skip2 = 0;
9038 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009039 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009040#if CONFIG_PVQ
9041 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009042#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009043 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009044 this_mode = av1_mode_order[mode_index].mode;
9045 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9046 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009047 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009048
9049#if CONFIG_EXT_INTER
9050 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9051 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -08009052 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009053 if (!is_interintra_allowed_bsize(bsize)) continue;
9054 }
9055
9056 if (is_inter_compound_mode(this_mode)) {
9057 frame_mv[this_mode][ref_frame].as_int =
9058 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9059 frame_mv[this_mode][second_ref_frame].as_int =
9060 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
9061 }
9062#endif // CONFIG_EXT_INTER
9063
9064 // Look at the reference frame of the best mode so far and set the
9065 // skip mask to look at a subset of the remaining modes.
9066 if (midx == mode_skip_start && best_mode_index >= 0) {
9067 switch (best_mbmode.ref_frame[0]) {
9068 case INTRA_FRAME: break;
9069 case LAST_FRAME:
9070 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9071 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9072 break;
9073#if CONFIG_EXT_REFS
9074 case LAST2_FRAME:
9075 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9076 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9077 break;
9078 case LAST3_FRAME:
9079 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9080 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9081 break;
9082#endif // CONFIG_EXT_REFS
9083 case GOLDEN_FRAME:
9084 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9085 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9086 break;
9087#if CONFIG_EXT_REFS
9088 case BWDREF_FRAME:
9089 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9090 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9091 break;
9092#endif // CONFIG_EXT_REFS
9093 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9094#if CONFIG_EXT_REFS
9095 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9096#endif // CONFIG_EXT_REFS
9097 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009098 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009099 case TOTAL_REFS_PER_FRAME:
9100 assert(0 && "Invalid Reference frame");
9101 break;
9102 }
9103 }
9104
9105 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009106 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009107 continue;
9108
9109 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
9110
9111 // Test best rd so far against threshold for trying this mode.
9112 if (best_mode_skippable && sf->schedule_mode_search)
9113 mode_threshold[mode_index] <<= 1;
9114
9115 if (best_rd < mode_threshold[mode_index]) continue;
9116
Yunqing Wangff4fa062017-04-21 10:56:08 -07009117 // This is only used in motion vector unit test.
9118 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
9119
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +02009120#if CONFIG_ONE_SIDED_COMPOUND // Changes LL bitstream
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +02009121#if CONFIG_EXT_REFS
9122 if (cpi->oxcf.pass == 0) {
9123 // Complexity-compression trade-offs
9124 // if (ref_frame == ALTREF_FRAME) continue;
9125 // if (ref_frame == BWDREF_FRAME) continue;
9126 if (second_ref_frame == ALTREF_FRAME) continue;
9127 // if (second_ref_frame == BWDREF_FRAME) continue;
9128 }
9129#endif
9130#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009131 comp_pred = second_ref_frame > INTRA_FRAME;
9132 if (comp_pred) {
9133 if (!cpi->allow_comp_inter_inter) continue;
9134
9135 // Skip compound inter modes if ARF is not available.
9136 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
9137
9138 // Do not allow compound prediction if the segment level reference frame
9139 // feature is in use as in this case there can only be one reference.
9140 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
9141
9142 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
9143 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
9144 continue;
9145
9146 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
9147 } else {
9148 if (ref_frame != INTRA_FRAME)
9149 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
9150 }
9151
9152 if (ref_frame == INTRA_FRAME) {
9153 if (sf->adaptive_mode_search)
9154 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
9155 continue;
9156
9157 if (this_mode != DC_PRED) {
9158 // Disable intra modes other than DC_PRED for blocks with low variance
9159 // Threshold for intra skipping based on source variance
9160 // TODO(debargha): Specialize the threshold for super block sizes
9161 const unsigned int skip_intra_var_thresh = 64;
9162 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
9163 x->source_variance < skip_intra_var_thresh)
9164 continue;
9165 // Only search the oblique modes if the best so far is
9166 // one of the neighboring directional modes
9167 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
9168 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
9169 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
9170 continue;
9171 }
9172 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
9173 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
9174 }
9175 }
Sarah Parkere5299862016-08-16 14:57:37 -07009176#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +00009177 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -07009178 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +00009179 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009180#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009181 } else {
Sarah Parkere5299862016-08-16 14:57:37 -07009182#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009183 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
9184 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009185#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009186 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009187#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +00009188 frame_mv, this_mode, ref_frames, bsize, -1,
9189 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009190 continue;
9191 }
9192
9193 mbmi->mode = this_mode;
9194 mbmi->uv_mode = DC_PRED;
9195 mbmi->ref_frame[0] = ref_frame;
9196 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -07009197#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009198 pmi->palette_size[0] = 0;
9199 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07009200#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009201#if CONFIG_FILTER_INTRA
9202 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9203 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9204#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009205 // Evaluate all sub-pel filters irrespective of whether we can use
9206 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07009207
9208 set_default_interp_filters(mbmi, cm->interp_filter);
9209
Yaowu Xuc27fc142016-08-22 16:08:15 -07009210 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -07009211 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009212
9213 x->skip = 0;
9214 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
9215
9216 // Select prediction reference frames.
9217 for (i = 0; i < MAX_MB_PLANE; i++) {
9218 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
9219 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
9220 }
9221
Yue Chen4d26acb2017-05-01 12:28:34 -07009222#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009223 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yue Chen4d26acb2017-05-01 12:28:34 -07009224#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009225
9226 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009227 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009228 TX_SIZE uv_tx;
9229 struct macroblockd_plane *const pd = &xd->plane[1];
9230#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08009231 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009232 if (is_directional_mode) {
hui su45dc5972016-12-08 17:42:50 -08009233 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -08009234 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009235 if (!angle_stats_ready) {
9236 const int src_stride = x->plane[0].src.stride;
9237 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009238#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009239 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07009240 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009241 directional_mode_skip_mask);
9242 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009243#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07009244 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009245 directional_mode_skip_mask);
9246 angle_stats_ready = 1;
9247 }
9248 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -08009249 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07009250 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
9251 intra_mode_cost[mbmi->mode], best_rd,
9252 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009253 } else {
9254 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009255 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009256 }
9257#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009258 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08009259#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009260 rate_y = rd_stats_y.rate;
9261 distortion_y = rd_stats_y.dist;
9262 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009263
9264 if (rate_y == INT_MAX) continue;
9265
hui su5db97432016-10-14 16:10:14 -07009266#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009267 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -07009268#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009269
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009270 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
9271 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009272 if (rate_uv_intra[uv_tx] == INT_MAX) {
9273 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -07009274 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
9275 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009276#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009277 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009278#endif // CONFIG_PALETTE
9279
Yaowu Xuc27fc142016-08-22 16:08:15 -07009280#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009281 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
9282#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009283#if CONFIG_FILTER_INTRA
9284 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9285#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009286 }
9287
9288 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -07009289 distortion_uv = dist_uvs[uv_tx];
9290 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009291 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009292#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009293 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009294 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9295 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9296 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9297 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9298 }
Urvang Joshib100db72016-10-12 16:28:56 -07009299#endif // CONFIG_PALETTE
9300
Yaowu Xuc27fc142016-08-22 16:08:15 -07009301#if CONFIG_EXT_INTRA
9302 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009303#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009304#if CONFIG_FILTER_INTRA
9305 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9306 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9307 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9308 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9309 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
9310 }
9311#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009312
Jingning Han36fe3202017-02-20 22:31:49 -08009313#if CONFIG_CB4X4
9314 rate2 = rate_y + intra_mode_cost[mbmi->mode];
9315 if (!x->skip_chroma_rd)
9316 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
9317#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009318 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9319 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -08009320#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -08009321
Urvang Joshib100db72016-10-12 16:28:56 -07009322#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009323 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009324 rate2 += av1_cost_bit(
9325 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -07009326 }
Urvang Joshib100db72016-10-12 16:28:56 -07009327#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009328
Jingning Hanbf9c6b72016-12-14 14:50:45 -08009329 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009330 // super_block_yrd above includes the cost of the tx_size in the
9331 // tokenonly rate, but for intra blocks, tx_size is always coded
9332 // (prediction granularity), so we account for it in the full rate,
9333 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009334 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009335 }
9336#if CONFIG_EXT_INTRA
9337 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08009338#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07009339 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -07009340 const int p_angle =
9341 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07009342 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009343 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08009344#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07009345 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9346 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009347 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009348 if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
hui su0a6731f2017-04-26 15:23:47 -07009349 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9350 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009351 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009352#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009353#if CONFIG_FILTER_INTRA
9354 if (mbmi->mode == DC_PRED) {
9355 rate2 +=
9356 av1_cost_bit(cm->fc->filter_intra_probs[0],
9357 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9358 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
9359 rate2 += write_uniform_cost(
9360 FILTER_INTRA_MODES,
9361 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9362 }
9363 }
9364 if (mbmi->uv_mode == DC_PRED) {
9365 rate2 +=
9366 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9367 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9368 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9369 rate2 += write_uniform_cost(
9370 FILTER_INTRA_MODES,
9371 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
9372 }
9373#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -07009374 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009375 rate2 += intra_cost_penalty;
9376 distortion2 = distortion_y + distortion_uv;
Yushin Cho63927c42017-05-23 15:41:05 -07009377#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9378 if (bsize < BLOCK_8X8) distortion2_y = distortion_y;
9379#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009380 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009381 int_mv backup_ref_mv[2];
9382
Jingning Hanc41a5492017-02-24 11:18:52 -08009383#if !SUB8X8_COMP_REF
Jingning Han69d21012017-05-14 16:51:27 -07009384 if (bsize == BLOCK_4X4 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -08009385#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -08009386
Yaowu Xuc27fc142016-08-22 16:08:15 -07009387 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
9388 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yue Chen4d26acb2017-05-01 12:28:34 -07009389#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009390 if (second_ref_frame == INTRA_FRAME) {
9391 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -07009392 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -07009393// TODO(debargha|geza.lore):
9394// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -07009395#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009396 mbmi->angle_delta[0] = 0;
9397 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -08009398#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07009399 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08009400#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07009401#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009402#if CONFIG_FILTER_INTRA
9403 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
9404 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
9405#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009406 }
Yue Chen4d26acb2017-05-01 12:28:34 -07009407#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009408 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009409 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009410
David Barker404b2e82017-03-27 13:07:47 +01009411#if CONFIG_EXT_INTER
9412 if (comp_pred) {
9413 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +01009414 int ref_mv_idx = 0;
9415 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
9416 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
9417 // mbmi->ref_mv_idx (like NEWMV)
9418 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
9419 ref_mv_idx = 1;
9420
9421 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
9422 int_mv this_mv =
9423 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +01009424 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9425 xd->n8_h << MI_SIZE_LOG2, xd);
9426 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
9427 }
David Barker3dfba992017-04-03 16:10:09 +01009428 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
9429 int_mv this_mv =
9430 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +01009431 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9432 xd->n8_h << MI_SIZE_LOG2, xd);
9433 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
9434 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009435 }
David Barker404b2e82017-03-27 13:07:47 +01009436 } else {
9437#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -07009438 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01009439 int ref;
9440 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9441 int_mv this_mv =
9442 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
9443 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
9444 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9445 xd->n8_h << MI_SIZE_LOG2, xd);
9446 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9447 }
9448 }
9449#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009450 }
David Barker404b2e82017-03-27 13:07:47 +01009451#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08009452 {
9453 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
9454 av1_init_rd_stats(&rd_stats);
9455 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009456
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009457 // Point to variables that are maintained between loop iterations
9458 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009459#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009460 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009461 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009462#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009463 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
9464 &rd_stats_uv, &disable_skip, frame_mv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009465 mi_row, mi_col, &args, best_rd);
Angie Chiang76159122016-11-09 12:13:22 -08009466
9467 rate2 = rd_stats.rate;
9468 skippable = rd_stats.skip;
9469 distortion2 = rd_stats.dist;
9470 total_sse = rd_stats.sse;
9471 rate_y = rd_stats_y.rate;
9472 rate_uv = rd_stats_uv.rate;
Yushin Cho63927c42017-05-23 15:41:05 -07009473#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9474 if (bsize < BLOCK_8X8) distortion2_y = rd_stats_y.dist;
9475#endif
Angie Chiang76159122016-11-09 12:13:22 -08009476 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009477
David Barker404b2e82017-03-27 13:07:47 +01009478// TODO(jingning): This needs some refactoring to improve code quality
9479// and reduce redundant steps.
9480#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +01009481 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +01009482 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9483 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
9484 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
9485#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009486 if ((mbmi->mode == NEARMV &&
9487 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
9488 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
David Barker404b2e82017-03-27 13:07:47 +01009489#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009490 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
9491 MB_MODE_INFO backup_mbmi = *mbmi;
9492 int backup_skip = x->skip;
9493 int64_t tmp_ref_rd = this_rd;
9494 int ref_idx;
9495
Yue Chen6e601e92016-12-05 18:19:00 -08009496// TODO(jingning): This should be deprecated shortly.
9497#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +01009498 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -08009499#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009500 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -08009501#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009502 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -07009503 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009504
9505 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009506 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009507 // Dummy
9508 int_mv backup_fmv[2];
9509 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
9510 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
9511
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07009512 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513
9514 if (this_rd < INT64_MAX) {
9515 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
9516 RDCOST(x->rdmult, x->rddiv, 0, total_sse))
9517 tmp_ref_rd =
9518 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009519 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
Yaowu Xuc27fc142016-08-22 16:08:15 -07009520 distortion2);
9521 else
9522 tmp_ref_rd =
9523 RDCOST(x->rdmult, x->rddiv,
Yaowu Xuf883b422016-08-30 14:01:10 -07009524 rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
Yaowu Xuc27fc142016-08-22 16:08:15 -07009525 rate_y - rate_uv,
9526 total_sse);
9527 }
9528#if CONFIG_VAR_TX
9529 for (i = 0; i < MAX_MB_PLANE; ++i)
9530 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9531 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -08009532#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009533
9534 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
9535 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009536 int dummy_disable_skip = 0;
9537 int ref;
9538 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009539 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009540
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -08009541 av1_invalid_rd_stats(&tmp_rd_stats);
Jingning Han52617b22017-04-11 12:50:08 -07009542 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -08009543
Yaowu Xuc27fc142016-08-22 16:08:15 -07009544 mbmi->ref_mv_idx = 1 + ref_idx;
9545
David Barker3dfba992017-04-03 16:10:09 +01009546#if CONFIG_EXT_INTER
9547 if (comp_pred) {
9548 int ref_mv_idx = mbmi->ref_mv_idx;
9549 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
9550 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
9551 // mbmi->ref_mv_idx (like NEWMV)
9552 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
9553 ref_mv_idx = 1 + mbmi->ref_mv_idx;
9554
9555 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
9556 int_mv this_mv =
9557 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
9558 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9559 xd->n8_h << MI_SIZE_LOG2, xd);
9560 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
9561 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
9562 int_mv this_mv =
9563 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
9564 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9565 xd->n8_h << MI_SIZE_LOG2, xd);
9566 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
9567 }
9568
9569 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
9570 int_mv this_mv =
9571 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
9572 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9573 xd->n8_h << MI_SIZE_LOG2, xd);
9574 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
9575 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
9576 int_mv this_mv =
9577 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
9578 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9579 xd->n8_h << MI_SIZE_LOG2, xd);
9580 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
9581 }
9582 } else {
9583#endif // CONFIG_EXT_INTER
9584 for (ref = 0; ref < 1 + comp_pred; ++ref) {
9585 int_mv this_mv =
9586 (ref == 0)
9587 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9588 .this_mv
9589 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
9590 .comp_mv;
9591 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
9592 xd->n8_h << MI_SIZE_LOG2, xd);
9593 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
9594 }
9595#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009596 }
David Barker3dfba992017-04-03 16:10:09 +01009597#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009598
9599 cur_mv =
9600 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
9601 .this_mv;
9602 clamp_mv2(&cur_mv.as_mv, xd);
9603
Alex Converse0fa0f422017-04-24 12:51:14 -07009604 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009605 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009606#if CONFIG_EXT_INTER
9607 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -08009608#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009609
9610 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -08009611 av1_init_rd_stats(&tmp_rd_stats);
Fergus Simpson073c6f32017-02-17 12:13:48 -08009612
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009613 // Point to variables that are not maintained between iterations
9614 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009615#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009616 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009617 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009618#endif // CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009619 tmp_alt_rd = handle_inter_mode(
9620 cpi, x, bsize, &tmp_rd_stats, &tmp_rd_stats_y, &tmp_rd_stats_uv,
9621 &dummy_disable_skip, frame_mv, mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009622 // Prevent pointers from escaping local scope
9623 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009624#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009625 args.single_newmv_rate = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -08009626#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009627 }
9628
9629 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
9630 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009631 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9632 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -08009633 tmp_rd_stats.rate +=
9634 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
9635 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009636 }
9637
9638 if (mbmi_ext->ref_mv_count[ref_frame_type] >
9639 mbmi->ref_mv_idx + idx_offset + 1 &&
9640 ref_idx < ref_set - 1) {
9641 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07009642 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
9643 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -08009644 tmp_rd_stats.rate +=
9645 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
9646 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009647 }
9648
9649 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -07009650#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang76159122016-11-09 12:13:22 -08009651 tmp_alt_rd = RDCOST(x->rdmult, x->rddiv, tmp_rd_stats.rate,
9652 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009653#else
Angie Chiang76159122016-11-09 12:13:22 -08009654 if (RDCOST(x->rdmult, x->rddiv,
9655 tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
9656 tmp_rd_stats.dist) <
9657 RDCOST(x->rdmult, x->rddiv, 0, tmp_rd_stats.sse))
Yaowu Xuf883b422016-08-30 14:01:10 -07009658 tmp_alt_rd =
9659 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009660 tmp_rd_stats.rate +
9661 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
9662 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009663 else
Yaowu Xuf883b422016-08-30 14:01:10 -07009664 tmp_alt_rd =
9665 RDCOST(x->rdmult, x->rddiv,
Angie Chiang76159122016-11-09 12:13:22 -08009666 tmp_rd_stats.rate +
9667 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
9668 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
9669 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -07009670#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009671 }
9672
9673 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -08009674 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009675 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -08009676 distortion2 = tmp_rd_stats.dist;
9677 skippable = tmp_rd_stats.skip;
9678 rate_y = tmp_rd_stats_y.rate;
9679 rate_uv = tmp_rd_stats_uv.rate;
9680 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009681 this_rd = tmp_alt_rd;
9682 tmp_ref_rd = tmp_alt_rd;
9683 backup_mbmi = *mbmi;
9684 backup_skip = x->skip;
Yushin Cho63927c42017-05-23 15:41:05 -07009685#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9686 if (bsize < BLOCK_8X8) {
9687 total_sse_y = tmp_rd_stats_y.sse;
9688 distortion2_y = tmp_rd_stats_y.dist;
9689 }
9690#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009691#if CONFIG_VAR_TX
9692 for (i = 0; i < MAX_MB_PLANE; ++i)
9693 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
9694 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -08009695#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009696 } else {
9697 *mbmi = backup_mbmi;
9698 x->skip = backup_skip;
9699 }
9700 }
9701
9702 frame_mv[NEARMV][ref_frame] = backup_mv;
9703 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
9704 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
9705#if CONFIG_VAR_TX
9706 for (i = 0; i < MAX_MB_PLANE; ++i)
9707 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
9708 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -08009709#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009710 }
9711 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
9712 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009713
9714 if (this_rd == INT64_MAX) continue;
9715
Jingning Hanc41a5492017-02-24 11:18:52 -08009716#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -07009717 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -08009718#else
Jingning Han69d21012017-05-14 16:51:27 -07009719 if (mbmi->sb_type != BLOCK_4X4)
Jingning Hanc41a5492017-02-24 11:18:52 -08009720 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -08009721#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009722
9723 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
9724 }
9725
Yaowu Xuc27fc142016-08-22 16:08:15 -07009726 // Estimate the reference frame signaling cost and add it
9727 // to the rolling cost variable.
9728 if (comp_pred) {
9729 rate2 += ref_costs_comp[ref_frame];
9730#if CONFIG_EXT_REFS
9731 rate2 += ref_costs_comp[second_ref_frame];
9732#endif // CONFIG_EXT_REFS
9733 } else {
9734 rate2 += ref_costs_single[ref_frame];
9735 }
9736
Yue Chen69f18e12016-09-08 14:48:15 -07009737#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009738 if (ref_frame == INTRA_FRAME) {
9739#else
9740 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -07009741#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009742 if (skippable) {
9743 // Back out the coefficient coding costs
9744 rate2 -= (rate_y + rate_uv);
9745 rate_y = 0;
9746 rate_uv = 0;
9747 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -07009748 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009749 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009750 if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
9751 distortion2) <
9752 RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009753 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009754 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009755 } else {
9756 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -07009757 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009758 distortion2 = total_sse;
9759 assert(total_sse >= 0);
9760 rate2 -= (rate_y + rate_uv);
9761 this_skip2 = 1;
9762 rate_y = 0;
9763 rate_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -07009764#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9765 if (bsize < BLOCK_8X8) distortion2_y = total_sse_y;
9766#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009767 }
9768 } else {
9769 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -07009770 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009771 }
9772
9773 // Calculate the final RD estimate for this mode.
9774 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -07009775#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009776 } else {
9777 this_skip2 = mbmi->skip;
9778 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
9779 if (this_skip2) {
9780 rate_y = 0;
9781 rate_uv = 0;
9782 }
Yue Chen69f18e12016-09-08 14:48:15 -07009783#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009784 }
9785
Yaowu Xuc27fc142016-08-22 16:08:15 -07009786 if (ref_frame == INTRA_FRAME) {
9787 // Keep record of best intra rd
9788 if (this_rd < best_intra_rd) {
9789 best_intra_rd = this_rd;
9790 best_intra_mode = mbmi->mode;
9791 }
Yue Chen4d26acb2017-05-01 12:28:34 -07009792#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Emil Keyder01770b32017-01-20 18:03:11 -05009793 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009794 if (this_rd < best_single_inter_rd) {
9795 best_single_inter_rd = this_rd;
9796 best_single_inter_ref = mbmi->ref_frame[0];
9797 }
Yue Chen4d26acb2017-05-01 12:28:34 -07009798#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009799 }
9800
9801 if (!disable_skip && ref_frame == INTRA_FRAME) {
9802 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009803 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009804 }
9805
9806 // Did this mode help.. i.e. is it the new best mode
9807 if (this_rd < best_rd || x->skip) {
9808 if (!mode_excluded) {
9809 // Note index of best mode so far
9810 best_mode_index = mode_index;
9811
9812 if (ref_frame == INTRA_FRAME) {
9813 /* required for left and above block mv */
9814 mbmi->mv[0].as_int = 0;
9815 } else {
9816 best_pred_sse = x->pred_sse[ref_frame];
9817 }
9818
9819 rd_cost->rate = rate2;
9820#if CONFIG_SUPERTX
9821 if (x->skip)
9822 *returnrate_nocoef = rate2;
9823 else
9824 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009825 *returnrate_nocoef -= av1_cost_bit(
9826 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
9827 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9828 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -07009829#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -07009830#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
9831 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -08009832 const MOTION_MODE motion_allowed = motion_mode_allowed(
9833#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
9834 0, xd->global_motion,
9835#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
9836 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -08009837 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -07009838 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -08009839 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -07009840 *returnrate_nocoef -=
9841 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -07009842#else
9843 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -07009844#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07009845#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009846#endif // CONFIG_SUPERTX
9847 rd_cost->dist = distortion2;
9848 rd_cost->rdcost = this_rd;
9849 best_rd = this_rd;
9850 best_mbmode = *mbmi;
9851 best_skip2 = this_skip2;
9852 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -07009853 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
9854 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009855 best_rate_uv = rate_uv;
Yushin Cho63927c42017-05-23 15:41:05 -07009856#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9857 if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2_y;
9858#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009859#if CONFIG_VAR_TX
9860 for (i = 0; i < MAX_MB_PLANE; ++i)
9861 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9862 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -08009863#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009864 }
9865 }
9866
9867 /* keep record of best compound/single-only prediction */
9868 if (!disable_skip && ref_frame != INTRA_FRAME) {
9869 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
9870
9871 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
9872 single_rate = rate2 - compmode_cost;
9873 hybrid_rate = rate2;
9874 } else {
9875 single_rate = rate2;
9876 hybrid_rate = rate2 + compmode_cost;
9877 }
9878
9879 single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
9880 hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
9881
9882 if (!comp_pred) {
9883 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
9884 best_pred_rd[SINGLE_REFERENCE] = single_rd;
9885 } else {
9886 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
9887 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
9888 }
9889 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
9890 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
9891 }
9892
Yaowu Xuc27fc142016-08-22 16:08:15 -07009893 if (x->skip && !comp_pred) break;
9894 }
9895
9896 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
9897 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
9898 is_inter_mode(best_mbmode.mode)) ||
9899 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
9900 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009901 int skip_blk = 0;
9902 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009903
9904 x->use_default_inter_tx_type = 0;
9905 x->use_default_intra_tx_type = 0;
9906
9907 *mbmi = best_mbmode;
9908
9909 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
9910
9911 // Select prediction reference frames.
9912 for (i = 0; i < MAX_MB_PLANE; i++) {
9913 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
9914 if (has_second_ref(mbmi))
9915 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
9916 }
9917
9918 if (is_inter_mode(mbmi->mode)) {
Jingning Hanc44009c2017-05-06 11:36:49 -07009919 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -07009920#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -08009921 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009922 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009923 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
9924 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -08009925 }
Yue Chencb60b182016-10-13 15:18:22 -07009926#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009927 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009928#if CONFIG_VAR_TX
9929 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -07009930 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009931 } else {
9932 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009933 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009934 for (idy = 0; idy < xd->n8_h; ++idy)
9935 for (idx = 0; idx < xd->n8_w; ++idx)
9936 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009937 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009938 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
9939 }
9940
Angie Chiangb5dda482016-11-02 16:19:58 -07009941 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009942#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009943 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009944 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009945#endif // CONFIG_VAR_TX
9946 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009947 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -08009948 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009949 }
9950
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009951 if (RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9952 (rd_stats_y.dist + rd_stats_uv.dist)) >
9953 RDCOST(x->rdmult, x->rddiv, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009954 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009955 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9956 rd_stats_uv.rate = 0;
9957 rd_stats_y.dist = rd_stats_y.sse;
9958 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009959 } else {
9960 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009961 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009962 }
9963
9964 if (RDCOST(x->rdmult, x->rddiv, best_rate_y + best_rate_uv, rd_cost->dist) >
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009965 RDCOST(x->rdmult, x->rddiv, rd_stats_y.rate + rd_stats_uv.rate,
9966 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009967#if CONFIG_VAR_TX
9968 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -08009969#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07009970 best_mbmode.tx_type = mbmi->tx_type;
9971 best_mbmode.tx_size = mbmi->tx_size;
9972#if CONFIG_VAR_TX
9973 for (idy = 0; idy < xd->n8_h; ++idy)
9974 for (idx = 0; idx < xd->n8_w; ++idx)
9975 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
9976
9977 for (i = 0; i < MAX_MB_PLANE; ++i)
9978 memcpy(ctx->blk_skip[i], x->blk_skip[i],
9979 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07009980
9981 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -08009982#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009983 rd_cost->rate +=
9984 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
9985 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Yushin Cho63927c42017-05-23 15:41:05 -07009986#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9987 if (bsize < BLOCK_8X8) rd_cost->dist_y = rd_stats_y.dist;
9988#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009989 rd_cost->rdcost =
9990 RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
9991 best_skip2 = skip_blk;
9992 }
9993 }
9994
Urvang Joshib100db72016-10-12 16:28:56 -07009995#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009996 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -07009997 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08009998 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009999#if CONFIG_SUPERTX
10000 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010001#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080010002 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
10003 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070010004 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010005 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080010006 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010007 uint8_t *const best_palette_color_map =
10008 x->palette_buffer->best_palette_color_map;
10009 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080010010 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010011
10012 mbmi->mode = DC_PRED;
10013 mbmi->uv_mode = DC_PRED;
10014 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010015 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070010016 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080010017 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
10018 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
10019 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080010020 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
10021 memcpy(color_map, best_palette_color_map,
10022 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010023 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
10024 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010025 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
10026 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010027 if (rate_uv_intra[uv_tx] == INT_MAX) {
10028 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010029 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10030 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010031 pmi_uv[uv_tx] = *pmi;
10032#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010033 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10034#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010035#if CONFIG_FILTER_INTRA
10036 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10037#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010038 }
10039 mbmi->uv_mode = mode_uv[uv_tx];
10040 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080010041 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010042 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10043 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10044 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080010045 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010046#if CONFIG_EXT_INTRA
10047 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010048#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010049#if CONFIG_FILTER_INTRA
10050 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10051 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10052 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10053 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10054 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10055 }
10056#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010057 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
10058 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
10059 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010060 rate2 += ref_costs_single[INTRA_FRAME];
10061
10062 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010063 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010064#if CONFIG_SUPERTX
10065 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080010066#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010067 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010068 } else {
10069#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010070 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080010071#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070010072 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010073 }
10074 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10075 if (this_rd < best_rd) {
10076 best_mode_index = 3;
10077 mbmi->mv[0].as_int = 0;
10078 rd_cost->rate = rate2;
10079#if CONFIG_SUPERTX
10080 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080010081#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010082 rd_cost->dist = distortion2;
10083 rd_cost->rdcost = this_rd;
10084 best_rd = this_rd;
10085 best_mbmode = *mbmi;
10086 best_skip2 = 0;
10087 best_mode_skippable = skippable;
10088 }
10089 }
10090PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070010091#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010092
hui su5db97432016-10-14 16:10:14 -070010093#if CONFIG_FILTER_INTRA
10094 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070010095 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070010096 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070010097#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080010098 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070010099#endif // CONFIG_PALETTE
10100 !dc_skipped && best_mode_index >= 0 &&
10101 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070010102 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080010103 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
10104 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070010105#if CONFIG_EXT_INTRA
10106 uv_angle_delta,
10107#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070010108#if CONFIG_PALETTE
10109 pmi_uv, palette_ctx,
10110#endif // CONFIG_PALETTE
10111 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010112 &best_mode_index, &best_skip2, &best_mode_skippable,
10113#if CONFIG_SUPERTX
10114 returnrate_nocoef,
10115#endif // CONFIG_SUPERTX
10116 best_pred_rd, &best_mbmode, rd_cost);
10117 }
hui su5db97432016-10-14 16:10:14 -070010118#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010119
10120 // The inter modes' rate costs are not calculated precisely in some cases.
10121 // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
10122 // ZEROMV. Here, checks are added for those cases, and the mode decisions
10123 // are corrected.
10124 if (best_mbmode.mode == NEWMV
10125#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010126 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070010127#endif // CONFIG_EXT_INTER
10128 ) {
10129 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10130 best_mbmode.ref_frame[1] };
10131 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070010132 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070010133 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070010134#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080010135 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
10136 cm->allow_high_precision_mv, bsize,
10137 mi_col, mi_row, 0)
10138 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080010139 zeromv[1].as_int = comp_pred_mode
10140 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
10141 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080010142 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080010143 .as_int
10144 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010145#else
10146 zeromv[0].as_int = 0;
10147 zeromv[1].as_int = 0;
10148#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010149 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010150 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010151 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010152 : INT_MAX;
10153
10154 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10155 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10156 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
10157 best_mbmode.mode = NEARMV;
10158 best_mbmode.ref_mv_idx = i;
10159 }
10160 }
10161
10162 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
10163 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070010164 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165 best_mbmode.mode = ZEROMV;
10166 } else {
10167 int_mv nearestmv[2];
10168 int_mv nearmv[2];
10169
10170#if CONFIG_EXT_INTER
10171 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
10172 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
10173 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
10174 } else {
10175 nearmv[0] = frame_mv[NEARMV][refs[0]];
10176 nearmv[1] = frame_mv[NEARMV][refs[1]];
10177 }
10178#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010179 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070010180 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010181 : INT_MAX;
10182
10183 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10184 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10185 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
10186
10187 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
10188 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
10189 best_mbmode.mode = NEARMV;
10190 best_mbmode.ref_mv_idx = i;
10191 }
10192 }
Fergus Simpson4063a682017-02-28 16:52:22 -080010193#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010194 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
10195 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
10196 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
10197 } else {
10198 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
10199 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
10200 }
10201
10202 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010010203 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010204#if CONFIG_EXT_INTER
10205 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010010206 } else {
10207 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
10208 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
10209 : INT_MAX;
10210
10211 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
10212 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
10213 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
10214
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -070010215 // Try switching to the NEAR_NEARMV mode
10216 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010010217 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
10218 best_mbmode.mode = NEAR_NEARMV;
10219 best_mbmode.ref_mv_idx = i;
10220 }
10221 }
10222
David Barker3dfba992017-04-03 16:10:09 +010010223 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010010224 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10225 best_mbmode.mv[1].as_int == zeromv[1].as_int)
10226 best_mbmode.mode = ZERO_ZEROMV;
10227 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010228#else
10229 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010010230 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10231 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010232 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010010233 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010234#endif // CONFIG_EXT_INTER
10235 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010236 }
10237
David Barker9620bcd2017-03-22 14:46:42 +000010238 // Make sure that the ref_mv_idx is only nonzero when we're
10239 // using a mode which can support ref_mv_idx
10240 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010010241#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010242 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
10243 have_nearmv_in_inter_mode(best_mbmode.mode))) {
David Barker404b2e82017-03-27 13:07:47 +010010244#else
David Barker9620bcd2017-03-22 14:46:42 +000010245 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
David Barker404b2e82017-03-27 13:07:47 +010010246#endif
David Barker9620bcd2017-03-22 14:46:42 +000010247 best_mbmode.ref_mv_idx = 0;
10248 }
10249
David Barkercdcac6d2016-12-01 17:04:16 +000010250 {
Jingning Han731af492016-11-17 11:53:23 -080010251 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
10252 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000010253 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000010254 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000010255#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000010256 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
10257 best_mbmode.ref_frame[1] };
10258 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000010259 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080010260 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000010261 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070010262 zeromv[1].as_int = (refs[1] != NONE_FRAME)
10263 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
10264 cm->allow_high_precision_mv,
10265 bsize, mi_col, mi_row, 0)
10266 .as_int
10267 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000010268 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
10269 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
10270#else
10271 zeromv[0].as_int = zeromv[1].as_int = 0;
10272#endif // CONFIG_GLOBAL_MOTION
10273 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
10274 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
10275#if CONFIG_EXT_INTER
10276 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
10277#else
Emil Keyder01770b32017-01-20 18:03:11 -050010278 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000010279 best_mbmode.mv[1].as_int == zeromv[1].as_int)
10280#endif // CONFIG_EXT_INTER
10281 ) {
10282 best_mbmode.mode = ZEROMV;
10283 }
David Barker68e6e862016-11-24 15:10:15 +000010284 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010285 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010286
10287 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
10288 rd_cost->rate = INT_MAX;
10289 rd_cost->rdcost = INT64_MAX;
10290 return;
10291 }
10292
Yaowu Xuc27fc142016-08-22 16:08:15 -070010293#if CONFIG_DUAL_FILTER
10294 assert((cm->interp_filter == SWITCHABLE) ||
10295 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
10296 !is_inter_block(&best_mbmode));
10297 assert((cm->interp_filter == SWITCHABLE) ||
10298 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
10299 !is_inter_block(&best_mbmode));
10300 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
10301 assert((cm->interp_filter == SWITCHABLE) ||
10302 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
10303 !is_inter_block(&best_mbmode));
10304 assert((cm->interp_filter == SWITCHABLE) ||
10305 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
10306 !is_inter_block(&best_mbmode));
10307 }
10308#else
10309 assert((cm->interp_filter == SWITCHABLE) ||
10310 (cm->interp_filter == best_mbmode.interp_filter) ||
10311 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080010312#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010313
10314 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070010315 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10316 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010317
10318 // macroblock modes
10319 *mbmi = best_mbmode;
10320 x->skip |= best_skip2;
10321
Yue Chen19e7aa82016-11-30 14:05:39 -080010322// Note: this section is needed since the mode may have been forced to
10323// ZEROMV by the all-zero mode handling of ref-mv.
10324#if CONFIG_GLOBAL_MOTION
10325 if (mbmi->mode == ZEROMV
10326#if CONFIG_EXT_INTER
10327 || mbmi->mode == ZERO_ZEROMV
10328#endif // CONFIG_EXT_INTER
10329 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080010330#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
10331 // Correct the motion mode for ZEROMV
10332 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
10333#if SEPARATE_GLOBAL_MOTION
10334 0, xd->global_motion,
10335#endif // SEPARATE_GLOBAL_MOTION
10336 xd->mi[0]);
10337 if (mbmi->motion_mode > last_motion_mode_allowed)
10338 mbmi->motion_mode = last_motion_mode_allowed;
10339#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
10340
10341 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080010342 if (is_nontrans_global_motion(xd)) {
10343#if CONFIG_DUAL_FILTER
10344 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
10345 ? EIGHTTAP_REGULAR
10346 : cm->interp_filter;
10347 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
10348 ? EIGHTTAP_REGULAR
10349 : cm->interp_filter;
10350#else
10351 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
10352 : cm->interp_filter;
10353#endif // CONFIG_DUAL_FILTER
10354 }
10355 }
10356#endif // CONFIG_GLOBAL_MOTION
10357
Yaowu Xuc27fc142016-08-22 16:08:15 -070010358 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
10359 if (mbmi->mode != NEWMV)
10360 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
10361 else
10362 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
10363 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010364
10365 for (i = 0; i < REFERENCE_MODES; ++i) {
10366 if (best_pred_rd[i] == INT64_MAX)
10367 best_pred_diff[i] = INT_MIN;
10368 else
10369 best_pred_diff[i] = best_rd - best_pred_rd[i];
10370 }
10371
10372 x->skip |= best_mode_skippable;
10373
10374 assert(best_mode_index >= 0);
10375
10376 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
10377 best_mode_skippable);
10378
Urvang Joshib100db72016-10-12 16:28:56 -070010379#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010380 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
10381 restore_uv_color_map(cpi, x);
10382 }
Urvang Joshib100db72016-10-12 16:28:56 -070010383#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010384}
10385
Urvang Joshi52648442016-10-13 17:27:51 -070010386void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
10387 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000010388 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070010389 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070010390 PICK_MODE_CONTEXT *ctx,
10391 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070010392 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010393 MACROBLOCKD *const xd = &x->e_mbd;
10394 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10395 unsigned char segment_id = mbmi->segment_id;
10396 const int comp_pred = 0;
10397 int i;
10398 int64_t best_pred_diff[REFERENCE_MODES];
10399 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
10400 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Yaowu Xuf883b422016-08-30 14:01:10 -070010401 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070010402 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010403 int64_t this_rd = INT64_MAX;
10404 int rate2 = 0;
10405 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000010406 (void)mi_row;
10407 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010408
10409 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
10410 &comp_mode_p);
10411
10412 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
10413 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
10414 x->pred_mv_sad[i] = INT_MAX;
10415
10416 rd_cost->rate = INT_MAX;
10417
10418 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
10419
Urvang Joshib100db72016-10-12 16:28:56 -070010420#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010421 mbmi->palette_mode_info.palette_size[0] = 0;
10422 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010423#endif // CONFIG_PALETTE
10424
hui su5db97432016-10-14 16:10:14 -070010425#if CONFIG_FILTER_INTRA
10426 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10427 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10428#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010429 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070010430 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010431 mbmi->uv_mode = DC_PRED;
10432 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050010433 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070010434#if CONFIG_GLOBAL_MOTION
10435 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080010436 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080010437 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
10438 0)
David Barkercdcac6d2016-12-01 17:04:16 +000010439 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070010440#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010441 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070010442#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070010443 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070010444 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070010445
Yaowu Xuc27fc142016-08-22 16:08:15 -070010446 mbmi->ref_mv_idx = 0;
10447 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010448
Yue Chendead17d2017-04-20 16:19:39 -070010449 mbmi->motion_mode = SIMPLE_TRANSLATION;
10450#if CONFIG_MOTION_VAR
10451 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
10452#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070010453#if CONFIG_WARPED_MOTION
10454 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
10455 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
10456 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
10457 }
10458#endif
Yue Chendead17d2017-04-20 16:19:39 -070010459
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010460 set_default_interp_filters(mbmi, cm->interp_filter);
10461
10462 if (cm->interp_filter != SWITCHABLE) {
10463 best_filter = cm->interp_filter;
10464 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010465 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010466 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070010467 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
10468 int rs;
10469 int best_rs = INT_MAX;
10470 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
10471#if CONFIG_DUAL_FILTER
10472 int k;
10473 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
10474#else
10475 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080010476#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070010477 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010478 if (rs < best_rs) {
10479 best_rs = rs;
10480#if CONFIG_DUAL_FILTER
10481 best_filter = mbmi->interp_filter[0];
10482#else
10483 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080010484#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010485 }
10486 }
10487 }
10488 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010489// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070010490#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010491 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010492#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010493 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080010494#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010495 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010496
10497 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070010498 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010499
10500 // Estimate the reference frame signaling cost and add it
10501 // to the rolling cost variable.
10502 rate2 += ref_costs_single[LAST_FRAME];
10503 this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
10504
10505 rd_cost->rate = rate2;
10506 rd_cost->dist = distortion2;
10507 rd_cost->rdcost = this_rd;
Yushin Cho63927c42017-05-23 15:41:05 -070010508#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10509 if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2;
10510#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010511 if (this_rd >= best_rd_so_far) {
10512 rd_cost->rate = INT_MAX;
10513 rd_cost->rdcost = INT64_MAX;
10514 return;
10515 }
10516
10517#if CONFIG_DUAL_FILTER
10518 assert((cm->interp_filter == SWITCHABLE) ||
10519 (cm->interp_filter == mbmi->interp_filter[0]));
10520#else
10521 assert((cm->interp_filter == SWITCHABLE) ||
10522 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080010523#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010524
Yaowu Xuf883b422016-08-30 14:01:10 -070010525 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
10526 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010527
Yaowu Xuf883b422016-08-30 14:01:10 -070010528 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010529
10530 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
10531}
10532
Yue Chencb60b182016-10-13 15:18:22 -070010533#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010534// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070010535//
10536// The OBMC predictor is computed as:
10537//
10538// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010539// AOM_BLEND_A64(Mh(x),
10540// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070010541// PLeft(x, y))
10542//
Yaowu Xuf883b422016-08-30 14:01:10 -070010543// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070010544// rounding, this can be written as:
10545//
Yaowu Xuf883b422016-08-30 14:01:10 -070010546// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010547// Mh(x) * Mv(y) * P(x,y) +
10548// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010549// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010550//
10551// Where :
10552//
Yaowu Xuf883b422016-08-30 14:01:10 -070010553// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
10554// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010555//
10556// This function computes 'wsrc' and 'mask' as:
10557//
10558// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010559// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070010560// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070010561// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010562//
10563// mask(x, y) = Mh(x) * Mv(y)
10564//
10565// These can then be used to efficiently approximate the error for any
10566// predictor P in the context of the provided neighbouring predictors by
10567// computing:
10568//
10569// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070010570// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010571//
Yaowu Xuf883b422016-08-30 14:01:10 -070010572static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010573 const MACROBLOCKD *xd, int mi_row,
10574 int mi_col, const uint8_t *above,
10575 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070010576 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010577 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
10578 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080010579 const int bw = xd->n8_w << MI_SIZE_LOG2;
10580 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070010581 int32_t *mask_buf = x->mask_buf;
10582 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010583 const int wsrc_stride = bw;
10584 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070010585 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010586#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010587 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
10588#else
10589 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010590#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010591
10592 // plane 0 should not be subsampled
10593 assert(xd->plane[0].subsampling_x == 0);
10594 assert(xd->plane[0].subsampling_y == 0);
10595
Yaowu Xuf883b422016-08-30 14:01:10 -070010596 av1_zero_array(wsrc_buf, bw * bh);
10597 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010598
10599 // handle above row
10600 if (xd->up_available) {
10601 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010602 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010603 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010604 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070010605 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
10606 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010607
10608 assert(miw > 0);
10609
10610 i = 0;
10611 do { // for each mi in the above row
10612 const int mi_col_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070010613 const MB_MODE_INFO *above_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010614 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070010615#if CONFIG_CHROMA_SUB8X8
10616 if (above_mbmi->sb_type < BLOCK_8X8)
10617 above_mbmi =
10618 &xd->mi[mi_col_offset + 1 + mi_row_offset * xd->mi_stride]->mbmi;
10619#endif
Jingning Han680b09e2017-05-22 16:42:36 -070010620 const BLOCK_SIZE a_bsize = AOMMAX(above_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070010621 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010622 const int neighbor_bw = mi_step * MI_SIZE;
10623
10624 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070010625 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
10626 neighbor_count += 2;
10627 else
10628 neighbor_count++;
10629 if (neighbor_count > neighbor_limit) break;
10630
Yaowu Xuc27fc142016-08-22 16:08:15 -070010631 const int tmp_stride = above_stride;
10632 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
10633 int32_t *mask = mask_buf + (i * MI_SIZE);
10634
10635 if (!is_hbd) {
10636 const uint8_t *tmp = above;
10637
10638 for (row = 0; row < overlap; ++row) {
10639 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010640 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010641 for (col = 0; col < neighbor_bw; ++col) {
10642 wsrc[col] = m1 * tmp[col];
10643 mask[col] = m0;
10644 }
10645 wsrc += wsrc_stride;
10646 mask += mask_stride;
10647 tmp += tmp_stride;
10648 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010649#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010650 } else {
10651 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
10652
10653 for (row = 0; row < overlap; ++row) {
10654 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070010655 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010656 for (col = 0; col < neighbor_bw; ++col) {
10657 wsrc[col] = m1 * tmp[col];
10658 mask[col] = m0;
10659 }
10660 wsrc += wsrc_stride;
10661 mask += mask_stride;
10662 tmp += tmp_stride;
10663 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010664#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010665 }
10666 }
10667
10668 above += neighbor_bw;
10669 i += mi_step;
10670 } while (i < miw);
10671 }
10672
10673 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010674 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
10675 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010676 }
10677
10678 // handle left column
10679 if (xd->left_available) {
10680 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070010681 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010682 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070010683 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070010684 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
10685 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010686
10687 assert(mih > 0);
10688
10689 i = 0;
10690 do { // for each mi in the left column
10691 const int mi_row_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070010692 MB_MODE_INFO *left_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070010693 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070010694
10695#if CONFIG_CHROMA_SUB8X8
10696 if (left_mbmi->sb_type < BLOCK_8X8)
10697 left_mbmi =
10698 &xd->mi[mi_col_offset + (mi_row_offset + 1) * xd->mi_stride]->mbmi;
10699#endif
Jingning Han680b09e2017-05-22 16:42:36 -070010700 const BLOCK_SIZE l_bsize = AOMMAX(left_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070010701 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010702 const int neighbor_bh = mi_step * MI_SIZE;
10703
10704 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070010705 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
10706 neighbor_count += 2;
10707 else
10708 neighbor_count++;
10709 if (neighbor_count > neighbor_limit) break;
10710
Yaowu Xuc27fc142016-08-22 16:08:15 -070010711 const int tmp_stride = left_stride;
10712 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
10713 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
10714
10715 if (!is_hbd) {
10716 const uint8_t *tmp = left;
10717
10718 for (row = 0; row < neighbor_bh; ++row) {
10719 for (col = 0; col < overlap; ++col) {
10720 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010721 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10722 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10723 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10724 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010725 }
10726 wsrc += wsrc_stride;
10727 mask += mask_stride;
10728 tmp += tmp_stride;
10729 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010730#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010731 } else {
10732 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
10733
10734 for (row = 0; row < neighbor_bh; ++row) {
10735 for (col = 0; col < overlap; ++col) {
10736 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070010737 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
10738 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
10739 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
10740 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010741 }
10742 wsrc += wsrc_stride;
10743 mask += mask_stride;
10744 tmp += tmp_stride;
10745 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010746#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010747 }
10748 }
10749
10750 left += neighbor_bh * left_stride;
10751 i += mi_step;
10752 } while (i < mih);
10753 }
10754
10755 if (!is_hbd) {
10756 const uint8_t *src = x->plane[0].src.buf;
10757
10758 for (row = 0; row < bh; ++row) {
10759 for (col = 0; col < bw; ++col) {
10760 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10761 }
10762 wsrc_buf += wsrc_stride;
10763 src += x->plane[0].src.stride;
10764 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010765#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010766 } else {
10767 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
10768
10769 for (row = 0; row < bh; ++row) {
10770 for (col = 0; col < bw; ++col) {
10771 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
10772 }
10773 wsrc_buf += wsrc_stride;
10774 src += x->plane[0].src.stride;
10775 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010776#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010777 }
10778}
Yue Chenf27b1602017-01-13 11:11:43 -080010779
10780#if CONFIG_NCOBMC
10781void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
10782 int mi_row, int mi_col) {
10783 const AV1_COMMON *const cm = &cpi->common;
10784 MACROBLOCKD *const xd = &x->e_mbd;
10785 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
10786 MB_MODE_INFO backup_mbmi;
10787 BLOCK_SIZE bsize = mbmi->sb_type;
10788 int ref, skip_blk, backup_skip = x->skip;
10789 int64_t rd_causal;
10790 RD_STATS rd_stats_y, rd_stats_uv;
10791 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
10792 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10793
10794 // Recompute the best causal predictor and rd
10795 mbmi->motion_mode = SIMPLE_TRANSLATION;
10796 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10797 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
10798 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
10799 assert(cfg != NULL);
10800 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
10801 &xd->block_refs[ref]->sf);
10802 }
Jingning Han91d9a792017-04-18 12:01:52 -070010803 av1_setup_dst_planes(x->e_mbd.plane, bsize,
10804 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080010805
Jingning Hanc44009c2017-05-06 11:36:49 -070010806 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chenf27b1602017-01-13 11:11:43 -080010807
10808 av1_subtract_plane(x, bsize, 0);
10809 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
10810 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
10811 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
10812 if (rd_stats_y.skip && rd_stats_uv.skip) {
10813 rd_stats_y.rate = rate_skip1;
10814 rd_stats_uv.rate = 0;
10815 rd_stats_y.dist = rd_stats_y.sse;
10816 rd_stats_uv.dist = rd_stats_uv.sse;
10817 skip_blk = 0;
10818 } else if (RDCOST(x->rdmult, x->rddiv,
10819 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
10820 (rd_stats_y.dist + rd_stats_uv.dist)) >
10821 RDCOST(x->rdmult, x->rddiv, rate_skip1,
10822 (rd_stats_y.sse + rd_stats_uv.sse))) {
10823 rd_stats_y.rate = rate_skip1;
10824 rd_stats_uv.rate = 0;
10825 rd_stats_y.dist = rd_stats_y.sse;
10826 rd_stats_uv.dist = rd_stats_uv.sse;
10827 skip_blk = 1;
10828 } else {
10829 rd_stats_y.rate += rate_skip0;
10830 skip_blk = 0;
10831 }
10832 backup_skip = skip_blk;
10833 backup_mbmi = *mbmi;
10834 rd_causal = RDCOST(x->rdmult, x->rddiv, (rd_stats_y.rate + rd_stats_uv.rate),
10835 (rd_stats_y.dist + rd_stats_uv.dist));
10836 rd_causal += RDCOST(x->rdmult, x->rddiv,
10837 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
10838
10839 // Check non-causal mode
10840 mbmi->motion_mode = OBMC_CAUSAL;
10841 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
10842
10843 av1_subtract_plane(x, bsize, 0);
10844 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
10845 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
10846 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
10847 if (rd_stats_y.skip && rd_stats_uv.skip) {
10848 rd_stats_y.rate = rate_skip1;
10849 rd_stats_uv.rate = 0;
10850 rd_stats_y.dist = rd_stats_y.sse;
10851 rd_stats_uv.dist = rd_stats_uv.sse;
10852 skip_blk = 0;
10853 } else if (RDCOST(x->rdmult, x->rddiv,
10854 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
10855 (rd_stats_y.dist + rd_stats_uv.dist)) >
10856 RDCOST(x->rdmult, x->rddiv, rate_skip1,
10857 (rd_stats_y.sse + rd_stats_uv.sse))) {
10858 rd_stats_y.rate = rate_skip1;
10859 rd_stats_uv.rate = 0;
10860 rd_stats_y.dist = rd_stats_y.sse;
10861 rd_stats_uv.dist = rd_stats_uv.sse;
10862 skip_blk = 1;
10863 } else {
10864 rd_stats_y.rate += rate_skip0;
10865 skip_blk = 0;
10866 }
10867
10868 if (rd_causal >
10869 RDCOST(x->rdmult, x->rddiv,
10870 rd_stats_y.rate + rd_stats_uv.rate +
10871 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
10872 (rd_stats_y.dist + rd_stats_uv.dist))) {
10873 x->skip = skip_blk;
10874 } else {
10875 *mbmi = backup_mbmi;
10876 x->skip = backup_skip;
10877 }
10878}
Fergus Simpson4063a682017-02-28 16:52:22 -080010879#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070010880#endif // CONFIG_MOTION_VAR