blob: e7bedcc13565b06fa66bd985650141a667421f6f [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
Zoe Liuc082bbc2017-05-17 13:31:37 -0700116#if CONFIG_EXT_COMP_REFS
117#define SECOND_REF_FRAME_MASK \
118 ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | (1 << GOLDEN_FRAME) | \
119 (1 << LAST2_FRAME) | 0x01) // NOLINT
120#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | (1 << BWDREF_FRAME) | 0x01)
Zoe Liuc082bbc2017-05-17 13:31:37 -0700122#endif // CONFIG_EXT_COMP_REFS
123#else // !CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01)
125#endif // CONFIG_EXT_REFS
126
127#define MIN_EARLY_TERM_INDEX 3
128#define NEW_MV_DISCOUNT_FACTOR 8
129
130#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700131#define ANGLE_SKIP_THRESH 10
132#define FILTER_FAST_SEARCH 1
133#endif // CONFIG_EXT_INTRA
134
Sarah Parker345366a2017-06-15 12:13:01 -0700135// Setting this to 1 will disable trellis optimization within the
136// transform search. Trellis optimization will still be applied
137// in the final encode.
138#define DISABLE_TRELLISQ_SEARCH 0
139
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140const double ADST_FLIP_SVM[8] = { -6.6623, -2.8062, -3.2531, 3.1671, // vert
141 -7.7051, -3.2234, -3.6193, 3.4533 }; // horz
142
143typedef struct {
144 PREDICTION_MODE mode;
145 MV_REFERENCE_FRAME ref_frame[2];
146} MODE_DEFINITION;
147
148typedef struct { MV_REFERENCE_FRAME ref_frame[2]; } REF_DEFINITION;
149
150struct rdcost_block_args {
Yaowu Xuf883b422016-08-30 14:01:10 -0700151 const AV1_COMP *cpi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700152 MACROBLOCK *x;
153 ENTROPY_CONTEXT t_above[2 * MAX_MIB_SIZE];
154 ENTROPY_CONTEXT t_left[2 * MAX_MIB_SIZE];
Angie Chiang7c2b7f22016-11-07 16:00:00 -0800155 RD_STATS rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156 int64_t this_rd;
157 int64_t best_rd;
158 int exit_early;
159 int use_fast_coef_costing;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160};
161
162#define LAST_NEW_MV_INDEX 6
Yaowu Xuf883b422016-08-30 14:01:10 -0700163static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
Emil Keyder01770b32017-01-20 18:03:11 -0500164 { NEARESTMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500166 { NEARESTMV, { LAST2_FRAME, NONE_FRAME } },
167 { NEARESTMV, { LAST3_FRAME, NONE_FRAME } },
168 { NEARESTMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500170 { NEARESTMV, { ALTREF_FRAME, NONE_FRAME } },
171 { NEARESTMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172
Emil Keyder01770b32017-01-20 18:03:11 -0500173 { DC_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700174
Emil Keyder01770b32017-01-20 18:03:11 -0500175 { NEWMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500177 { NEWMV, { LAST2_FRAME, NONE_FRAME } },
178 { NEWMV, { LAST3_FRAME, NONE_FRAME } },
179 { NEWMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700180#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500181 { NEWMV, { ALTREF_FRAME, NONE_FRAME } },
182 { NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183
Emil Keyder01770b32017-01-20 18:03:11 -0500184 { NEARMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700185#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500186 { NEARMV, { LAST2_FRAME, NONE_FRAME } },
187 { NEARMV, { LAST3_FRAME, NONE_FRAME } },
188 { NEARMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700189#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500190 { NEARMV, { ALTREF_FRAME, NONE_FRAME } },
191 { NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700192
Emil Keyder01770b32017-01-20 18:03:11 -0500193 { ZEROMV, { LAST_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700194#if CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500195 { ZEROMV, { LAST2_FRAME, NONE_FRAME } },
196 { ZEROMV, { LAST3_FRAME, NONE_FRAME } },
197 { ZEROMV, { BWDREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198#endif // CONFIG_EXT_REFS
Emil Keyder01770b32017-01-20 18:03:11 -0500199 { ZEROMV, { GOLDEN_FRAME, NONE_FRAME } },
200 { ZEROMV, { ALTREF_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201
202// TODO(zoeliu): May need to reconsider the order on the modes to check
203
204#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -0700205
206#if CONFIG_COMPOUND_SINGLEREF
207 // Single ref comp mode
208 { SR_NEAREST_NEARMV, { LAST_FRAME, NONE_FRAME } },
209#if CONFIG_EXT_REFS
210 { SR_NEAREST_NEARMV, { LAST2_FRAME, NONE_FRAME } },
211 { SR_NEAREST_NEARMV, { LAST3_FRAME, NONE_FRAME } },
212 { SR_NEAREST_NEARMV, { BWDREF_FRAME, NONE_FRAME } },
213#endif // CONFIG_EXT_REFS
214 { SR_NEAREST_NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
215 { SR_NEAREST_NEARMV, { ALTREF_FRAME, NONE_FRAME } },
216
217 /*
218 { SR_NEAREST_NEWMV, { LAST_FRAME, NONE_FRAME } },
219#if CONFIG_EXT_REFS
220 { SR_NEAREST_NEWMV, { LAST2_FRAME, NONE_FRAME } },
221 { SR_NEAREST_NEWMV, { LAST3_FRAME, NONE_FRAME } },
222 { SR_NEAREST_NEWMV, { BWDREF_FRAME, NONE_FRAME } },
223#endif // CONFIG_EXT_REFS
224 { SR_NEAREST_NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
225 { SR_NEAREST_NEWMV, { ALTREF_FRAME, NONE_FRAME } },*/
226
227 { SR_NEAR_NEWMV, { LAST_FRAME, NONE_FRAME } },
228#if CONFIG_EXT_REFS
229 { SR_NEAR_NEWMV, { LAST2_FRAME, NONE_FRAME } },
230 { SR_NEAR_NEWMV, { LAST3_FRAME, NONE_FRAME } },
231 { SR_NEAR_NEWMV, { BWDREF_FRAME, NONE_FRAME } },
232#endif // CONFIG_EXT_REFS
233 { SR_NEAR_NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
234 { SR_NEAR_NEWMV, { ALTREF_FRAME, NONE_FRAME } },
235
236 { SR_ZERO_NEWMV, { LAST_FRAME, NONE_FRAME } },
237#if CONFIG_EXT_REFS
238 { SR_ZERO_NEWMV, { LAST2_FRAME, NONE_FRAME } },
239 { SR_ZERO_NEWMV, { LAST3_FRAME, NONE_FRAME } },
240 { SR_ZERO_NEWMV, { BWDREF_FRAME, NONE_FRAME } },
241#endif // CONFIG_EXT_REFS
242 { SR_ZERO_NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
243 { SR_ZERO_NEWMV, { ALTREF_FRAME, NONE_FRAME } },
244
245 { SR_NEW_NEWMV, { LAST_FRAME, NONE_FRAME } },
246#if CONFIG_EXT_REFS
247 { SR_NEW_NEWMV, { LAST2_FRAME, NONE_FRAME } },
248 { SR_NEW_NEWMV, { LAST3_FRAME, NONE_FRAME } },
249 { SR_NEW_NEWMV, { BWDREF_FRAME, NONE_FRAME } },
250#endif // CONFIG_EXT_REFS
251 { SR_NEW_NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
252 { SR_NEW_NEWMV, { ALTREF_FRAME, NONE_FRAME } },
253#endif // CONFIG_COMPOUND_SINGLEREF
254
Yaowu Xuc27fc142016-08-22 16:08:15 -0700255 { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
256#if CONFIG_EXT_REFS
257 { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
258 { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
259#endif // CONFIG_EXT_REFS
260 { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
261#if CONFIG_EXT_REFS
262 { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
263 { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
264 { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
265 { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
Zoe Liuc082bbc2017-05-17 13:31:37 -0700266
267#if CONFIG_EXT_COMP_REFS
268 { NEAREST_NEARESTMV, { LAST_FRAME, LAST2_FRAME } },
269 { NEAREST_NEARESTMV, { LAST_FRAME, GOLDEN_FRAME } },
270 { NEAREST_NEARESTMV, { BWDREF_FRAME, ALTREF_FRAME } },
271#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700272#endif // CONFIG_EXT_REFS
273
274#else // CONFIG_EXT_INTER
275
276 { NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
277#if CONFIG_EXT_REFS
278 { NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
279 { NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
280#endif // CONFIG_EXT_REFS
281 { NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
282#if CONFIG_EXT_REFS
283 { NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
284 { NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
285 { NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
286 { NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
Zoe Liuc082bbc2017-05-17 13:31:37 -0700287
288#if CONFIG_EXT_COMP_REFS
289 { NEARESTMV, { LAST_FRAME, LAST2_FRAME } },
290 { NEARESTMV, { LAST_FRAME, GOLDEN_FRAME } },
291 { NEARESTMV, { BWDREF_FRAME, ALTREF_FRAME } },
292#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700293#endif // CONFIG_EXT_REFS
294#endif // CONFIG_EXT_INTER
295
Emil Keyder01770b32017-01-20 18:03:11 -0500296 { TM_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700297
Urvang Joshi6be4a542016-11-03 15:24:05 -0700298#if CONFIG_ALT_INTRA
Emil Keyder01770b32017-01-20 18:03:11 -0500299 { SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
Urvang Joshie6ca8e82017-03-15 14:57:41 -0700300#if CONFIG_SMOOTH_HV
301 { SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
302 { SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
303#endif // CONFIG_SMOOTH_HV
Urvang Joshi6be4a542016-11-03 15:24:05 -0700304#endif // CONFIG_ALT_INTRA
305
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700307 { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
308 { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
309 { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
310 { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
311 { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
312 { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
313 { ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
314
315#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700316 { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
317 { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
318 { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
319 { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
320 { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
321 { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
322 { ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
323
Yaowu Xuc27fc142016-08-22 16:08:15 -0700324 { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
325 { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
326 { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
327 { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
328 { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
329 { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
330 { ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
331#endif // CONFIG_EXT_REFS
332
Yaowu Xuc27fc142016-08-22 16:08:15 -0700333 { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
334 { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
335 { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
336 { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
337 { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
338 { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
339 { ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
340
341#if CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700342 { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
343 { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
344 { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
345 { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
346 { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
347 { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
348 { ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
349
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350 { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
351 { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
352 { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
353 { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
354 { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
355 { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
356 { ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
357
Yaowu Xuc27fc142016-08-22 16:08:15 -0700358 { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
359 { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
360 { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
361 { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
362 { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
363 { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
364 { ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
365
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
367 { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
368 { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
369 { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
370 { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
371 { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
372 { ZERO_ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
Zoe Liuc082bbc2017-05-17 13:31:37 -0700373
374#if CONFIG_EXT_COMP_REFS
375 { NEAR_NEARMV, { LAST_FRAME, LAST2_FRAME } },
376 { NEW_NEARESTMV, { LAST_FRAME, LAST2_FRAME } },
377 { NEAREST_NEWMV, { LAST_FRAME, LAST2_FRAME } },
378 { NEW_NEARMV, { LAST_FRAME, LAST2_FRAME } },
379 { NEAR_NEWMV, { LAST_FRAME, LAST2_FRAME } },
380 { NEW_NEWMV, { LAST_FRAME, LAST2_FRAME } },
381 { ZERO_ZEROMV, { LAST_FRAME, LAST2_FRAME } },
382
383 { NEAR_NEARMV, { LAST_FRAME, GOLDEN_FRAME } },
384 { NEW_NEARESTMV, { LAST_FRAME, GOLDEN_FRAME } },
385 { NEAREST_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
386 { NEW_NEARMV, { LAST_FRAME, GOLDEN_FRAME } },
387 { NEAR_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
388 { NEW_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
389 { ZERO_ZEROMV, { LAST_FRAME, GOLDEN_FRAME } },
390
391 { NEAR_NEARMV, { BWDREF_FRAME, ALTREF_FRAME } },
392 { NEW_NEARESTMV, { BWDREF_FRAME, ALTREF_FRAME } },
393 { NEAREST_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
394 { NEW_NEARMV, { BWDREF_FRAME, ALTREF_FRAME } },
395 { NEAR_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
396 { NEW_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
397 { ZERO_ZEROMV, { BWDREF_FRAME, ALTREF_FRAME } },
398#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399#endif // CONFIG_EXT_REFS
400
Zoe Liuc082bbc2017-05-17 13:31:37 -0700401#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402
403 { NEARMV, { LAST_FRAME, ALTREF_FRAME } },
404 { NEWMV, { LAST_FRAME, ALTREF_FRAME } },
405#if CONFIG_EXT_REFS
406 { NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
407 { NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
408 { NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
409 { NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
410#endif // CONFIG_EXT_REFS
411 { NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
412 { NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
413
414#if CONFIG_EXT_REFS
415 { NEARMV, { LAST_FRAME, BWDREF_FRAME } },
416 { NEWMV, { LAST_FRAME, BWDREF_FRAME } },
417 { NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
418 { NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
419 { NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
420 { NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
421 { NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
422 { NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
Zoe Liuc082bbc2017-05-17 13:31:37 -0700423
424#if CONFIG_EXT_COMP_REFS
425 { NEARMV, { LAST_FRAME, LAST2_FRAME } },
426 { NEWMV, { LAST_FRAME, LAST2_FRAME } },
427 { NEARMV, { LAST_FRAME, GOLDEN_FRAME } },
428 { NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
429 { NEARMV, { BWDREF_FRAME, ALTREF_FRAME } },
430 { NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
431#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700432#endif // CONFIG_EXT_REFS
433
434 { ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
435#if CONFIG_EXT_REFS
436 { ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
437 { ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
438#endif // CONFIG_EXT_REFS
439 { ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
440
441#if CONFIG_EXT_REFS
442 { ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
443 { ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
444 { ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
445 { ZEROMV, { GOLDEN_FRAME, BWDREF_FRAME } },
Zoe Liuc082bbc2017-05-17 13:31:37 -0700446
447#if CONFIG_EXT_COMP_REFS
448 { ZEROMV, { LAST_FRAME, LAST2_FRAME } },
449 { ZEROMV, { LAST_FRAME, GOLDEN_FRAME } },
450 { ZEROMV, { BWDREF_FRAME, ALTREF_FRAME } },
451#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700452#endif // CONFIG_EXT_REFS
453
454#endif // CONFIG_EXT_INTER
455
Emil Keyder01770b32017-01-20 18:03:11 -0500456 { H_PRED, { INTRA_FRAME, NONE_FRAME } },
457 { V_PRED, { INTRA_FRAME, NONE_FRAME } },
458 { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
459 { D207_PRED, { INTRA_FRAME, NONE_FRAME } },
460 { D153_PRED, { INTRA_FRAME, NONE_FRAME } },
461 { D63_PRED, { INTRA_FRAME, NONE_FRAME } },
462 { D117_PRED, { INTRA_FRAME, NONE_FRAME } },
463 { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700464
465#if CONFIG_EXT_INTER
466 { ZEROMV, { LAST_FRAME, INTRA_FRAME } },
467 { NEARESTMV, { LAST_FRAME, INTRA_FRAME } },
468 { NEARMV, { LAST_FRAME, INTRA_FRAME } },
469 { NEWMV, { LAST_FRAME, INTRA_FRAME } },
470
471#if CONFIG_EXT_REFS
472 { ZEROMV, { LAST2_FRAME, INTRA_FRAME } },
473 { NEARESTMV, { LAST2_FRAME, INTRA_FRAME } },
474 { NEARMV, { LAST2_FRAME, INTRA_FRAME } },
475 { NEWMV, { LAST2_FRAME, INTRA_FRAME } },
476
477 { ZEROMV, { LAST3_FRAME, INTRA_FRAME } },
478 { NEARESTMV, { LAST3_FRAME, INTRA_FRAME } },
479 { NEARMV, { LAST3_FRAME, INTRA_FRAME } },
480 { NEWMV, { LAST3_FRAME, INTRA_FRAME } },
481#endif // CONFIG_EXT_REFS
482
483 { ZEROMV, { GOLDEN_FRAME, INTRA_FRAME } },
484 { NEARESTMV, { GOLDEN_FRAME, INTRA_FRAME } },
485 { NEARMV, { GOLDEN_FRAME, INTRA_FRAME } },
486 { NEWMV, { GOLDEN_FRAME, INTRA_FRAME } },
487
488#if CONFIG_EXT_REFS
489 { ZEROMV, { BWDREF_FRAME, INTRA_FRAME } },
490 { NEARESTMV, { BWDREF_FRAME, INTRA_FRAME } },
491 { NEARMV, { BWDREF_FRAME, INTRA_FRAME } },
492 { NEWMV, { BWDREF_FRAME, INTRA_FRAME } },
493#endif // CONFIG_EXT_REFS
494
495 { ZEROMV, { ALTREF_FRAME, INTRA_FRAME } },
496 { NEARESTMV, { ALTREF_FRAME, INTRA_FRAME } },
497 { NEARMV, { ALTREF_FRAME, INTRA_FRAME } },
498 { NEWMV, { ALTREF_FRAME, INTRA_FRAME } },
499#endif // CONFIG_EXT_INTER
500};
501
hui su5db97432016-10-14 16:10:14 -0700502#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503static INLINE int write_uniform_cost(int n, int v) {
hui su37499292017-04-26 09:49:53 -0700504 const int l = get_unsigned_bits(n);
505 const int m = (1 << l) - n;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506 if (l == 0) return 0;
507 if (v < m)
Yaowu Xuf883b422016-08-30 14:01:10 -0700508 return (l - 1) * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700509 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700510 return l * av1_cost_bit(128, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700511}
hui su5db97432016-10-14 16:10:14 -0700512#endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700513
514// constants for prune 1 and prune 2 decision boundaries
515#define FAST_EXT_TX_CORR_MID 0.0
516#define FAST_EXT_TX_EDST_MID 0.1
517#define FAST_EXT_TX_CORR_MARGIN 0.5
518#define FAST_EXT_TX_EDST_MARGIN 0.3
519
Yushin Cho7a428ba2017-01-12 16:28:49 -0800520#if CONFIG_DAALA_DIST
521static int od_compute_var_4x4(od_coeff *x, int stride) {
522 int sum;
523 int s2;
524 int i;
525 sum = 0;
526 s2 = 0;
527 for (i = 0; i < 4; i++) {
528 int j;
529 for (j = 0; j < 4; j++) {
530 int t;
531
532 t = x[i * stride + j];
533 sum += t;
534 s2 += t * t;
535 }
536 }
537 // TODO(yushin) : Check wheter any changes are required for high bit depth.
538 return (s2 - (sum * sum >> 4)) >> 4;
539}
540
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500541/* OD_DIST_LP_MID controls the frequency weighting filter used for computing
542 the distortion. For a value X, the filter is [1 X 1]/(X + 2) and
543 is applied both horizontally and vertically. For X=5, the filter is
544 a good approximation for the OD_QM8_Q4_HVS quantization matrix. */
545#define OD_DIST_LP_MID (5)
546#define OD_DIST_LP_NORM (OD_DIST_LP_MID + 2)
547
Yushin Cho7a428ba2017-01-12 16:28:49 -0800548static double od_compute_dist_8x8(int qm, int use_activity_masking, od_coeff *x,
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500549 od_coeff *y, od_coeff *e_lp, int stride) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800550 double sum;
551 int min_var;
552 double mean_var;
553 double var_stat;
554 double activity;
555 double calibration;
556 int i;
557 int j;
558 double vardist;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800559
560 vardist = 0;
561 OD_ASSERT(qm != OD_FLAT_QM);
Alex Converse76b89632017-03-20 11:47:12 -0700562 (void)qm;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800563#if 1
564 min_var = INT_MAX;
565 mean_var = 0;
566 for (i = 0; i < 3; i++) {
567 for (j = 0; j < 3; j++) {
568 int varx;
569 int vary;
570 varx = od_compute_var_4x4(x + 2 * i * stride + 2 * j, stride);
571 vary = od_compute_var_4x4(y + 2 * i * stride + 2 * j, stride);
572 min_var = OD_MINI(min_var, varx);
573 mean_var += 1. / (1 + varx);
574 /* The cast to (double) is to avoid an overflow before the sqrt.*/
575 vardist += varx - 2 * sqrt(varx * (double)vary) + vary;
576 }
577 }
578 /* We use a different variance statistic depending on whether activity
579 masking is used, since the harmonic mean appeared slghtly worse with
580 masking off. The calibration constant just ensures that we preserve the
581 rate compared to activity=1. */
582 if (use_activity_masking) {
583 calibration = 1.95;
584 var_stat = 9. / mean_var;
585 } else {
586 calibration = 1.62;
587 var_stat = min_var;
588 }
589 /* 1.62 is a calibration constant, 0.25 is a noise floor and 1/6 is the
590 activity masking constant. */
591 activity = calibration * pow(.25 + var_stat, -1. / 6);
592#else
593 activity = 1;
Fergus Simpson4063a682017-02-28 16:52:22 -0800594#endif // 1
Yushin Cho7a428ba2017-01-12 16:28:49 -0800595 sum = 0;
596 for (i = 0; i < 8; i++) {
597 for (j = 0; j < 8; j++)
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500598 sum += e_lp[i * stride + j] * (double)e_lp[i * stride + j];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800599 }
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500600 /* Normalize the filter to unit DC response. */
601 sum *= 1. / (OD_DIST_LP_NORM * OD_DIST_LP_NORM * OD_DIST_LP_NORM *
602 OD_DIST_LP_NORM);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800603 return activity * activity * (sum + vardist);
604}
605
606// Note : Inputs x and y are in a pixel domain
Yushin Cho75b01002017-06-21 13:43:57 -0700607static double od_compute_dist_common(int qm, int activity_masking, od_coeff *x,
608 od_coeff *y, int bsize_w, int bsize_h,
609 int qindex, od_coeff *tmp,
610 od_coeff *e_lp) {
611 int i, j;
612 double sum = 0;
613 const int mid = OD_DIST_LP_MID;
614
615 for (j = 0; j < bsize_w; j++) {
616 e_lp[j] = mid * tmp[j] + 2 * tmp[bsize_w + j];
617 e_lp[(bsize_h - 1) * bsize_w + j] = mid * tmp[(bsize_h - 1) * bsize_w + j] +
618 2 * tmp[(bsize_h - 2) * bsize_w + j];
619 }
620 for (i = 1; i < bsize_h - 1; i++) {
621 for (j = 0; j < bsize_w; j++) {
622 e_lp[i * bsize_w + j] = mid * tmp[i * bsize_w + j] +
623 tmp[(i - 1) * bsize_w + j] +
624 tmp[(i + 1) * bsize_w + j];
625 }
626 }
627 for (i = 0; i < bsize_h; i += 8) {
628 for (j = 0; j < bsize_w; j += 8) {
629 sum += od_compute_dist_8x8(qm, activity_masking, &x[i * bsize_w + j],
630 &y[i * bsize_w + j], &e_lp[i * bsize_w + j],
631 bsize_w);
632 }
633 }
634 /* Scale according to linear regression against SSE, for 8x8 blocks. */
635 if (activity_masking) {
636 sum *= 2.2 + (1.7 - 2.2) * (qindex - 99) / (210 - 99) +
637 (qindex < 99 ? 2.5 * (qindex - 99) / 99 * (qindex - 99) / 99 : 0);
638 } else {
639 sum *= qindex >= 128
640 ? 1.4 + (0.9 - 1.4) * (qindex - 128) / (209 - 128)
641 : qindex <= 43 ? 1.5 + (2.0 - 1.5) * (qindex - 43) / (16 - 43)
642 : 1.5 + (1.4 - 1.5) * (qindex - 43) / (128 - 43);
643 }
644
645 return sum;
646}
647
Yushin Cho7a428ba2017-01-12 16:28:49 -0800648static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
649 od_coeff *y, int bsize_w, int bsize_h,
650 int qindex) {
651 int i;
652 double sum;
653 sum = 0;
654
Yushin Cho7a428ba2017-01-12 16:28:49 -0800655 assert(bsize_w >= 8 && bsize_h >= 8);
656
657 if (qm == OD_FLAT_QM) {
658 for (i = 0; i < bsize_w * bsize_h; i++) {
659 double tmp;
660 tmp = x[i] - y[i];
661 sum += tmp * tmp;
662 }
663 } else {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500664 int j;
665 DECLARE_ALIGNED(16, od_coeff, e[MAX_TX_SQUARE]);
666 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
667 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
668 int mid = OD_DIST_LP_MID;
669 for (i = 0; i < bsize_h; i++) {
670 for (j = 0; j < bsize_w; j++) {
671 e[i * bsize_w + j] = x[i * bsize_w + j] - y[i * bsize_w + j];
672 }
673 }
674 for (i = 0; i < bsize_h; i++) {
675 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
676 tmp[i * bsize_w + bsize_w - 1] =
677 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
678 for (j = 1; j < bsize_w - 1; j++) {
679 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
680 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
681 }
682 }
Yushin Cho75b01002017-06-21 13:43:57 -0700683 sum = od_compute_dist_common(qm, activity_masking, x, y, bsize_w, bsize_h,
684 qindex, tmp, e_lp);
685 }
686 return sum;
687}
688
689static double od_compute_dist_diff(int qm, int activity_masking, od_coeff *x,
690 od_coeff *e, int bsize_w, int bsize_h,
691 int qindex) {
692 int i;
693 double sum;
694 sum = 0;
695
696 assert(bsize_w >= 8 && bsize_h >= 8);
697
698 if (qm == OD_FLAT_QM) {
699 for (i = 0; i < bsize_w * bsize_h; i++) {
700 double tmp;
701 tmp = e[i];
702 sum += tmp * tmp;
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500703 }
Yushin Cho75b01002017-06-21 13:43:57 -0700704 } else {
705 int j;
706 DECLARE_ALIGNED(16, od_coeff, y[MAX_TX_SQUARE]);
707 DECLARE_ALIGNED(16, od_coeff, tmp[MAX_TX_SQUARE]);
708 DECLARE_ALIGNED(16, od_coeff, e_lp[MAX_TX_SQUARE]);
709 int mid = OD_DIST_LP_MID;
710 for (i = 0; i < bsize_h; i++) {
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500711 for (j = 0; j < bsize_w; j++) {
Yushin Cho75b01002017-06-21 13:43:57 -0700712 y[i * bsize_w + j] = x[i * bsize_w + j] - e[i * bsize_w + j];
Jean-Marc Valin79c0f322017-01-18 01:58:33 -0500713 }
714 }
Yushin Cho75b01002017-06-21 13:43:57 -0700715 for (i = 0; i < bsize_h; i++) {
716 tmp[i * bsize_w] = mid * e[i * bsize_w] + 2 * e[i * bsize_w + 1];
717 tmp[i * bsize_w + bsize_w - 1] =
718 mid * e[i * bsize_w + bsize_w - 1] + 2 * e[i * bsize_w + bsize_w - 2];
719 for (j = 1; j < bsize_w - 1; j++) {
720 tmp[i * bsize_w + j] = mid * e[i * bsize_w + j] +
721 e[i * bsize_w + j - 1] + e[i * bsize_w + j + 1];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800722 }
723 }
Yushin Cho75b01002017-06-21 13:43:57 -0700724
725 sum = od_compute_dist_common(qm, activity_masking, x, y, bsize_w, bsize_h,
726 qindex, tmp, e_lp);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800727 }
728 return sum;
729}
730
Yushin Cho8ab875d2017-06-23 14:47:21 -0700731int64_t av1_daala_dist(const MACROBLOCKD *xd, const uint8_t *src,
732 int src_stride, const uint8_t *dst, int dst_stride,
733 int bsw, int bsh, int visible_w, int visible_h, int qm,
734 int use_activity_masking, int qindex) {
Yushin Cho7a428ba2017-01-12 16:28:49 -0800735 int i, j;
736 int64_t d;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800737 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
738 DECLARE_ALIGNED(16, od_coeff, rec[MAX_TX_SQUARE]);
Yushin Cho8ab875d2017-06-23 14:47:21 -0700739#if !CONFIG_HIGHBITDEPTH
740 (void)xd;
741#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -0800742 assert(qm == OD_HVS_QM);
743
Yushin Cho8ab875d2017-06-23 14:47:21 -0700744#if CONFIG_HIGHBITDEPTH
745 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yushin Cho75b01002017-06-21 13:43:57 -0700746 for (j = 0; j < bsh; j++)
Yushin Cho8ab875d2017-06-23 14:47:21 -0700747 for (i = 0; i < bsw; i++)
748 orig[j * bsw + i] = CONVERT_TO_SHORTPTR(src)[j * src_stride + i];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800749
Yushin Cho8ab875d2017-06-23 14:47:21 -0700750 if ((bsw == visible_w) && (bsh == visible_h)) {
Yushin Cho75b01002017-06-21 13:43:57 -0700751 for (j = 0; j < bsh; j++)
Yushin Cho8ab875d2017-06-23 14:47:21 -0700752 for (i = 0; i < bsw; i++)
753 rec[j * bsw + i] = CONVERT_TO_SHORTPTR(dst)[j * dst_stride + i];
754 } else {
755 for (j = 0; j < visible_h; j++)
756 for (i = 0; i < visible_w; i++)
757 rec[j * bsw + i] = CONVERT_TO_SHORTPTR(dst)[j * dst_stride + i];
Yushin Cho75b01002017-06-21 13:43:57 -0700758
Yushin Cho8ab875d2017-06-23 14:47:21 -0700759 if (visible_w < bsw) {
760 for (j = 0; j < bsh; j++)
761 for (i = visible_w; i < bsw; i++)
762 rec[j * bsw + i] = CONVERT_TO_SHORTPTR(src)[j * src_stride + i];
763 }
764
765 if (visible_h < bsh) {
766 for (j = visible_h; j < bsh; j++)
767 for (i = 0; i < bsw; i++)
768 rec[j * bsw + i] = CONVERT_TO_SHORTPTR(src)[j * src_stride + i];
769 }
Yushin Cho75b01002017-06-21 13:43:57 -0700770 }
Yushin Cho8ab875d2017-06-23 14:47:21 -0700771 } else {
772#endif
773 for (j = 0; j < bsh; j++)
774 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
775
776 if ((bsw == visible_w) && (bsh == visible_h)) {
777 for (j = 0; j < bsh; j++)
778 for (i = 0; i < bsw; i++) rec[j * bsw + i] = dst[j * dst_stride + i];
779 } else {
780 for (j = 0; j < visible_h; j++)
781 for (i = 0; i < visible_w; i++)
782 rec[j * bsw + i] = dst[j * dst_stride + i];
783
784 if (visible_w < bsw) {
785 for (j = 0; j < bsh; j++)
786 for (i = visible_w; i < bsw; i++)
787 rec[j * bsw + i] = src[j * src_stride + i];
788 }
789
790 if (visible_h < bsh) {
791 for (j = visible_h; j < bsh; j++)
792 for (i = 0; i < bsw; i++) rec[j * bsw + i] = src[j * src_stride + i];
793 }
794 }
795#if CONFIG_HIGHBITDEPTH
Yushin Cho75b01002017-06-21 13:43:57 -0700796 }
Yushin Cho8ab875d2017-06-23 14:47:21 -0700797#endif // CONFIG_HIGHBITDEPTH
798
Yushin Cho7a428ba2017-01-12 16:28:49 -0800799 d = (int64_t)od_compute_dist(qm, use_activity_masking, orig, rec, bsw, bsh,
800 qindex);
801 return d;
802}
Yushin Cho75b01002017-06-21 13:43:57 -0700803
Yushin Cho8ab875d2017-06-23 14:47:21 -0700804static int64_t av1_daala_dist_diff(const MACROBLOCKD *xd, const uint8_t *src,
805 int src_stride, const int16_t *diff,
806 int dst_stride, int bsw, int bsh,
807 int visible_w, int visible_h, int qm,
808 int use_activity_masking, int qindex) {
Yushin Cho75b01002017-06-21 13:43:57 -0700809 int i, j;
810 int64_t d;
811 DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
812 DECLARE_ALIGNED(16, od_coeff, diff32[MAX_TX_SQUARE]);
Yushin Cho8ab875d2017-06-23 14:47:21 -0700813#if !CONFIG_HIGHBITDEPTH
814 (void)xd;
815#endif
Yushin Cho75b01002017-06-21 13:43:57 -0700816 assert(qm == OD_HVS_QM);
817
Yushin Cho8ab875d2017-06-23 14:47:21 -0700818#if CONFIG_HIGHBITDEPTH
819 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
820 for (j = 0; j < bsh; j++)
821 for (i = 0; i < bsw; i++)
822 orig[j * bsw + i] = CONVERT_TO_SHORTPTR(src)[j * src_stride + i];
823 } else {
824#endif
825 for (j = 0; j < bsh; j++)
826 for (i = 0; i < bsw; i++) orig[j * bsw + i] = src[j * src_stride + i];
827#if CONFIG_HIGHBITDEPTH
828 }
829#endif // CONFIG_HIGHBITDEPTH
Yushin Cho75b01002017-06-21 13:43:57 -0700830
831 if ((bsw == visible_w) && (bsh == visible_h)) {
832 for (j = 0; j < bsh; j++)
833 for (i = 0; i < bsw; i++) diff32[j * bsw + i] = diff[j * dst_stride + i];
834 } else {
835 for (j = 0; j < visible_h; j++)
836 for (i = 0; i < visible_w; i++)
837 diff32[j * bsw + i] = diff[j * dst_stride + i];
838
839 if (visible_w < bsw) {
840 for (j = 0; j < bsh; j++)
841 for (i = visible_w; i < bsw; i++) diff32[j * bsw + i] = 0;
842 }
843
844 if (visible_h < bsh) {
845 for (j = visible_h; j < bsh; j++)
846 for (i = 0; i < bsw; i++) diff32[j * bsw + i] = 0;
847 }
848 }
Yushin Cho8ab875d2017-06-23 14:47:21 -0700849
Yushin Cho75b01002017-06-21 13:43:57 -0700850 d = (int64_t)od_compute_dist_diff(qm, use_activity_masking, orig, diff32, bsw,
851 bsh, qindex);
852
853 return d;
854}
Fergus Simpson4063a682017-02-28 16:52:22 -0800855#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -0800856
Yaowu Xuf883b422016-08-30 14:01:10 -0700857static void get_energy_distribution_fine(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse9f217762017-04-20 15:34:54 -0700858 const uint8_t *src, int src_stride,
859 const uint8_t *dst, int dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700860 double *hordist, double *verdist) {
Alex Converse9f217762017-04-20 15:34:54 -0700861 const int bw = block_size_wide[bsize];
862 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700863 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 -0700864
865 const int f_index = bsize - BLOCK_16X16;
866 if (f_index < 0) {
Alex Converse9f217762017-04-20 15:34:54 -0700867 const int w_shift = bw == 8 ? 1 : 2;
868 const int h_shift = bh == 8 ? 1 : 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200869#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700870 if (cpi->common.use_highbitdepth) {
Alex Converse9f217762017-04-20 15:34:54 -0700871 const uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
872 const uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
873 for (int i = 0; i < bh; ++i)
874 for (int j = 0; j < bw; ++j) {
875 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700876 esq[index] +=
877 (src16[j + i * src_stride] - dst16[j + i * dst_stride]) *
878 (src16[j + i * src_stride] - dst16[j + i * dst_stride]);
879 }
880 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200881#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882
Alex Converse9f217762017-04-20 15:34:54 -0700883 for (int i = 0; i < bh; ++i)
884 for (int j = 0; j < bw; ++j) {
885 const int index = (j >> w_shift) + ((i >> h_shift) << 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 esq[index] += (src[j + i * src_stride] - dst[j + i * dst_stride]) *
887 (src[j + i * src_stride] - dst[j + i * dst_stride]);
888 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200889#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700890 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200891#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700892 } else {
Alex Converse9f217762017-04-20 15:34:54 -0700893 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[0]);
894 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
895 &esq[1]);
896 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
897 &esq[2]);
898 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
899 dst_stride, &esq[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 src += bh / 4 * src_stride;
901 dst += bh / 4 * dst_stride;
902
Alex Converse9f217762017-04-20 15:34:54 -0700903 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[4]);
904 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
905 &esq[5]);
906 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
907 &esq[6]);
908 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
909 dst_stride, &esq[7]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700910 src += bh / 4 * src_stride;
911 dst += bh / 4 * dst_stride;
912
Alex Converse9f217762017-04-20 15:34:54 -0700913 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[8]);
914 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
915 &esq[9]);
916 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
917 &esq[10]);
918 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
919 dst_stride, &esq[11]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920 src += bh / 4 * src_stride;
921 dst += bh / 4 * dst_stride;
922
Alex Converse9f217762017-04-20 15:34:54 -0700923 cpi->fn_ptr[f_index].vf(src, src_stride, dst, dst_stride, &esq[12]);
924 cpi->fn_ptr[f_index].vf(src + bw / 4, src_stride, dst + bw / 4, dst_stride,
925 &esq[13]);
926 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, dst + bw / 2, dst_stride,
927 &esq[14]);
928 cpi->fn_ptr[f_index].vf(src + 3 * bw / 4, src_stride, dst + 3 * bw / 4,
929 dst_stride, &esq[15]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700930 }
931
Alex Converse9f217762017-04-20 15:34:54 -0700932 double total = (double)esq[0] + esq[1] + esq[2] + esq[3] + esq[4] + esq[5] +
933 esq[6] + esq[7] + esq[8] + esq[9] + esq[10] + esq[11] +
934 esq[12] + esq[13] + esq[14] + esq[15];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 if (total > 0) {
936 const double e_recip = 1.0 / total;
Alex Converse9f217762017-04-20 15:34:54 -0700937 hordist[0] = ((double)esq[0] + esq[4] + esq[8] + esq[12]) * e_recip;
938 hordist[1] = ((double)esq[1] + esq[5] + esq[9] + esq[13]) * e_recip;
939 hordist[2] = ((double)esq[2] + esq[6] + esq[10] + esq[14]) * e_recip;
940 verdist[0] = ((double)esq[0] + esq[1] + esq[2] + esq[3]) * e_recip;
941 verdist[1] = ((double)esq[4] + esq[5] + esq[6] + esq[7]) * e_recip;
942 verdist[2] = ((double)esq[8] + esq[9] + esq[10] + esq[11]) * e_recip;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 } else {
944 hordist[0] = verdist[0] = 0.25;
945 hordist[1] = verdist[1] = 0.25;
946 hordist[2] = verdist[2] = 0.25;
947 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948}
949
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -0700950static int adst_vs_flipadst(const AV1_COMP *cpi, BLOCK_SIZE bsize,
951 const uint8_t *src, int src_stride,
952 const uint8_t *dst, int dst_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 int prune_bitmask = 0;
954 double svm_proj_h = 0, svm_proj_v = 0;
Alex Converse89912f92017-04-21 13:28:50 -0700955 double hdist[3] = { 0, 0, 0 }, vdist[3] = { 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 get_energy_distribution_fine(cpi, bsize, src, src_stride, dst, dst_stride,
957 hdist, vdist);
958
959 svm_proj_v = vdist[0] * ADST_FLIP_SVM[0] + vdist[1] * ADST_FLIP_SVM[1] +
960 vdist[2] * ADST_FLIP_SVM[2] + ADST_FLIP_SVM[3];
961 svm_proj_h = hdist[0] * ADST_FLIP_SVM[4] + hdist[1] * ADST_FLIP_SVM[5] +
962 hdist[2] * ADST_FLIP_SVM[6] + ADST_FLIP_SVM[7];
963 if (svm_proj_v > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
964 prune_bitmask |= 1 << FLIPADST_1D;
965 else if (svm_proj_v < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
966 prune_bitmask |= 1 << ADST_1D;
967
968 if (svm_proj_h > FAST_EXT_TX_EDST_MID + FAST_EXT_TX_EDST_MARGIN)
969 prune_bitmask |= 1 << (FLIPADST_1D + 8);
970 else if (svm_proj_h < FAST_EXT_TX_EDST_MID - FAST_EXT_TX_EDST_MARGIN)
971 prune_bitmask |= 1 << (ADST_1D + 8);
972
973 return prune_bitmask;
974}
975
976#if CONFIG_EXT_TX
Alex Converse89912f92017-04-21 13:28:50 -0700977static void get_horver_correlation(const int16_t *diff, int stride, int w,
978 int h, double *hcorr, double *vcorr) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700979 // Returns hor/ver correlation coefficient
980 const int num = (h - 1) * (w - 1);
981 double num_r;
982 int i, j;
983 int64_t xy_sum = 0, xz_sum = 0;
984 int64_t x_sum = 0, y_sum = 0, z_sum = 0;
985 int64_t x2_sum = 0, y2_sum = 0, z2_sum = 0;
986 double x_var_n, y_var_n, z_var_n, xy_var_n, xz_var_n;
987 *hcorr = *vcorr = 1;
988
989 assert(num > 0);
990 num_r = 1.0 / num;
991 for (i = 1; i < h; ++i) {
992 for (j = 1; j < w; ++j) {
993 const int16_t x = diff[i * stride + j];
994 const int16_t y = diff[i * stride + j - 1];
995 const int16_t z = diff[(i - 1) * stride + j];
996 xy_sum += x * y;
997 xz_sum += x * z;
998 x_sum += x;
999 y_sum += y;
1000 z_sum += z;
1001 x2_sum += x * x;
1002 y2_sum += y * y;
1003 z2_sum += z * z;
1004 }
1005 }
1006 x_var_n = x2_sum - (x_sum * x_sum) * num_r;
1007 y_var_n = y2_sum - (y_sum * y_sum) * num_r;
1008 z_var_n = z2_sum - (z_sum * z_sum) * num_r;
1009 xy_var_n = xy_sum - (x_sum * y_sum) * num_r;
1010 xz_var_n = xz_sum - (x_sum * z_sum) * num_r;
1011 if (x_var_n > 0 && y_var_n > 0) {
1012 *hcorr = xy_var_n / sqrt(x_var_n * y_var_n);
1013 *hcorr = *hcorr < 0 ? 0 : *hcorr;
1014 }
1015 if (x_var_n > 0 && z_var_n > 0) {
1016 *vcorr = xz_var_n / sqrt(x_var_n * z_var_n);
1017 *vcorr = *vcorr < 0 ? 0 : *vcorr;
1018 }
1019}
1020
Alex Converse89912f92017-04-21 13:28:50 -07001021int dct_vs_idtx(const int16_t *diff, int stride, int w, int h) {
1022 double hcorr, vcorr;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001023 int prune_bitmask = 0;
Alex Converse89912f92017-04-21 13:28:50 -07001024 get_horver_correlation(diff, stride, w, h, &hcorr, &vcorr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001025
Alex Converse89912f92017-04-21 13:28:50 -07001026 if (vcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001027 prune_bitmask |= 1 << IDTX_1D;
Alex Converse89912f92017-04-21 13:28:50 -07001028 else if (vcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001029 prune_bitmask |= 1 << DCT_1D;
1030
Alex Converse89912f92017-04-21 13:28:50 -07001031 if (hcorr > FAST_EXT_TX_CORR_MID + FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001032 prune_bitmask |= 1 << (IDTX_1D + 8);
Alex Converse89912f92017-04-21 13:28:50 -07001033 else if (hcorr < FAST_EXT_TX_CORR_MID - FAST_EXT_TX_CORR_MARGIN)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001034 prune_bitmask |= 1 << (DCT_1D + 8);
1035 return prune_bitmask;
1036}
1037
1038// Performance drop: 0.5%, Speed improvement: 24%
Yaowu Xuf883b422016-08-30 14:01:10 -07001039static int prune_two_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -07001040 MACROBLOCK *x, const MACROBLOCKD *xd,
1041 int adst_flipadst, int dct_idtx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001042 int prune = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043
Alex Converse89912f92017-04-21 13:28:50 -07001044 if (adst_flipadst) {
1045 const struct macroblock_plane *const p = &x->plane[0];
1046 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001047 prune |= adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride,
Alex Converse89912f92017-04-21 13:28:50 -07001048 pd->dst.buf, pd->dst.stride);
1049 }
1050 if (dct_idtx) {
1051 av1_subtract_plane(x, bsize, 0);
1052 const struct macroblock_plane *const p = &x->plane[0];
1053 const int bw = 4 << (b_width_log2_lookup[bsize]);
1054 const int bh = 4 << (b_height_log2_lookup[bsize]);
1055 prune |= dct_vs_idtx(p->src_diff, bw, bw, bh);
1056 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001057
1058 return prune;
1059}
1060#endif // CONFIG_EXT_TX
1061
1062// Performance drop: 0.3%, Speed improvement: 5%
Yaowu Xuf883b422016-08-30 14:01:10 -07001063static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
Alex Converse89912f92017-04-21 13:28:50 -07001064 const MACROBLOCK *x, const MACROBLOCKD *xd) {
1065 const struct macroblock_plane *const p = &x->plane[0];
1066 const struct macroblockd_plane *const pd = &xd->plane[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001067 return adst_vs_flipadst(cpi, bsize, p->src.buf, p->src.stride, pd->dst.buf,
Alex Converse89912f92017-04-21 13:28:50 -07001068 pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001069}
1070
Yaowu Xuf883b422016-08-30 14:01:10 -07001071static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001072 const MACROBLOCKD *const xd, int tx_set) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001073#if CONFIG_EXT_TX
Yaowu Xu37fe5fb2017-05-09 11:43:45 -07001074 const int *tx_set_1D = tx_set >= 0 ? ext_tx_used_inter_1D[tx_set] : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001075#else
1076 const int tx_set_1D[TX_TYPES_1D] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -08001077#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001078
1079 switch (cpi->sf.tx_type_search.prune_mode) {
1080 case NO_PRUNE: return 0; break;
1081 case PRUNE_ONE:
Sarah Parker68a26b62016-10-28 13:19:33 -07001082 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001083 return 0;
1084 return prune_one_for_sby(cpi, bsize, x, xd);
1085 break;
1086#if CONFIG_EXT_TX
1087 case PRUNE_TWO:
Sarah Parker68a26b62016-10-28 13:19:33 -07001088 if ((tx_set >= 0) && !(tx_set_1D[FLIPADST_1D] & tx_set_1D[ADST_1D])) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001089 if (!(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D])) return 0;
1090 return prune_two_for_sby(cpi, bsize, x, xd, 0, 1);
1091 }
Sarah Parker68a26b62016-10-28 13:19:33 -07001092 if ((tx_set >= 0) && !(tx_set_1D[DCT_1D] & tx_set_1D[IDTX_1D]))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093 return prune_two_for_sby(cpi, bsize, x, xd, 1, 0);
1094 return prune_two_for_sby(cpi, bsize, x, xd, 1, 1);
1095 break;
Fergus Simpson4063a682017-02-28 16:52:22 -08001096#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001097 }
1098 assert(0);
1099 return 0;
1100}
1101
1102static int do_tx_type_search(TX_TYPE tx_type, int prune) {
1103// TODO(sarahparker) implement for non ext tx
1104#if CONFIG_EXT_TX
1105 return !(((prune >> vtx_tab[tx_type]) & 1) |
1106 ((prune >> (htx_tab[tx_type] + 8)) & 1));
1107#else
1108 // temporary to avoid compiler warnings
1109 (void)vtx_tab;
1110 (void)htx_tab;
1111 (void)tx_type;
1112 (void)prune;
1113 return 1;
Fergus Simpson4063a682017-02-28 16:52:22 -08001114#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001115}
1116
Yaowu Xuf883b422016-08-30 14:01:10 -07001117static void model_rd_from_sse(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001118 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
1119 int plane, int64_t sse, int *rate,
1120 int64_t *dist) {
1121 const struct macroblockd_plane *const pd = &xd->plane[plane];
1122 const int dequant_shift =
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001123#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001124 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd - 5 :
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001125#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001126 3;
1127
1128 // Fast approximate the modelling function.
1129 if (cpi->sf.simple_model_rd_from_var) {
1130 const int64_t square_error = sse;
1131 int quantizer = (pd->dequant[1] >> dequant_shift);
1132
1133 if (quantizer < 120)
1134 *rate = (int)((square_error * (280 - quantizer)) >>
Yaowu Xuf883b422016-08-30 14:01:10 -07001135 (16 - AV1_PROB_COST_SHIFT));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 else
1137 *rate = 0;
1138 *dist = (square_error * quantizer) >> 8;
1139 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001140 av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[bsize],
1141 pd->dequant[1] >> dequant_shift, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001142 }
1143
1144 *dist <<= 4;
1145}
1146
Yaowu Xuf883b422016-08-30 14:01:10 -07001147static void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001148 MACROBLOCK *x, MACROBLOCKD *xd, int plane_from,
1149 int plane_to, int *out_rate_sum,
1150 int64_t *out_dist_sum, int *skip_txfm_sb,
1151 int64_t *skip_sse_sb) {
1152 // Note our transform coeffs are 8 times an orthogonal transform.
1153 // Hence quantizer step is also 8 times. To get effective quantizer
1154 // we need to divide by 8 before sending to modeling function.
1155 int plane;
1156 const int ref = xd->mi[0]->mbmi.ref_frame[0];
1157
1158 int64_t rate_sum = 0;
1159 int64_t dist_sum = 0;
1160 int64_t total_sse = 0;
1161
1162 x->pred_sse[ref] = 0;
1163
1164 for (plane = plane_from; plane <= plane_to; ++plane) {
1165 struct macroblock_plane *const p = &x->plane[plane];
1166 struct macroblockd_plane *const pd = &xd->plane[plane];
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001167#if CONFIG_CHROMA_SUB8X8
Jingning Han9ce464c2017-02-20 15:36:30 -08001168 const BLOCK_SIZE bs = AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
1169#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001171#endif // CONFIG_CHROMA_SUB8X8
Yaowu Xuc27fc142016-08-22 16:08:15 -07001172
1173 unsigned int sse;
1174 int rate;
1175 int64_t dist;
1176
Jingning Han9ce464c2017-02-20 15:36:30 -08001177#if CONFIG_CB4X4
1178 if (x->skip_chroma_rd && plane) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -08001179#endif // CONFIG_CB4X4
Jingning Han9ce464c2017-02-20 15:36:30 -08001180
Yaowu Xuc27fc142016-08-22 16:08:15 -07001181 // TODO(geza): Write direct sse functions that do not compute
1182 // variance as well.
1183 cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
1184 &sse);
1185
1186 if (plane == 0) x->pred_sse[ref] = sse;
1187
1188 total_sse += sse;
1189
1190 model_rd_from_sse(cpi, xd, bs, plane, sse, &rate, &dist);
1191
1192 rate_sum += rate;
1193 dist_sum += dist;
1194 }
1195
1196 *skip_txfm_sb = total_sse == 0;
1197 *skip_sse_sb = total_sse << 4;
1198 *out_rate_sum = (int)rate_sum;
1199 *out_dist_sum = dist_sum;
1200}
1201
Yaowu Xuf883b422016-08-30 14:01:10 -07001202int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
1203 intptr_t block_size, int64_t *ssz) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001204 int i;
1205 int64_t error = 0, sqcoeff = 0;
1206
1207 for (i = 0; i < block_size; i++) {
1208 const int diff = coeff[i] - dqcoeff[i];
1209 error += diff * diff;
1210 sqcoeff += coeff[i] * coeff[i];
1211 }
1212
1213 *ssz = sqcoeff;
1214 return error;
1215}
1216
Yaowu Xuf883b422016-08-30 14:01:10 -07001217int64_t av1_block_error_fp_c(const int16_t *coeff, const int16_t *dqcoeff,
1218 int block_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001219 int i;
1220 int64_t error = 0;
1221
1222 for (i = 0; i < block_size; i++) {
1223 const int diff = coeff[i] - dqcoeff[i];
1224 error += diff * diff;
1225 }
1226
1227 return error;
1228}
1229
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001230#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001231int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
1232 const tran_low_t *dqcoeff, intptr_t block_size,
1233 int64_t *ssz, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234 int i;
1235 int64_t error = 0, sqcoeff = 0;
1236 int shift = 2 * (bd - 8);
1237 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1238
1239 for (i = 0; i < block_size; i++) {
1240 const int64_t diff = coeff[i] - dqcoeff[i];
1241 error += diff * diff;
1242 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
1243 }
1244 assert(error >= 0 && sqcoeff >= 0);
1245 error = (error + rounding) >> shift;
1246 sqcoeff = (sqcoeff + rounding) >> shift;
1247
1248 *ssz = sqcoeff;
1249 return error;
1250}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001251#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252
Thomas Daede6ff6af62017-02-03 16:29:24 -08001253#if CONFIG_PVQ
1254// Without PVQ, av1_block_error_c() return two kind of errors,
1255// 1) reconstruction (i.e. decoded) error and
1256// 2) Squared sum of transformed residue (i.e. 'coeff')
1257// However, if PVQ is enabled, coeff does not keep the transformed residue
1258// but instead a transformed original is kept.
1259// Hence, new parameter ref vector (i.e. transformed predicted signal)
1260// is required to derive the residue signal,
1261// i.e. coeff - ref = residue (all transformed).
1262
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001263#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001264static int64_t av1_highbd_block_error2_c(const tran_low_t *coeff,
1265 const tran_low_t *dqcoeff,
1266 const tran_low_t *ref,
1267 intptr_t block_size, int64_t *ssz,
1268 int bd) {
1269 int64_t error;
1270 int64_t sqcoeff;
1271 int shift = 2 * (bd - 8);
1272 int rounding = shift > 0 ? 1 << (shift - 1) : 0;
1273 // Use the existing sse codes for calculating distortion of decoded signal:
1274 // i.e. (orig - decoded)^2
1275 // For high bit depth, throw away ssz until a 32-bit version of
1276 // av1_block_error_fp is written.
1277 int64_t ssz_trash;
1278 error = av1_block_error(coeff, dqcoeff, block_size, &ssz_trash);
1279 // prediction residue^2 = (orig - ref)^2
1280 sqcoeff = av1_block_error(coeff, ref, block_size, &ssz_trash);
1281 error = (error + rounding) >> shift;
1282 sqcoeff = (sqcoeff + rounding) >> shift;
1283 *ssz = sqcoeff;
1284 return error;
1285}
1286#else
1287// TODO(yushin) : Since 4x4 case does not need ssz, better to refactor into
1288// a separate function that does not do the extra computations for ssz.
1289static int64_t av1_block_error2_c(const tran_low_t *coeff,
1290 const tran_low_t *dqcoeff,
1291 const tran_low_t *ref, intptr_t block_size,
1292 int64_t *ssz) {
1293 int64_t error;
1294 // Use the existing sse codes for calculating distortion of decoded signal:
1295 // i.e. (orig - decoded)^2
1296 error = av1_block_error_fp(coeff, dqcoeff, block_size);
1297 // prediction residue^2 = (orig - ref)^2
1298 *ssz = av1_block_error_fp(coeff, ref, block_size);
1299 return error;
1300}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001301#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -08001302#endif // CONFIG_PVQ
1303
Jingning Hanab77e732017-02-28 15:20:59 -08001304#if !CONFIG_PVQ || CONFIG_VAR_TX
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001305/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 * decide whether to include cost of a trailing EOB node or not (i.e. we
1307 * can skip this if the last coefficient in this transform block, e.g. the
1308 * 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
1309 * were non-zero). */
Angie Chiang47e4b362017-03-24 11:25:10 -07001310#if !CONFIG_LV_MAP
1311static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
1312 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1313 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1314 int use_fast_coef_costing) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001315 MACROBLOCKD *const xd = &x->e_mbd;
1316 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1317 const struct macroblock_plane *p = &x->plane[plane];
1318 const struct macroblockd_plane *pd = &xd->plane[plane];
1319 const PLANE_TYPE type = pd->plane_type;
1320 const uint16_t *band_count = &band_count_table[tx_size][1];
1321 const int eob = p->eobs[block];
1322 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1323 const int tx_size_ctx = txsize_sqr_map[tx_size];
1324 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
1325 x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
1326 uint8_t token_cache[MAX_TX_SQUARE];
Angie Chiang77368af2017-03-23 16:22:07 -07001327 int pt = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001328 int c, cost;
Angie Chiang77368af2017-03-23 16:22:07 -07001329 const int16_t *scan = scan_order->scan;
1330 const int16_t *nb = scan_order->neighbors;
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001331 const int ref = is_inter_block(mbmi);
1332 aom_prob *blockz_probs =
1333 cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
Thomas Davies10525752017-03-06 12:10:46 +00001334
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001335#if CONFIG_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -07001336 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337#else
Alex Converseda3d94f2017-03-15 14:54:29 -07001338 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001339#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001340
1341#if !CONFIG_VAR_TX && !CONFIG_SUPERTX
1342 // Check for consistency of tx_size with mode info
Angie Chiang7fcfee42017-02-24 15:51:03 -08001343 assert(tx_size == get_tx_size(plane, xd));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001344#endif // !CONFIG_VAR_TX && !CONFIG_SUPERTX
Angie Chiang22ba7512016-10-20 17:10:33 -07001345 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001346
1347 if (eob == 0) {
1348 // single eob token
Thomas Daviesed8e2d22017-01-04 16:42:09 +00001349 cost = av1_cost_bit(blockz_probs[pt], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001350 } else {
1351 if (use_fast_coef_costing) {
1352 int band_left = *band_count++;
1353
1354 // dc token
1355 int v = qcoeff[0];
1356 int16_t prev_t;
Alex Converseda3d94f2017-03-15 14:54:29 -07001357 cost = av1_get_token_cost(v, &prev_t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001358 cost += (*token_costs)[!prev_t][pt][prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001359
Yaowu Xuf883b422016-08-30 14:01:10 -07001360 token_cache[0] = av1_pt_energy_class[prev_t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001361 ++token_costs;
1362
1363 // ac tokens
1364 for (c = 1; c < eob; c++) {
1365 const int rc = scan[c];
1366 int16_t t;
1367
1368 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001369 cost += av1_get_token_cost(v, &t, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001370 cost += (*token_costs)[!t][!prev_t][t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001371 prev_t = t;
1372 if (!--band_left) {
1373 band_left = *band_count++;
1374 ++token_costs;
1375 }
1376 }
1377
1378 // eob token
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001379 cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001380
1381 } else { // !use_fast_coef_costing
1382 int band_left = *band_count++;
1383
1384 // dc token
1385 int v = qcoeff[0];
1386 int16_t tok;
Alex Converseda3d94f2017-03-15 14:54:29 -07001387 cost = av1_get_token_cost(v, &tok, cat6_bits);
Thomas Davies10525752017-03-06 12:10:46 +00001388 cost += (*token_costs)[!tok][pt][tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001389
Yaowu Xuf883b422016-08-30 14:01:10 -07001390 token_cache[0] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001391 ++token_costs;
1392
Yaowu Xuc27fc142016-08-22 16:08:15 -07001393 // ac tokens
1394 for (c = 1; c < eob; c++) {
1395 const int rc = scan[c];
1396
1397 v = qcoeff[rc];
Alex Converseda3d94f2017-03-15 14:54:29 -07001398 cost += av1_get_token_cost(v, &tok, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001399 pt = get_coef_context(nb, token_cache, c);
Thomas Davies10525752017-03-06 12:10:46 +00001400 cost += (*token_costs)[!tok][pt][tok];
Yaowu Xuf883b422016-08-30 14:01:10 -07001401 token_cache[rc] = av1_pt_energy_class[tok];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402 if (!--band_left) {
1403 band_left = *band_count++;
1404 ++token_costs;
1405 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001406 }
1407
1408 // eob token
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001409 pt = get_coef_context(nb, token_cache, c);
1410 cost += (*token_costs)[0][pt][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001411 }
1412 }
1413
Yaowu Xuc27fc142016-08-22 16:08:15 -07001414 return cost;
1415}
Angie Chiang47e4b362017-03-24 11:25:10 -07001416#endif // !CONFIG_LV_MAP
1417
Angie Chiang05917872017-04-15 12:28:56 -07001418int av1_cost_coeffs(const AV1_COMP *const cpi, MACROBLOCK *x, int plane,
Angie Chiang47e4b362017-03-24 11:25:10 -07001419 int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
1420 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l,
1421 int use_fast_coef_costing) {
1422#if !CONFIG_LV_MAP
Angie Chiang05917872017-04-15 12:28:56 -07001423 const AV1_COMMON *const cm = &cpi->common;
Angie Chiang47e4b362017-03-24 11:25:10 -07001424 return cost_coeffs(cm, x, plane, block, tx_size, scan_order, a, l,
1425 use_fast_coef_costing);
1426#else // !CONFIG_LV_MAP
1427 (void)scan_order;
1428 (void)use_fast_coef_costing;
1429 const MACROBLOCKD *xd = &x->e_mbd;
1430 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1431 const struct macroblockd_plane *pd = &xd->plane[plane];
1432 const BLOCK_SIZE bsize = mbmi->sb_type;
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001433#if CONFIG_CHROMA_SUB8X8
Angie Chiang47e4b362017-03-24 11:25:10 -07001434 const BLOCK_SIZE plane_bsize =
1435 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001436#elif CONFIG_CB4X4
1437 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Angie Chiang47e4b362017-03-24 11:25:10 -07001438#else // CONFIG_CB4X4
1439 const BLOCK_SIZE plane_bsize =
1440 get_plane_block_size(AOMMAX(BLOCK_8X8, bsize), pd);
1441#endif // CONFIG_CB4X4
1442
1443 TXB_CTX txb_ctx;
1444 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
Jingning Hanaba246d2017-06-14 12:00:16 -07001445 return av1_cost_coeffs_txb(cpi, x, plane, block, tx_size, &txb_ctx);
Angie Chiang47e4b362017-03-24 11:25:10 -07001446#endif // !CONFIG_LV_MAP
1447}
Fergus Simpson0b96b472017-03-07 15:20:28 -08001448#endif // !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07001449
Alex Converse61f37b82017-03-29 15:26:03 -07001450// Get transform block visible dimensions cropped to the MI units.
1451static void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
1452 BLOCK_SIZE plane_bsize, int blk_row, int blk_col,
1453 BLOCK_SIZE tx_bsize, int *width, int *height,
1454 int *visible_width, int *visible_height) {
Yue Chen56e226e2017-05-02 16:21:40 -07001455#if !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
Alex Converse61f37b82017-03-29 15:26:03 -07001456 assert(tx_bsize <= plane_bsize);
Yue Chen56e226e2017-05-02 16:21:40 -07001457#endif // !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
Alex Converse61f37b82017-03-29 15:26:03 -07001458 int txb_height = block_size_high[tx_bsize];
1459 int txb_width = block_size_wide[tx_bsize];
1460 const int block_height = block_size_high[plane_bsize];
1461 const int block_width = block_size_wide[plane_bsize];
1462 const struct macroblockd_plane *const pd = &xd->plane[plane];
1463 // TODO(aconverse@google.com): Investigate using crop_width/height here rather
1464 // than the MI size
1465 const int block_rows =
1466 (xd->mb_to_bottom_edge >= 0)
1467 ? block_height
1468 : (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
1469 const int block_cols =
1470 (xd->mb_to_right_edge >= 0)
1471 ? block_width
1472 : (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) + block_width;
1473 const int tx_unit_size = tx_size_wide_log2[0];
1474 if (width) *width = txb_width;
1475 if (height) *height = txb_height;
1476 *visible_width = clamp(block_cols - (blk_col << tx_unit_size), 0, txb_width);
1477 *visible_height =
1478 clamp(block_rows - (blk_row << tx_unit_size), 0, txb_height);
1479}
1480
Yushin Cho75b01002017-06-21 13:43:57 -07001481// Compute the pixel domain distortion from src and dst on all visible 4x4s in
1482// the
Alex Converse61f37b82017-03-29 15:26:03 -07001483// transform block.
Yushin Cho75b01002017-06-21 13:43:57 -07001484static unsigned pixel_dist(const AV1_COMP *const cpi, const MACROBLOCK *x,
1485 int plane, const uint8_t *src, const int src_stride,
1486 const uint8_t *dst, const int dst_stride,
1487 int blk_row, int blk_col,
1488 const BLOCK_SIZE plane_bsize,
1489 const BLOCK_SIZE tx_bsize) {
Alex Converse61f37b82017-03-29 15:26:03 -07001490 int txb_rows, txb_cols, visible_rows, visible_cols;
Yushin Cho75b01002017-06-21 13:43:57 -07001491 const MACROBLOCKD *xd = &x->e_mbd;
1492#if CONFIG_DAALA_DIST
1493 int qm = OD_HVS_QM;
1494 int use_activity_masking = 0;
1495#if CONFIG_PVQ
1496 use_activity_masking = x->daala_enc.use_activity_masking;
1497#endif // CONFIG_PVQ
1498#endif // CONFIG_DAALA_DIST
Alex Converse61f37b82017-03-29 15:26:03 -07001499 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize,
1500 &txb_cols, &txb_rows, &visible_cols, &visible_rows);
1501 assert(visible_rows > 0);
1502 assert(visible_cols > 0);
Yushin Cho75b01002017-06-21 13:43:57 -07001503
1504#if CONFIG_DAALA_DIST
1505 if (plane == 0 && txb_cols >= 8 && txb_rows >= 8)
Yushin Cho8ab875d2017-06-23 14:47:21 -07001506 return av1_daala_dist(xd, src, src_stride, dst, dst_stride, txb_cols,
1507 txb_rows, visible_cols, visible_rows, qm,
1508 use_activity_masking, x->qindex);
Yushin Cho75b01002017-06-21 13:43:57 -07001509#endif // CONFIG_DAALA_DIST
1510
Yue Chen56e226e2017-05-02 16:21:40 -07001511#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
1512 if ((txb_rows == visible_rows && txb_cols == visible_cols) &&
1513 tx_bsize < BLOCK_SIZES) {
1514#else
Alex Converse61f37b82017-03-29 15:26:03 -07001515 if (txb_rows == visible_rows && txb_cols == visible_cols) {
Yue Chen56e226e2017-05-02 16:21:40 -07001516#endif
Alex Converse61f37b82017-03-29 15:26:03 -07001517 unsigned sse;
1518 cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse);
1519 return sse;
1520 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001521#if CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001522 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1523 uint64_t sse = aom_highbd_sse_odd_size(src, src_stride, dst, dst_stride,
1524 visible_cols, visible_rows);
1525 return (unsigned int)ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
1526 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001527#endif // CONFIG_HIGHBITDEPTH
Alex Converse61f37b82017-03-29 15:26:03 -07001528 unsigned sse = aom_sse_odd_size(src, src_stride, dst, dst_stride,
1529 visible_cols, visible_rows);
1530 return sse;
1531}
1532
Yushin Cho75b01002017-06-21 13:43:57 -07001533// Compute the pixel domain distortion from diff on all visible 4x4s in the
1534// transform block.
1535static int64_t pixel_diff_dist(const MACROBLOCK *x, int plane,
1536 const int16_t *diff, const int diff_stride,
1537 int blk_row, int blk_col,
1538 const BLOCK_SIZE plane_bsize,
1539 const BLOCK_SIZE tx_bsize) {
Alex Converse61f37b82017-03-29 15:26:03 -07001540 int visible_rows, visible_cols;
Yushin Cho75b01002017-06-21 13:43:57 -07001541 const MACROBLOCKD *xd = &x->e_mbd;
1542#if CONFIG_DAALA_DIST
1543 int txb_height = block_size_high[tx_bsize];
1544 int txb_width = block_size_wide[tx_bsize];
1545 const int src_stride = x->plane[plane].src.stride;
1546 const int src_idx = (blk_row * src_stride + blk_col) << tx_size_wide_log2[0];
1547 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1548 int qm = OD_HVS_QM;
1549 int use_activity_masking = 0;
1550#if CONFIG_PVQ
1551 use_activity_masking = x->daala_enc.use_activity_masking;
1552#endif // CONFIG_PVQ
1553#endif
1554
Alex Converse61f37b82017-03-29 15:26:03 -07001555 get_txb_dimensions(xd, plane, plane_bsize, blk_row, blk_col, tx_bsize, NULL,
1556 NULL, &visible_cols, &visible_rows);
Yushin Cho75b01002017-06-21 13:43:57 -07001557
1558#if CONFIG_DAALA_DIST
1559 if (plane == 0 && txb_width >= 8 && txb_height >= 8)
Yushin Cho8ab875d2017-06-23 14:47:21 -07001560 return av1_daala_dist_diff(
1561 xd, src, src_stride, diff, diff_stride, txb_width, txb_height,
1562 visible_cols, visible_rows, qm, use_activity_masking, x->qindex);
Yushin Cho75b01002017-06-21 13:43:57 -07001563 else
1564#endif
1565 return aom_sum_squares_2d_i16(diff, diff_stride, visible_cols,
1566 visible_rows);
Alex Converse61f37b82017-03-29 15:26:03 -07001567}
1568
Angie Chiang808d8592017-04-06 18:36:55 -07001569void av1_dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane,
1570 BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col,
1571 TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse,
1572 OUTPUT_STATUS output_status) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001573 MACROBLOCKD *const xd = &x->e_mbd;
1574 const struct macroblock_plane *const p = &x->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001575#if CONFIG_DAALA_DIST
Yushin Cho4483e3d2017-04-18 19:41:20 -07001576 struct macroblockd_plane *const pd = &xd->plane[plane];
1577#else // CONFIG_DAALA_DIST
1578 const struct macroblockd_plane *const pd = &xd->plane[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001579#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001580
1581 if (cpi->sf.use_transform_domain_distortion && !CONFIG_DAALA_DIST) {
hui sud2f12ba2017-04-12 10:08:43 -07001582 // Transform domain distortion computation is more efficient as it does
Yaowu Xuc27fc142016-08-22 16:08:15 -07001583 // not involve an inverse transform, but it is less accurate.
Jingning Hanb9c57272016-10-25 10:15:39 -07001584 const int buffer_length = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001585 int64_t this_sse;
Jingning Hanff705452017-04-27 11:32:15 -07001586 int shift = (MAX_TX_SCALE - av1_get_tx_scale(tx_size)) * 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001587 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
1588 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001589#if CONFIG_PVQ
Yaowu Xud6ea71c2016-11-07 10:24:14 -08001590 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001591
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001592#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001593 const int bd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? xd->bd : 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001594 *out_dist = av1_highbd_block_error2_c(coeff, dqcoeff, ref_coeff,
1595 buffer_length, &this_sse, bd) >>
1596 shift;
1597#else
1598 *out_dist = av1_block_error2_c(coeff, dqcoeff, ref_coeff, buffer_length,
1599 &this_sse) >>
1600 shift;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001601#endif // CONFIG_HIGHBITDEPTH
Yi Luod61e6082017-05-26 16:14:39 -07001602#else // !CONFIG_PVQ
1603#if CONFIG_HIGHBITDEPTH
1604 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1605 *out_dist = av1_highbd_block_error(coeff, dqcoeff, buffer_length,
1606 &this_sse, xd->bd) >>
1607 shift;
1608 else
1609#endif
1610 *out_dist =
1611 av1_block_error(coeff, dqcoeff, buffer_length, &this_sse) >> shift;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001612#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001613 *out_sse = this_sse >> shift;
1614 } else {
1615 const BLOCK_SIZE tx_bsize = txsize_to_bsize[tx_size];
Angie Chiang50910f62017-04-03 12:31:34 -07001616#if !CONFIG_PVQ || CONFIG_DAALA_DIST
Jingning Hanb9c57272016-10-25 10:15:39 -07001617 const int bsw = block_size_wide[tx_bsize];
1618 const int bsh = block_size_high[tx_bsize];
Angie Chiang50910f62017-04-03 12:31:34 -07001619#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620 const int src_stride = x->plane[plane].src.stride;
1621 const int dst_stride = xd->plane[plane].dst.stride;
Jingning Hanb9c57272016-10-25 10:15:39 -07001622 // Scale the transform block index to pixel unit.
1623 const int src_idx = (blk_row * src_stride + blk_col)
1624 << tx_size_wide_log2[0];
1625 const int dst_idx = (blk_row * dst_stride + blk_col)
1626 << tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001627 const uint8_t *src = &x->plane[plane].src.buf[src_idx];
1628 const uint8_t *dst = &xd->plane[plane].dst.buf[dst_idx];
1629 const tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1630 const uint16_t eob = p->eobs[block];
1631
Yaowu Xuc27fc142016-08-22 16:08:15 -07001632 assert(cpi != NULL);
Jingning Hanb9c57272016-10-25 10:15:39 -07001633 assert(tx_size_wide_log2[0] == tx_size_high_log2[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001634
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001635 {
1636 const int diff_stride = block_size_wide[plane_bsize];
1637 const int diff_idx = (blk_row * diff_stride + blk_col)
1638 << tx_size_wide_log2[0];
1639 const int16_t *diff = &p->src_diff[diff_idx];
Yushin Cho75b01002017-06-21 13:43:57 -07001640 *out_sse = pixel_diff_dist(x, plane, diff, diff_stride, blk_row, blk_col,
1641 plane_bsize, tx_bsize);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001642#if CONFIG_HIGHBITDEPTH
hui sub1cc1f92017-04-11 17:41:29 -07001643 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Alex Conversef323f012017-04-24 09:26:33 -07001644 *out_sse = ROUND_POWER_OF_TWO(*out_sse, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001645#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001646 }
Alex Conversef323f012017-04-24 09:26:33 -07001647 *out_sse *= 16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001648
1649 if (eob) {
Angie Chiang228cc182017-04-07 15:22:16 -07001650 if (output_status == OUTPUT_HAS_DECODED_PIXELS) {
Yushin Cho75b01002017-06-21 13:43:57 -07001651 *out_dist = pixel_dist(cpi, x, plane, src, src_stride, dst, dst_stride,
1652 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001653 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001654#if CONFIG_HIGHBITDEPTH
Jingning Han6a9dbef2017-04-10 10:25:14 -07001655 uint8_t *recon;
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001656 DECLARE_ALIGNED(16, uint16_t, recon16[MAX_TX_SQUARE]);
Jingning Han6a9dbef2017-04-10 10:25:14 -07001657
1658 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1659 recon = CONVERT_TO_BYTEPTR(recon16);
1660 else
1661 recon = (uint8_t *)recon16;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001662#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001663 DECLARE_ALIGNED(16, uint8_t, recon[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001664#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001665
Angie Chiang50910f62017-04-03 12:31:34 -07001666#if !CONFIG_PVQ
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001667#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001668 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1669 aom_highbd_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0,
1670 NULL, 0, bsw, bsh, xd->bd);
1671 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001672#endif // CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001673 aom_convolve_copy(dst, dst_stride, recon, MAX_TX_SIZE, NULL, 0, NULL,
1674 0, bsw, bsh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001675#if CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001676 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001677#endif // CONFIG_HIGHBITDEPTH
Angie Chiangc0cf6c02017-04-04 13:47:27 -07001678#else
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001679 (void)dst;
Angie Chiang50910f62017-04-03 12:31:34 -07001680#endif // !CONFIG_PVQ
Angie Chiang41fffae2017-04-03 10:33:18 -07001681
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001682 const PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001683 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiang41fffae2017-04-03 10:33:18 -07001684
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001685 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, recon,
1686 MAX_TX_SIZE, eob);
Angie Chiang41fffae2017-04-03 10:33:18 -07001687
Yushin Cho7a428ba2017-01-12 16:28:49 -08001688#if CONFIG_DAALA_DIST
Yushin Cho75b01002017-06-21 13:43:57 -07001689 if (plane == 0 && (bsw < 8 || bsh < 8)) {
1690 // Save decoded pixels for inter block in pd->pred to avoid
1691 // block_8x8_rd_txfm_daala_dist() need to produce them
1692 // by calling av1_inverse_transform_block() again.
1693 const int pred_stride = block_size_wide[plane_bsize];
1694 const int pred_idx = (blk_row * pred_stride + blk_col)
1695 << tx_size_wide_log2[0];
1696 int16_t *pred = &pd->pred[pred_idx];
1697 int i, j;
Yushin Cho4483e3d2017-04-18 19:41:20 -07001698
Yushin Cho8ab875d2017-06-23 14:47:21 -07001699#if CONFIG_HIGHBITDEPTH
1700 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1701 for (j = 0; j < bsh; j++)
1702 for (i = 0; i < bsw; i++)
1703 pred[j * pred_stride + i] =
1704 CONVERT_TO_SHORTPTR(recon)[j * MAX_TX_SIZE + i];
1705 } else {
1706#endif
1707 for (j = 0; j < bsh; j++)
1708 for (i = 0; i < bsw; i++)
1709 pred[j * pred_stride + i] = recon[j * MAX_TX_SIZE + i];
1710#if CONFIG_HIGHBITDEPTH
1711 }
1712#endif // CONFIG_HIGHBITDEPTH
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001713 }
1714#endif // CONFIG_DAALA_DIST
Yushin Cho75b01002017-06-21 13:43:57 -07001715 *out_dist =
1716 pixel_dist(cpi, x, plane, src, src_stride, recon, MAX_TX_SIZE,
1717 blk_row, blk_col, plane_bsize, tx_bsize);
Angie Chiang8f6ddec2017-04-04 17:07:00 -07001718 }
Alex Conversef323f012017-04-24 09:26:33 -07001719 *out_dist *= 16;
1720 } else {
1721 *out_dist = *out_sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001722 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723 }
1724}
1725
Yaowu Xuc27fc142016-08-22 16:08:15 -07001726static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
1727 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
1728 struct rdcost_block_args *args = arg;
1729 MACROBLOCK *const x = args->x;
1730 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001731 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiange50f3ec2017-04-10 15:50:33 -07001732 const AV1_COMP *cpi = args->cpi;
Angie Chiang65a39bb2017-04-11 16:50:04 -07001733 ENTROPY_CONTEXT *a = args->t_above + blk_col;
1734 ENTROPY_CONTEXT *l = args->t_left + blk_row;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001735#if !CONFIG_TXK_SEL
Angie Chiang18ad8942017-04-11 12:37:07 -07001736 const AV1_COMMON *cm = &cpi->common;
1737#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001738 int64_t rd1, rd2, rd;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001739 RD_STATS this_rd_stats;
Yushin Cho6341f5c2017-03-24 14:36:28 -07001740
Jingning Hane65436b2017-06-14 09:26:11 -07001741#if !CONFIG_SUPERTX && !CONFIG_VAR_TX
Angie Chiangbc2288c2017-04-09 15:41:17 -07001742 assert(tx_size == get_tx_size(plane, xd));
Yue Chen8e689e42017-06-02 10:56:10 -07001743#endif // !CONFIG_SUPERTX
Angie Chiangbc2288c2017-04-09 15:41:17 -07001744
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001745 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001746
1747 if (args->exit_early) return;
1748
1749 if (!is_inter_block(mbmi)) {
Luc Trudeauf5334002017-04-25 12:21:26 -04001750#if CONFIG_CFL
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001751
1752#if CONFIG_EC_ADAPT
1753 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
1754#else
1755 FRAME_CONTEXT *const ec_ctx = cm->fc;
1756#endif // CONFIG_EC_ADAPT
1757
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001758#if CONFIG_DEBUG
1759// av1_predict_intra_block_facade does not pass plane_bsize, we need to validate
1760// that we will get the same value of plane_bsize on the other side.
1761#if CONFIG_CHROMA_SUB8X8
1762 const BLOCK_SIZE plane_bsize_val = AOMMAX(
1763 BLOCK_4X4, get_plane_block_size(mbmi->sb_type, &xd->plane[plane]));
1764#else
1765 const BLOCK_SIZE plane_bsize_val =
1766 get_plane_block_size(mbmi->sb_type, &xd->plane[plane]);
1767#endif // CONFIG_CHROMA_SUB8X8
1768 assert(plane_bsize == plane_bsize_val);
1769#endif // CONFIG_DEBUG
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001770 av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001771 blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001772#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001773 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001774#endif
hui sub8a6fd62017-05-10 10:57:57 -07001775#if CONFIG_DPCM_INTRA
1776 const int block_raster_idx =
1777 av1_block_index_to_raster_order(tx_size, block);
1778 const PREDICTION_MODE mode =
1779 (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
1780 TX_TYPE tx_type = get_tx_type((plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV,
1781 xd, block, tx_size);
1782 if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
1783 int8_t skip;
1784 av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
1785 plane_bsize, tx_size, tx_type, a, l, &skip);
1786 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1787 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1788 OUTPUT_HAS_DECODED_PIXELS);
1789 goto CALCULATE_RD;
1790 }
1791#endif // CONFIG_DPCM_INTRA
Angie Chiang62e54cd2017-04-06 10:45:56 -07001792 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
1793 }
1794
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001795#if !CONFIG_TXK_SEL
Angie Chiang62e54cd2017-04-06 10:45:56 -07001796 // full forward transform and quantization
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001797 const int coeff_ctx = combine_entropy_contexts(*a, *l);
Sarah Parker345366a2017-06-15 12:13:01 -07001798#if DISABLE_TRELLISQ_SEARCH
1799 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1800 coeff_ctx, AV1_XFORM_QUANT_B);
1801#else
Angie Chiang62e54cd2017-04-06 10:45:56 -07001802 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1803 coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07001804 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Sarah Parker345366a2017-06-15 12:13:01 -07001805#endif // DISABLE_TRELLISQ_SEARCH
Angie Chiang62e54cd2017-04-06 10:45:56 -07001806
1807 if (!is_inter_block(mbmi)) {
1808 struct macroblock_plane *const p = &x->plane[plane];
Angie Chiangbc2288c2017-04-09 15:41:17 -07001809 av1_inverse_transform_block_facade(xd, plane, block, blk_row, blk_col,
1810 p->eobs[block]);
Angie Chiang808d8592017-04-06 18:36:55 -07001811 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1812 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1813 OUTPUT_HAS_DECODED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001814 } else {
Angie Chiang808d8592017-04-06 18:36:55 -07001815 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1816 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1817 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001818 }
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001819#if CONFIG_CFL
1820 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1821 struct macroblockd_plane *const pd = &xd->plane[plane];
1822 const int dst_stride = pd->dst.stride;
1823 uint8_t *dst =
1824 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Luc Trudeau780d2492017-06-15 22:26:41 -04001825 // TODO (ltrudeau) Store sub-8x8 inter blocks when bottom right block is
1826 // intra predicted.
1827 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size, plane_bsize);
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001828 }
1829#endif
hui sub8a6fd62017-05-10 10:57:57 -07001830#if CONFIG_DPCM_INTRA
1831CALCULATE_RD : {}
1832#endif // CONFIG_DPCM_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07001833 rd = RDCOST(x->rdmult, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001834 if (args->this_rd + rd > args->best_rd) {
1835 args->exit_early = 1;
1836 return;
1837 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001838#if !CONFIG_PVQ
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001839 const PLANE_TYPE plane_type = get_plane_type(plane);
1840 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07001841 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
Angie Chiang05917872017-04-15 12:28:56 -07001842 this_rd_stats.rate =
1843 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l,
1844 args->use_fast_coef_costing);
Angie Chiang65a39bb2017-04-11 16:50:04 -07001845#else // !CONFIG_PVQ
1846 this_rd_stats.rate = x->rate;
1847#endif // !CONFIG_PVQ
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001848#else // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001849 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
1850 tx_size, a, l, args->use_fast_coef_costing,
1851 &this_rd_stats);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001852#endif // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001853
1854#if !CONFIG_PVQ
Angie Chiang3963d632016-11-10 18:41:40 -08001855#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001856 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1857 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001858#endif // CONFIG_RD_DEBUG
Yushin Cho6341f5c2017-03-24 14:36:28 -07001859 av1_set_txb_context(x, plane, block, tx_size, a, l);
Fergus Simpson4063a682017-02-28 16:52:22 -08001860#endif // !CONFIG_PVQ
Angie Chiangb3a12b52017-03-23 14:53:10 -07001861
Urvang Joshi70006e42017-06-14 16:08:55 -07001862 rd1 = RDCOST(x->rdmult, this_rd_stats.rate, this_rd_stats.dist);
1863 rd2 = RDCOST(x->rdmult, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001864
1865 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001866 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001867
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001868#if !CONFIG_PVQ
1869 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1870#else
1871 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001872#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001873 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001874
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 args->this_rd += rd;
1876
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001877#if CONFIG_DAALA_DIST
1878 if (!(plane == 0 && plane_bsize >= BLOCK_8X8 &&
1879 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))) {
1880#endif
1881 if (args->this_rd > args->best_rd) {
1882 args->exit_early = 1;
1883 return;
1884 }
1885#if CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07001886 }
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001887#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001888}
1889
Yushin Cho7a428ba2017-01-12 16:28:49 -08001890#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001891static void daala_dist_sub8x8_txfm_rd(MACROBLOCK *x, BLOCK_SIZE bsize,
1892 struct rdcost_block_args *args) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08001893 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001894 const struct macroblockd_plane *const pd = &xd->plane[0];
1895 const struct macroblock_plane *const p = &x->plane[0];
Yushin Cho4483e3d2017-04-18 19:41:20 -07001896 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001897 const int src_stride = p->src.stride;
1898 const int dst_stride = pd->dst.stride;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001899 const uint8_t *src = &p->src.buf[0];
1900 const uint8_t *dst = &pd->dst.buf[0];
1901 const int16_t *pred = &pd->pred[0];
1902 const int bw = block_size_wide[bsize];
1903 const int bh = block_size_high[bsize];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001904
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001905 int i, j;
1906 int64_t rd, rd1, rd2;
1907 int qm = OD_HVS_QM;
1908 int use_activity_masking = 0;
1909 unsigned int tmp1, tmp2;
1910 int qindex = x->qindex;
Yushin Cho04749122017-05-25 14:19:07 -07001911#if CONFIG_PVQ
1912 use_activity_masking = x->daala_enc.use_activity_masking;
1913#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -08001914
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001915 assert((bw & 0x07) == 0);
1916 assert((bh & 0x07) == 0);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001917
Yushin Cho8ab875d2017-06-23 14:47:21 -07001918#if CONFIG_HIGHBITDEPTH
1919 uint8_t *pred8;
1920 DECLARE_ALIGNED(16, uint16_t, pred16[MAX_TX_SQUARE]);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001921
Yushin Cho8ab875d2017-06-23 14:47:21 -07001922 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1923 pred8 = CONVERT_TO_BYTEPTR(pred16);
1924 else
1925 pred8 = (uint8_t *)pred16;
1926#else
1927 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1928#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001929
Yushin Cho8ab875d2017-06-23 14:47:21 -07001930#if CONFIG_HIGHBITDEPTH
1931 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1932 for (j = 0; j < bh; j++)
1933 for (i = 0; i < bw; i++)
1934 CONVERT_TO_SHORTPTR(pred8)[j * bw + i] = pred[j * bw + i];
1935 } else {
1936#endif
1937 for (j = 0; j < bh; j++)
1938 for (i = 0; i < bw; i++) pred8[j * bw + i] = pred[j * bw + i];
1939#if CONFIG_HIGHBITDEPTH
1940 }
1941#endif // CONFIG_HIGHBITDEPTH
1942
1943 tmp1 = av1_daala_dist(xd, src, src_stride, pred8, bw, bw, bh, bw, bh, qm,
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001944 use_activity_masking, qindex);
Yushin Cho8ab875d2017-06-23 14:47:21 -07001945 tmp2 = av1_daala_dist(xd, src, src_stride, dst, dst_stride, bw, bh, bw, bh,
1946 qm, use_activity_masking, qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001947
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001948 if (!is_inter_block(mbmi)) {
1949 args->rd_stats.sse = (int64_t)tmp1 * 16;
1950 args->rd_stats.dist = (int64_t)tmp2 * 16;
1951 } else {
1952 // For inter mode, the decoded pixels are provided in pd->pred,
1953 // while the predicted pixels are in dst.
1954 args->rd_stats.sse = (int64_t)tmp2 * 16;
1955 args->rd_stats.dist = (int64_t)tmp1 * 16;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001956 }
1957
Urvang Joshi70006e42017-06-14 16:08:55 -07001958 rd1 = RDCOST(x->rdmult, args->rd_stats.rate, args->rd_stats.dist);
1959 rd2 = RDCOST(x->rdmult, 0, args->rd_stats.sse);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001960 rd = AOMMIN(rd1, rd2);
1961
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001962 args->rd_stats.rdcost = rd;
1963 args->this_rd = rd;
Yushin Cho04eb9592017-06-21 17:35:06 -07001964
1965 if (args->this_rd > args->best_rd) args->exit_early = 1;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001966}
Fergus Simpson4063a682017-02-28 16:52:22 -08001967#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001968
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001969static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1970 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1971 BLOCK_SIZE bsize, TX_SIZE tx_size,
1972 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973 MACROBLOCKD *const xd = &x->e_mbd;
1974 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001976 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977 args.x = x;
1978 args.cpi = cpi;
1979 args.best_rd = ref_best_rd;
1980 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001981 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001982
1983 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1984
Yaowu Xuf883b422016-08-30 14:01:10 -07001985 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001987 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1988 &args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001989#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001990 if (!args.exit_early && plane == 0 && bsize >= BLOCK_8X8 &&
Yushin Cho7a428ba2017-01-12 16:28:49 -08001991 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001992 daala_dist_sub8x8_txfm_rd(x, bsize, &args);
1993#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -08001994
Yaowu Xuc27fc142016-08-22 16:08:15 -07001995 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001996 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001997 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001998 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001999 }
2000}
2001
2002#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07002003void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
2004 int64_t *distortion, int *skippable,
2005 int64_t *sse, int64_t ref_best_rd, int plane,
2006 BLOCK_SIZE bsize, TX_SIZE tx_size,
2007 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008 MACROBLOCKD *const xd = &x->e_mbd;
2009 const struct macroblockd_plane *const pd = &xd->plane[plane];
2010 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07002011 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002012 args.cpi = cpi;
2013 args.x = x;
2014 args.best_rd = ref_best_rd;
2015 args.use_fast_coef_costing = use_fast_coef_casting;
2016
2017#if CONFIG_EXT_TX
2018 assert(tx_size < TX_SIZES);
2019#endif // CONFIG_EXT_TX
2020
2021 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
2022
Yaowu Xuf883b422016-08-30 14:01:10 -07002023 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002024
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
2026 &args);
2027
2028 if (args.exit_early) {
2029 *rate = INT_MAX;
2030 *distortion = INT64_MAX;
2031 *sse = INT64_MAX;
2032 *skippable = 0;
2033 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002034 *distortion = args.rd_stats.dist;
2035 *rate = args.rd_stats.rate;
2036 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002037 *skippable = !x->plane[plane].eobs[0];
2038 }
2039}
2040#endif // CONFIG_SUPERTX
2041
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002042static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002043 BLOCK_SIZE bsize, TX_SIZE tx_size) {
2044 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002045 const MACROBLOCKD *const xd = &x->e_mbd;
2046 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002047
2048 const int tx_select =
2049 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
2050
2051 if (tx_select) {
2052 const int is_inter = is_inter_block(mbmi);
2053 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
2054 : intra_tx_size_cat_lookup[bsize];
2055 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
2056 const int depth = tx_size_to_depth(coded_tx_size);
2057 const int tx_size_ctx = get_tx_size_context(xd);
Yue Chen56e226e2017-05-02 16:21:40 -07002058 int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
2059#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
2060 if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size)
2061 r_tx_size += av1_cost_bit(cm->fc->quarter_tx_size_prob,
2062 tx_size == quarter_txsize_lookup[bsize]);
2063#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002064 return r_tx_size;
2065 } else {
2066 return 0;
2067 }
2068}
2069
Angie Chiang65201562017-04-10 15:23:28 -07002070// #TODO(angiebird): use this function whenever it's possible
Angie Chiang05917872017-04-15 12:28:56 -07002071int av1_tx_type_cost(const AV1_COMP *cpi, const MACROBLOCKD *xd,
2072 BLOCK_SIZE bsize, int plane, TX_SIZE tx_size,
2073 TX_TYPE tx_type) {
2074 if (plane > 0) return 0;
2075
Jingning Han243b66b2017-06-23 12:11:47 -07002076#if CONFIG_VAR_TX
2077 tx_size = get_min_tx_size(tx_size);
2078#endif
2079
Angie Chiang65201562017-04-10 15:23:28 -07002080 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2081 const int is_inter = is_inter_block(mbmi);
2082#if CONFIG_EXT_TX
2083 const AV1_COMMON *cm = &cpi->common;
2084 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
2085 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2086 const int ext_tx_set =
2087 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
2088 if (is_inter) {
2089 if (ext_tx_set > 0)
2090 return cpi
2091 ->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]][tx_type];
2092 } else {
2093 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
2094 return cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]]
2095 [mbmi->mode][tx_type];
2096 }
2097 }
2098#else
2099 (void)bsize;
2100 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2101 !FIXED_TX_TYPE) {
2102 if (is_inter) {
2103 return cpi->inter_tx_type_costs[tx_size][tx_type];
2104 } else {
2105 return cpi->intra_tx_type_costs[tx_size]
2106 [intra_mode_to_tx_type_context[mbmi->mode]]
2107 [tx_type];
2108 }
2109 }
2110#endif // CONFIG_EXT_TX
2111 return 0;
2112}
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002113static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2114 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
2115 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07002116 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002117 MACROBLOCKD *const xd = &x->e_mbd;
2118 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2119 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002120 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121 int s0, s1;
2122 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002123 const int tx_select =
2124 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002125
2126 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002127
2128 assert(skip_prob > 0);
2129#if CONFIG_EXT_TX && CONFIG_RECT_TX
2130 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
2131#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2132
Yaowu Xuf883b422016-08-30 14:01:10 -07002133 s0 = av1_cost_bit(skip_prob, 0);
2134 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002135
2136 mbmi->tx_type = tx_type;
2137 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002138 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002139 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002140 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002141#if !CONFIG_TXK_SEL
Angie Chiang05917872017-04-15 12:28:56 -07002142 int plane = 0;
2143 rd_stats->rate += av1_tx_type_cost(cpi, xd, bs, plane, tx_size, tx_type);
2144#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002146 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002147 if (is_inter) {
Urvang Joshi70006e42017-06-14 16:08:55 -07002148 rd = RDCOST(x->rdmult, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002149 } else {
Urvang Joshi70006e42017-06-14 16:08:55 -07002150 rd = RDCOST(x->rdmult, s1 + r_tx_size * tx_select, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002151 }
2152 } else {
Urvang Joshi70006e42017-06-14 16:08:55 -07002153 rd = RDCOST(x->rdmult, rd_stats->rate + s0 + r_tx_size * tx_select,
2154 rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155 }
2156
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002157 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002158
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002159 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2160 !(rd_stats->skip))
Urvang Joshi70006e42017-06-14 16:08:55 -07002161 rd = AOMMIN(rd, RDCOST(x->rdmult, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002162
2163 return rd;
2164}
2165
Angie Chiang2d147c12017-04-05 11:23:59 -07002166static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
2167 TX_TYPE tx_type, TX_SIZE tx_size) {
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002168 const MACROBLOCKD *const xd = &x->e_mbd;
2169 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiang2d147c12017-04-05 11:23:59 -07002170 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2171 const int is_inter = is_inter_block(mbmi);
2172 int prune = 0;
2173 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2174 // passing -1 in for tx_type indicates that all 1D
2175 // transforms should be considered for pruning
2176 prune = prune_tx_types(cpi, bs, x, xd, -1);
2177
Angie Chianga4fa1902017-04-05 15:26:09 -07002178 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
Angie Chiang2d147c12017-04-05 11:23:59 -07002179 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
2180 return 1;
2181 if (!is_inter && x->use_default_intra_tx_type &&
2182 tx_type != get_default_tx_type(0, xd, 0, tx_size))
2183 return 1;
2184 if (is_inter && x->use_default_inter_tx_type &&
2185 tx_type != get_default_tx_type(0, xd, 0, tx_size))
2186 return 1;
2187 if (max_tx_size >= TX_32X32 && tx_size == TX_4X4) return 1;
2188#if CONFIG_EXT_TX
2189 const AV1_COMMON *const cm = &cpi->common;
2190 int ext_tx_set =
2191 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
2192 if (is_inter) {
2193 if (!ext_tx_used_inter[ext_tx_set][tx_type]) return 1;
2194 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2195 if (!do_tx_type_search(tx_type, prune)) return 1;
2196 }
2197 } else {
2198 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2199 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) return 1;
2200 }
2201 if (!ext_tx_used_intra[ext_tx_set][tx_type]) return 1;
2202 }
2203#else // CONFIG_EXT_TX
2204 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) return 1;
2205 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2206 !do_tx_type_search(tx_type, prune))
2207 return 1;
2208#endif // CONFIG_EXT_TX
2209 return 0;
2210}
2211
Yue Chen5e606542017-05-24 17:03:17 -07002212#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Urvang Joshi52648442016-10-13 17:27:51 -07002213static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
2214 MACROBLOCK *x, int *r, int64_t *d, int *s,
2215 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002216 RD_STATS rd_stats;
2217 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
2218 max_txsize_lookup[bs]);
2219 *r = rd_stats.rate;
2220 *d = rd_stats.dist;
2221 *s = rd_stats.skip;
2222 *sse = rd_stats.sse;
2223 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002224}
Yue Chen5e606542017-05-24 17:03:17 -07002225#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226
Urvang Joshi52648442016-10-13 17:27:51 -07002227static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002228 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07002229 BLOCK_SIZE bs) {
2230 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002231 MACROBLOCKD *const xd = &x->e_mbd;
2232 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2233 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002234 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002235 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
2236 int s0 = av1_cost_bit(skip_prob, 0);
2237 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238 const int is_inter = is_inter_block(mbmi);
2239 int prune = 0;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002240 const int plane = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002241#if CONFIG_EXT_TX
2242 int ext_tx_set;
2243#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002244 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002245
2246 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002247#if CONFIG_VAR_TX
2248 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002249#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002250#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002251 ext_tx_set =
2252 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253#endif // CONFIG_EXT_TX
2254
2255 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2256#if CONFIG_EXT_TX
2257 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2258#else
2259 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08002260#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002261#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002262 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2263 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002264 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002265#if CONFIG_PVQ
2266 od_rollback_buffer pre_buf, post_buf;
2267
2268 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2269 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002270#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002271
2272 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002273 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002274 if (is_inter) {
2275 if (x->use_default_inter_tx_type &&
2276 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2277 continue;
2278 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2279 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2280 if (!do_tx_type_search(tx_type, prune)) continue;
2281 }
2282 } else {
2283 if (x->use_default_intra_tx_type &&
2284 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2285 continue;
2286 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2287 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2288 }
2289 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2290 }
2291
2292 mbmi->tx_type = tx_type;
2293
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002294 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002295 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002296#if CONFIG_PVQ
2297 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002298#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002299 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002300 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002301
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002302 if (this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002303 this_rd = RDCOST(x->rdmult, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304 else
Urvang Joshi70006e42017-06-14 16:08:55 -07002305 this_rd =
2306 RDCOST(x->rdmult, this_rd_stats.rate + s0, this_rd_stats.dist);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002307 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2308 !this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002309 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002310
2311 if (this_rd < best_rd) {
2312 best_rd = this_rd;
2313 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002314 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002315#if CONFIG_PVQ
2316 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002317#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002318 }
2319 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002320#if CONFIG_PVQ
2321 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002322#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002323 } else {
2324 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002325 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2326 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002327 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002328#else // CONFIG_EXT_TX
2329 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2330 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002331 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002332 if (!is_inter && x->use_default_intra_tx_type &&
2333 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2334 continue;
2335 if (is_inter && x->use_default_inter_tx_type &&
2336 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2337 continue;
2338 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002339 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002340 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002341 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002342
2343 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002344 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002345 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2346 !do_tx_type_search(tx_type, prune))
2347 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002348 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002349 if (this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002350 this_rd = RDCOST(x->rdmult, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002352 this_rd =
Urvang Joshi70006e42017-06-14 16:08:55 -07002353 RDCOST(x->rdmult, this_rd_stats.rate + s0, this_rd_stats.dist);
2354 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2355 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002356
2357 if (this_rd < best_rd) {
2358 best_rd = this_rd;
2359 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002360 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002361 }
2362 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002363 } else {
2364 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002365 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2366 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002367 }
2368#endif // CONFIG_EXT_TX
2369 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002370}
2371
Urvang Joshi52648442016-10-13 17:27:51 -07002372static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002373 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002374 BLOCK_SIZE bs) {
2375 MACROBLOCKD *const xd = &x->e_mbd;
2376 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2377
2378 mbmi->tx_size = TX_4X4;
2379 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002380#if CONFIG_VAR_TX
2381 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002382#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002384 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2385 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002386}
2387
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002388#if CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002389static INLINE int bsize_to_num_blk(BLOCK_SIZE bsize) {
2390 int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
2391 return num_blk;
2392}
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002393#endif // CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002394
Urvang Joshi52648442016-10-13 17:27:51 -07002395static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002396 MACROBLOCK *x, RD_STATS *rd_stats,
2397 int64_t ref_best_rd, BLOCK_SIZE bs) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002398 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002399 MACROBLOCKD *const xd = &x->e_mbd;
2400 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002401 int64_t rd = INT64_MAX;
Angie Chianga4fa1902017-04-05 15:26:09 -07002402 int n;
2403 int start_tx, end_tx;
2404 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
2405 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2406 TX_SIZE best_tx_size = max_tx_size;
2407 TX_TYPE best_tx_type = DCT_DCT;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002408#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002409 TX_TYPE best_txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
2410 const int num_blk = bsize_to_num_blk(bs);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002411#endif // CONFIG_TXK_SEL
Angie Chianga4fa1902017-04-05 15:26:09 -07002412 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
2413 const int is_inter = is_inter_block(mbmi);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002414#if CONFIG_PVQ
2415 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002416 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002417#endif // CONFIG_PVQ
Angie Chianga4fa1902017-04-05 15:26:09 -07002418
2419 av1_invalid_rd_stats(rd_stats);
2420
2421#if CONFIG_EXT_TX && CONFIG_RECT_TX
2422 int evaluate_rect_tx = 0;
2423 if (tx_select) {
2424 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
2425 } else {
2426 const TX_SIZE chosen_tx_size =
2427 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2428 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
2429 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
2430 }
2431 if (evaluate_rect_tx) {
Angie Chiangf1cb0752017-04-10 16:01:20 -07002432 TX_TYPE tx_start = DCT_DCT;
2433 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002434#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002435 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2436 // performed in av1_search_txk_type()
2437 tx_end = DCT_DCT + 1;
2438#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002439 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002440 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002441 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Angie Chianga4fa1902017-04-05 15:26:09 -07002442 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
2443 RD_STATS this_rd_stats;
2444 int ext_tx_set =
2445 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
2446 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2447 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2448 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
2449 rect_tx_size);
2450 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002451#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002452 memcpy(best_txk_type, mbmi->txk_type,
2453 sizeof(best_txk_type[0]) * num_blk);
2454#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002455 best_tx_type = tx_type;
2456 best_tx_size = rect_tx_size;
2457 best_rd = rd;
2458 *rd_stats = this_rd_stats;
2459 }
2460 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002461#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002462 const int is_inter = is_inter_block(mbmi);
2463 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002464#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002465 }
2466 }
Yue Chen56e226e2017-05-02 16:21:40 -07002467
2468#if CONFIG_RECT_TX_EXT
2469 // test 1:4/4:1 tx
2470 int evaluate_quarter_tx = 0;
2471 if (is_quarter_tx_allowed(xd, mbmi, is_inter)) {
2472 if (tx_select) {
2473 evaluate_quarter_tx = 1;
2474 } else {
2475 const TX_SIZE chosen_tx_size =
2476 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2477 evaluate_quarter_tx = chosen_tx_size == quarter_txsize_lookup[bs];
2478 }
2479 }
2480 if (evaluate_quarter_tx) {
2481 TX_TYPE tx_start = DCT_DCT;
2482 TX_TYPE tx_end = TX_TYPES;
2483#if CONFIG_TXK_SEL
2484 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2485 // performed in av1_search_txk_type()
2486 tx_end = DCT_DCT + 1;
2487#endif
2488 TX_TYPE tx_type;
2489 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
2490 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
2491 const TX_SIZE tx_size = quarter_txsize_lookup[bs];
2492 RD_STATS this_rd_stats;
2493 int ext_tx_set =
2494 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
2495 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2496 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2497 rd =
2498 txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, tx_size);
2499 if (rd < best_rd) {
2500#if CONFIG_TXK_SEL
2501 memcpy(best_txk_type, mbmi->txk_type,
2502 sizeof(best_txk_type[0]) * num_blk);
2503#endif
2504 best_tx_type = tx_type;
2505 best_tx_size = tx_size;
2506 best_rd = rd;
2507 *rd_stats = this_rd_stats;
2508 }
2509 }
2510#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2511 const int is_inter = is_inter_block(mbmi);
2512 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2513#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2514 }
2515 }
2516#endif // CONFIG_RECT_TX_EXT
Angie Chianga4fa1902017-04-05 15:26:09 -07002517#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2518
2519 if (tx_select) {
2520 start_tx = max_tx_size;
2521 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
2522 } else {
2523 const TX_SIZE chosen_tx_size =
2524 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2525 start_tx = chosen_tx_size;
2526 end_tx = chosen_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527 }
2528
Angie Chianga4fa1902017-04-05 15:26:09 -07002529 last_rd = INT64_MAX;
2530 for (n = start_tx; n >= end_tx; --n) {
Sarah Parker36661922017-04-13 14:26:49 -07002531#if CONFIG_EXT_TX && CONFIG_RECT_TX
2532 if (is_rect_tx(n)) break;
2533#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002534 TX_TYPE tx_start = DCT_DCT;
2535 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002536#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002537 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2538 // performed in av1_search_txk_type()
2539 tx_end = DCT_DCT + 1;
2540#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002541 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002542 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002543 RD_STATS this_rd_stats;
2544 if (skip_txfm_search(cpi, x, bs, tx_type, n)) continue;
2545 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
2546#if CONFIG_PVQ
2547 od_encode_rollback(&x->daala_enc, &buf);
2548#endif // CONFIG_PVQ
2549 // Early termination in transform size search.
2550 if (cpi->sf.tx_size_search_breakout &&
2551 (rd == INT64_MAX ||
2552 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
2553 (n < (int)max_tx_size && rd > last_rd)))
2554 break;
2555
2556 last_rd = rd;
2557 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002558#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002559 memcpy(best_txk_type, mbmi->txk_type,
2560 sizeof(best_txk_type[0]) * num_blk);
2561#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002562 best_tx_type = tx_type;
2563 best_tx_size = n;
2564 best_rd = rd;
2565 *rd_stats = this_rd_stats;
2566 }
2567#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2568 const int is_inter = is_inter_block(mbmi);
2569 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2570#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2571 }
2572 }
2573 mbmi->tx_size = best_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002574 mbmi->tx_type = best_tx_type;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002575#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002576 memcpy(mbmi->txk_type, best_txk_type, sizeof(best_txk_type[0]) * num_blk);
2577#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578
Jingning Hane67b38a2016-11-04 10:30:00 -07002579#if CONFIG_VAR_TX
2580 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002581#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002582
Yaowu Xuc27fc142016-08-22 16:08:15 -07002583#if !CONFIG_EXT_TX
2584 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002585#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002586#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002587 if (best_rd != INT64_MAX) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002588 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx_size);
Yushin Cho05f540a2016-11-08 22:12:51 -08002589 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002590#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002591}
2592
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002593static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2594 RD_STATS *rd_stats, BLOCK_SIZE bs,
2595 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002596 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002597 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002598
2599 assert(bs == xd->mi[0]->mbmi.sb_type);
2600
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002601 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002602 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002604 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002605 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002606 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002607 }
2608}
2609
2610static int conditional_skipintra(PREDICTION_MODE mode,
2611 PREDICTION_MODE best_intra_mode) {
2612 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2613 best_intra_mode != D135_PRED)
2614 return 1;
2615 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2616 best_intra_mode != D45_PRED)
2617 return 1;
2618 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2619 best_intra_mode != D45_PRED)
2620 return 1;
2621 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2622 best_intra_mode != D135_PRED)
2623 return 1;
2624 return 0;
2625}
2626
hui su308a6392017-01-12 14:49:57 -08002627// Model based RD estimation for luma intra blocks.
2628static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002629 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002630 MACROBLOCKD *const xd = &x->e_mbd;
2631 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002632 assert(!is_inter_block(mbmi));
hui su308a6392017-01-12 14:49:57 -08002633 RD_STATS this_rd_stats;
2634 int row, col;
2635 int64_t temp_sse, this_rd;
2636 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2637 const int stepr = tx_size_high_unit[tx_size];
2638 const int stepc = tx_size_wide_unit[tx_size];
2639 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2640 const int max_blocks_high = max_block_high(xd, bsize, 0);
2641 mbmi->tx_size = tx_size;
2642 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002643 const int step = stepr * stepc;
2644 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002645 for (row = 0; row < max_blocks_high; row += stepr) {
2646 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002647#if CONFIG_CFL
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002648#if CONFIG_EC_ADAPT
2649 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
2650#else
Luc Trudeau64ed2ce2017-05-12 12:01:24 -04002651 FRAME_CONTEXT *const ec_ctx = cpi->common.fc;
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002652#endif // CONFIG_EC_ADAPT
2653
2654 av1_predict_intra_block_encoder_facade(x, ec_ctx, 0, block, col, row,
Luc Trudeau3dc55e02017-06-22 14:03:47 -04002655 tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002656#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002657 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002658#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002659 block += step;
hui su308a6392017-01-12 14:49:57 -08002660 }
2661 }
2662 // RD estimation.
2663 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2664 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002665#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07002666 if (av1_is_directional_mode(mbmi->mode, bsize) &&
2667 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002668 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2669 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002670 }
2671#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002672#if CONFIG_FILTER_INTRA
2673 if (mbmi->mode == DC_PRED) {
2674 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2675 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2676 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2677 mode_cost += (av1_cost_bit(prob, 1) +
2678 write_uniform_cost(FILTER_INTRA_MODES, mode));
2679 } else {
2680 mode_cost += av1_cost_bit(prob, 0);
2681 }
2682 }
2683#endif // CONFIG_FILTER_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07002684 this_rd =
2685 RDCOST(x->rdmult, this_rd_stats.rate + mode_cost, this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002686 return this_rd;
2687}
2688
Urvang Joshib100db72016-10-12 16:28:56 -07002689#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002690// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2691// new_height'. Extra rows and columns are filled in by copying last valid
2692// row/column.
2693static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2694 int orig_height, int new_width,
2695 int new_height) {
2696 int j;
2697 assert(new_width >= orig_width);
2698 assert(new_height >= orig_height);
2699 if (new_width == orig_width && new_height == orig_height) return;
2700
2701 for (j = orig_height - 1; j >= 0; --j) {
2702 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2703 // Copy last column to extra columns.
2704 memset(color_map + j * new_width + orig_width,
2705 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2706 }
2707 // Copy last row to extra rows.
2708 for (j = orig_height; j < new_height; ++j) {
2709 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2710 new_width);
2711 }
2712}
2713
hui su33567b22017-04-30 16:40:19 -07002714#if CONFIG_PALETTE_DELTA_ENCODING
2715// Bias toward using colors in the cache.
2716// TODO(huisu): Try other schemes to improve compression.
2717static void optimize_palette_colors(uint16_t *color_cache, int n_cache,
2718 int n_colors, int stride,
2719 float *centroids) {
2720 if (n_cache <= 0) return;
2721 for (int i = 0; i < n_colors * stride; i += stride) {
2722 float min_diff = fabsf(centroids[i] - color_cache[0]);
2723 int idx = 0;
2724 for (int j = 1; j < n_cache; ++j) {
2725 float this_diff = fabsf(centroids[i] - color_cache[j]);
2726 if (this_diff < min_diff) {
2727 min_diff = this_diff;
2728 idx = j;
2729 }
2730 }
2731 if (min_diff < 1.5) centroids[i] = color_cache[idx];
2732 }
2733}
2734#endif // CONFIG_PALETTE_DELTA_ENCODING
2735
hui sude0c70a2017-01-09 17:12:17 -08002736static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2737 BLOCK_SIZE bsize, int palette_ctx,
2738 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2739 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002740 int64_t *best_rd, int64_t *best_model_rd,
2741 int *rate, int *rate_tokenonly,
2742 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002743 int rate_overhead = 0;
2744 MACROBLOCKD *const xd = &x->e_mbd;
2745 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002746 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002747 assert(!is_inter_block(mbmi));
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002748 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002749 const int src_stride = x->plane[0].src.stride;
2750 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002751 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002752 int block_width, block_height, rows, cols;
2753 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2754 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002755
2756 assert(cpi->common.allow_screen_content_tools);
2757
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002758#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002759 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002760 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2761 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002763#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002764 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002765#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002766 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002767#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002768
2769 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002770 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002771 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002772 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002773 float *const data = x->palette_buffer->kmeans_data_buf;
2774 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002775 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002776 RD_STATS tokenonly_rd_stats;
2777 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002778 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002779#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002780 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2781 if (cpi->common.use_highbitdepth)
2782 lb = ub = src16[0];
2783 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002784#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002785 lb = ub = src[0];
2786
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002787#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002788 if (cpi->common.use_highbitdepth) {
2789 for (r = 0; r < rows; ++r) {
2790 for (c = 0; c < cols; ++c) {
2791 val = src16[r * src_stride + c];
2792 data[r * cols + c] = val;
2793 if (val < lb)
2794 lb = val;
2795 else if (val > ub)
2796 ub = val;
2797 }
2798 }
2799 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002800#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002801 for (r = 0; r < rows; ++r) {
2802 for (c = 0; c < cols; ++c) {
2803 val = src[r * src_stride + c];
2804 data[r * cols + c] = val;
2805 if (val < lb)
2806 lb = val;
2807 else if (val > ub)
2808 ub = val;
2809 }
2810 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002811#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002812 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002813#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002814
2815 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002816#if CONFIG_FILTER_INTRA
2817 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2818#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002819
2820 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2821
hui su33567b22017-04-30 16:40:19 -07002822#if CONFIG_PALETTE_DELTA_ENCODING
2823 const MODE_INFO *above_mi = xd->above_mi;
2824 const MODE_INFO *left_mi = xd->left_mi;
2825 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
2826 const int n_cache =
2827 av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
2828#endif // CONFIG_PALETTE_DELTA_ENCODING
2829
Yaowu Xuc27fc142016-08-22 16:08:15 -07002830 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2831 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002832 if (colors == PALETTE_MIN_SIZE) {
2833 // Special case: These colors automatically become the centroids.
2834 assert(colors == n);
2835 assert(colors == 2);
2836 centroids[0] = lb;
2837 centroids[1] = ub;
2838 k = 2;
2839 } else {
2840 for (i = 0; i < n; ++i) {
2841 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2842 }
2843 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
hui su33567b22017-04-30 16:40:19 -07002844#if CONFIG_PALETTE_DELTA_ENCODING
2845 optimize_palette_colors(color_cache, n_cache, n, 1, centroids);
2846#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi773e3542017-05-05 18:09:42 -07002847 k = av1_remove_duplicates(centroids, n);
2848 if (k < PALETTE_MIN_SIZE) {
2849 // Too few unique colors to create a palette. And DC_PRED will work
2850 // well for that case anyway. So skip.
2851 continue;
2852 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002853 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002854
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002855#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002856 if (cpi->common.use_highbitdepth)
2857 for (i = 0; i < k; ++i)
2858 pmi->palette_colors[i] =
2859 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2860 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002861#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002862 for (i = 0; i < k; ++i)
2863 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2864 pmi->palette_size[0] = k;
2865
Yaowu Xuf883b422016-08-30 14:01:10 -07002866 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002867 extend_palette_color_map(color_map, cols, rows, block_width,
2868 block_height);
hui su78c611a2017-01-13 17:06:04 -08002869 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002870 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002871 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002872 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002873 av1_cost_bit(
2874 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002875 1);
hui su33567b22017-04-30 16:40:19 -07002876 palette_mode_cost += av1_palette_color_cost_y(pmi,
2877#if CONFIG_PALETTE_DELTA_ENCODING
2878 color_cache, n_cache,
2879#endif // CONFIG_PALETTE_DELTA_ENCODING
2880 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002881 for (i = 0; i < rows; ++i) {
2882 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002883 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002884 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002885 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002886 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002887 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2888 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002889 }
2890 }
hui su78c611a2017-01-13 17:06:04 -08002891 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2892 if (*best_model_rd != INT64_MAX &&
2893 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2894 continue;
2895 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2896 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2897 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2898 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Urvang Joshi70006e42017-06-14 16:08:55 -07002899 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002900 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002901 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002902 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002903 if (this_rd < *best_rd) {
2904 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002905 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002906 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002907 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002908 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002909 if (rate) *rate = this_rate;
2910 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2911 if (distortion) *distortion = tokenonly_rd_stats.dist;
2912 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002913 }
2914 }
2915 }
hui sude0c70a2017-01-09 17:12:17 -08002916
2917 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2918 memcpy(color_map, best_palette_color_map,
2919 rows * cols * sizeof(best_palette_color_map[0]));
2920 }
2921 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002922 return rate_overhead;
2923}
Urvang Joshib100db72016-10-12 16:28:56 -07002924#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002925
Urvang Joshifeb925f2016-12-05 10:37:29 -08002926static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002927 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2928 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2929 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002930 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002931 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002932 PREDICTION_MODE mode;
2933 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi330aec82017-05-08 15:37:42 -07002934 assert(!is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002935 int64_t best_rd = rd_thresh;
2936 struct macroblock_plane *p = &x->plane[0];
2937 struct macroblockd_plane *pd = &xd->plane[0];
2938 const int src_stride = p->src.stride;
2939 const int dst_stride = pd->dst.stride;
2940 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002941 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002942#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08002943 // TODO(jingning): This is a temporal change. The whole function should be
2944 // out when cb4x4 is enabled.
2945 ENTROPY_CONTEXT ta[4], tempa[4];
2946 ENTROPY_CONTEXT tl[4], templ[4];
2947#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002948 ENTROPY_CONTEXT ta[2], tempa[2];
2949 ENTROPY_CONTEXT tl[2], templ[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002950#endif // CONFIG_CHROMA_2X2
Urvang Joshifeb925f2016-12-05 10:37:29 -08002951
2952 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2953 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2954 const int tx_width_unit = tx_size_wide_unit[tx_size];
2955 const int tx_height_unit = tx_size_high_unit[tx_size];
2956 const int pred_block_width = block_size_wide[bsize];
2957 const int pred_block_height = block_size_high[bsize];
2958 const int tx_width = tx_size_wide[tx_size];
2959 const int tx_height = tx_size_high[tx_size];
2960 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2961 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002962 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002963 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002964 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002965#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002966 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002967#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002968 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2969#if CONFIG_EXT_TX && CONFIG_RECT_TX
2970 const int sub_bsize = bsize;
2971#else
2972 const int sub_bsize = BLOCK_4X4;
2973#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002974
Yushin Cho77bba8d2016-11-04 16:36:56 -07002975#if CONFIG_PVQ
2976 od_rollback_buffer pre_buf, post_buf;
2977 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2978 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002979#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002980
Urvang Joshifeb925f2016-12-05 10:37:29 -08002981 assert(bsize < BLOCK_8X8);
2982 assert(tx_width < 8 || tx_height < 8);
2983#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002984 if (is_lossless)
2985 assert(tx_width == 4 && tx_height == 4);
2986 else
2987 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002988#else
2989 assert(tx_width == 4 && tx_height == 4);
2990#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2991
2992 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2993 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2994
2995 xd->mi[0]->mbmi.tx_size = tx_size;
2996
Urvang Joshib100db72016-10-12 16:28:56 -07002997#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002998 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002999#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003000
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003001#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003002 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08003003#if CONFIG_PVQ
3004 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3005#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003006 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3007 int64_t this_rd;
3008 int ratey = 0;
3009 int64_t distortion = 0;
3010 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003011 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003012
Urvang Joshifeb925f2016-12-05 10:37:29 -08003013 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
3014 (1 << mode)))
3015 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016
3017 // Only do the oblique modes if the best so far is
3018 // one of the neighboring directional modes
3019 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3020 if (conditional_skipintra(mode, *best_mode)) continue;
3021 }
3022
Urvang Joshifeb925f2016-12-05 10:37:29 -08003023 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
3024 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003025
Urvang Joshifeb925f2016-12-05 10:37:29 -08003026 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
3027 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
3028 const int block_raster_idx = (row + idy) * 2 + (col + idx);
3029 const int block =
3030 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003031 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
3032 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08003033#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003034 int16_t *const src_diff = av1_raster_block_offset_int16(
3035 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003036#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003037 int skip;
3038 assert(block < 4);
3039 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3040 idx == 0 && idy == 0));
3041 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3042 block == 0 || block == 2));
3043 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00003044 av1_predict_intra_block(
3045 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
3046 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003047#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003048 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
3049 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003050#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003051 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07003052 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003053 const SCAN_ORDER *scan_order =
3054 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003056 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003057#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07003058 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003059 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07003060 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07003061 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003062 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003063 skip = (p->eobs[block] == 0);
3064 can_skip &= skip;
3065 tempa[idx] = !skip;
3066 templ[idy] = !skip;
3067#if CONFIG_EXT_TX
3068 if (tx_size == TX_8X4) {
3069 tempa[idx + 1] = tempa[idx];
3070 } else if (tx_size == TX_4X8) {
3071 templ[idy + 1] = templ[idy];
3072 }
3073#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08003074#else
3075 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003076
Thomas Daede6ff6af62017-02-03 16:29:24 -08003077 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3078 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3079
3080 ratey += x->rate;
3081 skip = x->pvq_skip[0];
3082 tempa[idx] = !skip;
3083 templ[idy] = !skip;
3084 can_skip &= skip;
3085#endif
Urvang Joshi70006e42017-06-14 16:08:55 -07003086 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003087 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08003088#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003089 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08003090#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07003091 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3092 DCT_DCT, tx_size, dst, dst_stride,
3093 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003094 } else {
3095 int64_t dist;
3096 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07003097 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003098 const SCAN_ORDER *scan_order =
3099 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003100 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003101 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003102#if !CONFIG_PVQ
Sarah Parker345366a2017-06-15 12:13:01 -07003103#if DISABLE_TRELLISQ_SEARCH
3104 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3105 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3106#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003107 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003108 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07003109 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
3110 templ + idy);
Sarah Parker345366a2017-06-15 12:13:01 -07003111#endif // DISABLE_TRELLISQ_SEARCH
Angie Chiang05917872017-04-15 12:28:56 -07003112 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07003113 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003114 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003115 skip = (p->eobs[block] == 0);
3116 can_skip &= skip;
3117 tempa[idx] = !skip;
3118 templ[idy] = !skip;
3119#if CONFIG_EXT_TX
3120 if (tx_size == TX_8X4) {
3121 tempa[idx + 1] = tempa[idx];
3122 } else if (tx_size == TX_4X8) {
3123 templ[idy + 1] = templ[idy];
3124 }
3125#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08003126#else
3127 (void)scan_order;
3128
3129 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3130 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
3131 ratey += x->rate;
3132 skip = x->pvq_skip[0];
3133 tempa[idx] = !skip;
3134 templ[idy] = !skip;
3135 can_skip &= skip;
3136#endif
3137#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003138 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08003139#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07003140 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3141 tx_type, tx_size, dst, dst_stride,
3142 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003143 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003144 dist = (int64_t)tmp << 4;
3145 distortion += dist;
Urvang Joshi70006e42017-06-14 16:08:55 -07003146 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003147 goto next_highbd;
3148 }
3149 }
3150 }
3151
3152 rate += ratey;
Urvang Joshi70006e42017-06-14 16:08:55 -07003153 this_rd = RDCOST(x->rdmult, rate, distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003154
3155 if (this_rd < best_rd) {
3156 *bestrate = rate;
3157 *bestratey = ratey;
3158 *bestdistortion = distortion;
3159 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003160 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003162 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3163 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08003164#if CONFIG_PVQ
3165 od_encode_checkpoint(&x->daala_enc, &post_buf);
3166#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003167 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003168 memcpy(best_dst16 + idy * 8,
3169 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08003170 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003171 }
3172 }
3173 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08003174#if CONFIG_PVQ
3175 od_encode_rollback(&x->daala_enc, &pre_buf);
3176#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 }
3178
3179 if (best_rd >= rd_thresh) return best_rd;
3180
Thomas Daede6ff6af62017-02-03 16:29:24 -08003181#if CONFIG_PVQ
3182 od_encode_rollback(&x->daala_enc, &post_buf);
3183#endif
3184
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003185 if (y_skip) *y_skip &= best_can_skip;
3186
Urvang Joshifeb925f2016-12-05 10:37:29 -08003187 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003188 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08003189 best_dst16 + idy * 8,
3190 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003191 }
3192
3193 return best_rd;
3194 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003195#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003196
Yushin Cho77bba8d2016-11-04 16:36:56 -07003197#if CONFIG_PVQ
3198 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003199#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003200
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3202 int64_t this_rd;
3203 int ratey = 0;
3204 int64_t distortion = 0;
3205 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003206 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003207
Urvang Joshifeb925f2016-12-05 10:37:29 -08003208 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
3209 (1 << mode))) {
3210 continue;
3211 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003212
3213 // Only do the oblique modes if the best so far is
3214 // one of the neighboring directional modes
3215 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3216 if (conditional_skipintra(mode, *best_mode)) continue;
3217 }
3218
Urvang Joshifeb925f2016-12-05 10:37:29 -08003219 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
3220 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221
Urvang Joshifeb925f2016-12-05 10:37:29 -08003222 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
3223 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
3224 const int block_raster_idx = (row + idy) * 2 + (col + idx);
3225 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003226 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
3227 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07003228#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003229 int16_t *const src_diff = av1_raster_block_offset_int16(
3230 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08003231#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003232 int skip;
3233 assert(block < 4);
3234 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3235 idx == 0 && idy == 0));
3236 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3237 block == 0 || block == 2));
3238 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00003239 av1_predict_intra_block(xd, pd->width, pd->height,
3240 txsize_to_bsize[tx_size], mode, dst, dst_stride,
3241 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08003242#if CONFIG_CB4X4
3243 2 * (col + idx), 2 * (row + idy),
3244#else
3245 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08003246#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08003247 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003248#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003249 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
3250 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08003251#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003252
Urvang Joshi14731732017-04-27 18:40:49 -07003253 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003254 const SCAN_ORDER *scan_order =
3255 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Urvang Joshi14731732017-04-27 18:40:49 -07003256 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08003257#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003258 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08003259#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08003260#if !CONFIG_PVQ
Sarah Parker345366a2017-06-15 12:13:01 -07003261#if DISABLE_TRELLISQ_SEARCH
3262 av1_xform_quant(cm, x, 0, block,
3263#if CONFIG_CB4X4
3264 2 * (row + idy), 2 * (col + idx),
3265#else
3266 row + idy, col + idx,
3267#endif // CONFIG_CB4X4
3268 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3269#else
Urvang Joshi14731732017-04-27 18:40:49 -07003270 const AV1_XFORM_QUANT xform_quant =
3271 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
3272 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08003273#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003274 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08003275#else
Urvang Joshi14731732017-04-27 18:40:49 -07003276 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003277#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003278 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08003279
Angie Chiang3511c372017-05-31 12:47:07 -07003280 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
3281 templ + idy);
Sarah Parker345366a2017-06-15 12:13:01 -07003282#endif // DISABLE_TRELLISQ_SEARCH
Urvang Joshi14731732017-04-27 18:40:49 -07003283 ratey +=
3284 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
3285 templ + idy, cpi->sf.use_fast_coef_costing);
3286 skip = (p->eobs[block] == 0);
3287 can_skip &= skip;
3288 tempa[idx] = !skip;
3289 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003290#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07003291 if (tx_size == TX_8X4) {
3292 tempa[idx + 1] = tempa[idx];
3293 } else if (tx_size == TX_4X8) {
3294 templ[idy + 1] = templ[idy];
3295 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003296#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07003297#else
Urvang Joshi14731732017-04-27 18:40:49 -07003298 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08003299
Urvang Joshi14731732017-04-27 18:40:49 -07003300 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08003301#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003302 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08003303#else
Urvang Joshi14731732017-04-27 18:40:49 -07003304 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003305#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003306 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
3307
3308 ratey += x->rate;
3309 skip = x->pvq_skip[0];
3310 tempa[idx] = !skip;
3311 templ[idy] = !skip;
3312 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08003313#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07003314
3315 if (!is_lossless) { // To use the pixel domain distortion, we need to
3316 // calculate inverse txfm *before* calculating RD
3317 // cost. Compared to calculating the distortion in
3318 // the frequency domain, the overhead of encoding
3319 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08003320#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003321 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08003322#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003323 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3324 tx_type, tx_size, dst, dst_stride,
3325 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07003326 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003327 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07003328 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003329 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07003330 }
3331
Urvang Joshi70006e42017-06-14 16:08:55 -07003332 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd) goto next;
Urvang Joshi14731732017-04-27 18:40:49 -07003333
3334 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
3335#if CONFIG_PVQ
3336 if (!skip)
3337#endif // CONFIG_PVQ
3338 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3339 DCT_DCT, tx_size, dst, dst_stride,
3340 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003341 }
3342 }
3343 }
3344
3345 rate += ratey;
Urvang Joshi70006e42017-06-14 16:08:55 -07003346 this_rd = RDCOST(x->rdmult, rate, distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003347
3348 if (this_rd < best_rd) {
3349 *bestrate = rate;
3350 *bestratey = ratey;
3351 *bestdistortion = distortion;
3352 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003353 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003354 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003355 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3356 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003357#if CONFIG_PVQ
3358 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003359#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003360 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003362 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003363 }
3364 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003365#if CONFIG_PVQ
3366 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003367#endif // CONFIG_PVQ
3368 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003369
3370 if (best_rd >= rd_thresh) return best_rd;
3371
Yushin Cho77bba8d2016-11-04 16:36:56 -07003372#if CONFIG_PVQ
3373 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003374#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003375
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003376 if (y_skip) *y_skip &= best_can_skip;
3377
Urvang Joshifeb925f2016-12-05 10:37:29 -08003378 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003379 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003380 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003381
3382 return best_rd;
3383}
3384
Urvang Joshi52648442016-10-13 17:27:51 -07003385static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3386 MACROBLOCK *mb, int *rate,
3387 int *rate_y, int64_t *distortion,
3388 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003389 const MACROBLOCKD *const xd = &mb->e_mbd;
3390 MODE_INFO *const mic = xd->mi[0];
3391 const MODE_INFO *above_mi = xd->above_mi;
3392 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003393 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003394 assert(!is_inter_block(mbmi));
Urvang Joshifeb925f2016-12-05 10:37:29 -08003395 const BLOCK_SIZE bsize = mbmi->sb_type;
3396 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3397 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003398 int idx, idy;
3399 int cost = 0;
3400 int64_t total_distortion = 0;
3401 int tot_rate_y = 0;
3402 int64_t total_rd = 0;
3403 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003404 const int is_lossless = xd->lossless[mbmi->segment_id];
3405#if CONFIG_EXT_TX && CONFIG_RECT_TX
3406 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3407#else
3408 const TX_SIZE tx_size = TX_4X4;
3409#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003410
3411#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003412#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003413 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003414#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003415#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003416#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003417 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003418#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003419
3420 // TODO(any): Add search of the tx_type to improve rd performance at the
3421 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003422 mbmi->tx_type = DCT_DCT;
3423 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003424
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003425 if (y_skip) *y_skip = 1;
3426
Urvang Joshifeb925f2016-12-05 10:37:29 -08003427 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3428 // 8x8 coding block.
3429 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3430 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 PREDICTION_MODE best_mode = DC_PRED;
3432 int r = INT_MAX, ry = INT_MAX;
3433 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003434 int j;
3435 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003436 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003437 const PREDICTION_MODE A =
3438 av1_above_block_mode(mic, above_mi, pred_block_idx);
3439 const PREDICTION_MODE L =
3440 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003441
3442 bmode_costs = cpi->y_mode_costs[A][L];
3443 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003444 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003445 cpi, mb, idy, idx, &best_mode, bmode_costs,
3446 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003447 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003448#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003449 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003450#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003451 total_rd += this_rd;
3452 cost += r;
3453 total_distortion += d;
3454 tot_rate_y += ry;
3455
Urvang Joshifeb925f2016-12-05 10:37:29 -08003456 mic->bmi[pred_block_idx].as_mode = best_mode;
3457 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3458 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3459 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3460 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003461
3462 if (total_rd >= best_rd) return INT64_MAX;
3463 }
3464 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003465 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003466
Yushin Cho7a428ba2017-01-12 16:28:49 -08003467#if CONFIG_DAALA_DIST
3468 {
3469 const struct macroblock_plane *p = &mb->plane[0];
3470 const struct macroblockd_plane *pd = &xd->plane[0];
3471 const int src_stride = p->src.stride;
3472 const int dst_stride = pd->dst.stride;
3473 uint8_t *src = p->src.buf;
3474 uint8_t *dst = pd->dst.buf;
3475 int use_activity_masking = 0;
3476 int qm = OD_HVS_QM;
3477
3478#if CONFIG_PVQ
3479 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003480#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003481 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho8ab875d2017-06-23 14:47:21 -07003482 total_distortion =
3483 av1_daala_dist(xd, src, src_stride, dst, dst_stride, 8, 8, 8, 8, qm,
3484 use_activity_masking, mb->qindex)
3485 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08003486 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003487#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003488 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003489 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003490 int rate_tx_type = 0;
3491#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003492 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3493 1) {
3494 const int eset =
3495 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003496 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3497 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003498 }
3499#else
clang-format67948d32016-09-07 22:40:40 -07003500 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003501 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3502 [intra_mode_to_tx_type_context[mbmi->mode]]
3503 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003504#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003505 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003506 cost += rate_tx_type;
3507 tot_rate_y += rate_tx_type;
3508 }
3509
3510 *rate = cost;
3511 *rate_y = tot_rate_y;
3512 *distortion = total_distortion;
3513
Urvang Joshi70006e42017-06-14 16:08:55 -07003514 return RDCOST(mb->rdmult, cost, total_distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515}
3516
hui su5db97432016-10-14 16:10:14 -07003517#if CONFIG_FILTER_INTRA
3518// Return 1 if an filter intra mode is selected; return 0 otherwise.
3519static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3520 int *rate, int *rate_tokenonly,
3521 int64_t *distortion, int *skippable,
3522 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003523 int64_t *best_rd, int64_t *best_model_rd,
3524 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003525 MACROBLOCKD *const xd = &x->e_mbd;
3526 MODE_INFO *const mic = xd->mi[0];
3527 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003528 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003529 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003530 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003531 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003532 TX_TYPE best_tx_type;
3533
hui su5db97432016-10-14 16:10:14 -07003534 av1_zero(filter_intra_mode_info);
3535 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003536 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003537#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003538 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003539#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003540
3541 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003542 int this_rate;
3543 int64_t this_rd, this_model_rd;
3544 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003546 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003547 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3548 if (*best_model_rd != INT64_MAX &&
3549 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3550 continue;
3551 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003552 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3553 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003554 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003555 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Urvang Joshi70006e42017-06-14 16:08:55 -07003557 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003558
3559 if (this_rd < *best_rd) {
3560 *best_rd = this_rd;
3561 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003562 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003563 best_tx_type = mic->mbmi.tx_type;
3564 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003565 *rate_tokenonly = tokenonly_rd_stats.rate;
3566 *distortion = tokenonly_rd_stats.dist;
3567 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003568 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569 }
3570 }
3571
hui su5db97432016-10-14 16:10:14 -07003572 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003573 mbmi->mode = DC_PRED;
3574 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003575 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3576 filter_intra_mode_info.use_filter_intra_mode[0];
3577 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3578 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003579 mbmi->tx_type = best_tx_type;
3580 return 1;
3581 } else {
3582 return 0;
3583 }
3584}
hui su5db97432016-10-14 16:10:14 -07003585#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003586
hui su5db97432016-10-14 16:10:14 -07003587#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003588// Run RD calculation with given luma intra prediction angle., and return
3589// the RD cost. Update the best mode info. if the RD cost is the best so far.
3590static int64_t calc_rd_given_intra_angle(
3591 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3592 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3593 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3594 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003595#if CONFIG_INTRA_INTERP
3596 INTRA_FILTER *best_filter,
3597#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003598 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003599 int this_rate;
3600 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003601 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003602 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003603 assert(!is_inter_block(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003604
hui su45dc5972016-12-08 17:42:50 -08003605 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003606 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3607 if (*best_model_rd != INT64_MAX &&
3608 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3609 return INT64_MAX;
3610 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003611 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3612 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3613
3614 this_rate = tokenonly_rd_stats.rate + mode_cost +
3615 write_uniform_cost(2 * max_angle_delta + 1,
3616 mbmi->angle_delta[0] + max_angle_delta);
Urvang Joshi70006e42017-06-14 16:08:55 -07003617 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618
3619 if (this_rd < *best_rd) {
3620 *best_rd = this_rd;
3621 *best_angle_delta = mbmi->angle_delta[0];
3622 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003623#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003624 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003625#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003626 *best_tx_type = mbmi->tx_type;
3627 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003628 rd_stats->rate = tokenonly_rd_stats.rate;
3629 rd_stats->dist = tokenonly_rd_stats.dist;
3630 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003631 }
hui su45dc5972016-12-08 17:42:50 -08003632 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003633}
3634
hui su45dc5972016-12-08 17:42:50 -08003635// With given luma directional intra prediction mode, pick the best angle delta
3636// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003637static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003638 int *rate, RD_STATS *rd_stats,
3639 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003640 int64_t best_rd,
3641 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003642 MACROBLOCKD *const xd = &x->e_mbd;
3643 MODE_INFO *const mic = xd->mi[0];
3644 MB_MODE_INFO *mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003645 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08003646 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003647 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003648#if CONFIG_INTRA_INTERP
3649 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003650 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003651 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003652#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003653 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003654 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3655 TX_TYPE best_tx_type = mbmi->tx_type;
3656
hui su0a6731f2017-04-26 15:23:47 -07003657 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003658
hui su0a6731f2017-04-26 15:23:47 -07003659 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003660#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003661 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3662 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3663 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003664#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003665 for (i = 0; i < 2; ++i) {
3666 best_rd_in = (best_rd == INT64_MAX)
3667 ? INT64_MAX
3668 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3669 this_rd = calc_rd_given_intra_angle(
3670 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003671#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003672 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003673#else
hui su45dc5972016-12-08 17:42:50 -08003674 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003675#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003676 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003677 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003678#if CONFIG_INTRA_INTERP
3679 &best_filter,
3680#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003681 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003682 rd_cost[2 * angle_delta + i] = this_rd;
3683 if (first_try && this_rd == INT64_MAX) return best_rd;
3684 first_try = 0;
3685 if (angle_delta == 0) {
3686 rd_cost[1] = this_rd;
3687 break;
3688 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003689 }
hui su45dc5972016-12-08 17:42:50 -08003690#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003691 }
hui su45dc5972016-12-08 17:42:50 -08003692#endif // CONFIG_INTRA_INTERP
3693 }
3694
3695 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003696 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003697 int64_t rd_thresh;
3698#if CONFIG_INTRA_INTERP
3699 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3700 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3701 mic->mbmi.intra_filter = filter;
3702#endif // CONFIG_INTRA_INTERP
3703 for (i = 0; i < 2; ++i) {
3704 int skip_search = 0;
3705 rd_thresh = best_rd + (best_rd >> 5);
3706 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3707 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3708 skip_search = 1;
3709 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003710 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003711 cpi, x, bsize,
3712#if CONFIG_INTRA_INTERP
3713 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3714#else
3715 mode_cost,
3716#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003717 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003718 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3719#if CONFIG_INTRA_INTERP
3720 &best_filter,
3721#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003722 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003723 }
3724 }
3725#if CONFIG_INTRA_INTERP
3726 }
3727#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003728 }
3729
hui sueda3d762016-12-06 16:58:23 -08003730#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003731 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003732 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003733 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3735 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003736 this_rd = calc_rd_given_intra_angle(
3737 cpi, x, bsize,
3738 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003739 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003740 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003741 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003742 }
3743 }
3744 }
hui sueda3d762016-12-06 16:58:23 -08003745#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003746
3747 mbmi->tx_size = best_tx_size;
3748 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003749#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003750 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003751#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752 mbmi->tx_type = best_tx_type;
3753 return best_rd;
3754}
3755
3756// Indices are sign, integer, and fractional part of the gradient value
3757static const uint8_t gradient_to_angle_bin[2][7][16] = {
3758 {
3759 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3760 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3761 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3762 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3763 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3764 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3765 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3766 },
3767 {
3768 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3769 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3770 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3771 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3772 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3773 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3774 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3775 },
3776};
3777
Yue Chen56e226e2017-05-02 16:21:40 -07003778/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003779static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3780 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003781#if CONFIG_ALT_INTRA
3782 0,
3783#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003784};
Yue Chen56e226e2017-05-02 16:21:40 -07003785/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003786
3787static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003788 int cols, BLOCK_SIZE bsize,
3789 uint8_t *directional_mode_skip_mask) {
3790 memset(directional_mode_skip_mask, 0,
3791 INTRA_MODES * sizeof(*directional_mode_skip_mask));
Joe Young830d4ce2017-05-30 17:48:13 -07003792 // Check if angle_delta is used
3793 if (!av1_use_angle_delta(bsize)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003794 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003795 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3796 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003797 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003798 for (r = 1; r < rows; ++r) {
3799 for (c = 1; c < cols; ++c) {
3800 dx = src[c] - src[c - 1];
3801 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003802 int index;
3803 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804 if (dy == 0) {
3805 index = 2;
3806 } else {
hui su9cc10652017-04-27 17:22:07 -07003807 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003808 dx = abs(dx);
3809 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003810 const int remd = (dx % dy) * 16 / dy;
3811 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003812 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003813 }
3814 hist[index] += temp;
3815 }
3816 src += src_stride;
3817 }
3818
hui su9cc10652017-04-27 17:22:07 -07003819 int i;
3820 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003821 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3822 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003823 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003824 const uint8_t angle_bin = mode_to_angle_bin[i];
3825 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003826 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003827 if (angle_bin > 0) {
3828 score += hist[angle_bin - 1];
3829 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003830 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003831 if (angle_bin < DIRECTIONAL_MODES - 1) {
3832 score += hist[angle_bin + 1];
3833 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003834 }
3835 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3836 directional_mode_skip_mask[i] = 1;
3837 }
3838 }
3839}
3840
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003841#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003842static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003843 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003845 memset(directional_mode_skip_mask, 0,
3846 INTRA_MODES * sizeof(*directional_mode_skip_mask));
Joe Young830d4ce2017-05-30 17:48:13 -07003847 // Check if angle_delta is used
3848 if (!av1_use_angle_delta(bsize)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003849 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003850 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003851 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3852 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003853 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003854 for (r = 1; r < rows; ++r) {
3855 for (c = 1; c < cols; ++c) {
3856 dx = src[c] - src[c - 1];
3857 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003858 int index;
3859 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003860 if (dy == 0) {
3861 index = 2;
3862 } else {
hui su9cc10652017-04-27 17:22:07 -07003863 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003864 dx = abs(dx);
3865 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003866 const int remd = (dx % dy) * 16 / dy;
3867 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003868 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003869 }
3870 hist[index] += temp;
3871 }
3872 src += src_stride;
3873 }
3874
hui su9cc10652017-04-27 17:22:07 -07003875 int i;
3876 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003877 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3878 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003879 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003880 const uint8_t angle_bin = mode_to_angle_bin[i];
3881 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003882 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003883 if (angle_bin > 0) {
3884 score += hist[angle_bin - 1];
3885 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003887 if (angle_bin < DIRECTIONAL_MODES - 1) {
3888 score += hist[angle_bin + 1];
3889 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003890 }
3891 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3892 directional_mode_skip_mask[i] = 1;
3893 }
3894 }
3895}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003896#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003897#endif // CONFIG_EXT_INTRA
3898
3899// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003900static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3901 int *rate, int *rate_tokenonly,
3902 int64_t *distortion, int *skippable,
3903 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003904 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905 MACROBLOCKD *const xd = &x->e_mbd;
3906 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003907 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003908 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08003909 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003910 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003911#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003912 const int rows = block_size_high[bsize];
3913 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003914#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003915 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003916#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003917 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919 const int src_stride = x->plane[0].src.stride;
3920 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003921#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003922#if CONFIG_FILTER_INTRA
3923 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003924 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3925#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003926 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003927#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003928 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929 uint8_t *best_palette_color_map =
3930 cpi->common.allow_screen_content_tools
3931 ? x->palette_buffer->best_palette_color_map
3932 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003933 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003934 const int try_palette =
3935 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003936#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937 const MODE_INFO *above_mi = xd->above_mi;
3938 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003939 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3940 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003941 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003942#if CONFIG_PVQ
3943 od_rollback_buffer pre_buf, post_buf;
3944
3945 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3946 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003947#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003948 bmode_costs = cpi->y_mode_costs[A][L];
3949
3950#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003951 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003952#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003953 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003954 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 directional_mode_skip_mask);
3956 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003957#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003958 angle_estimation(src, src_stride, rows, cols, bsize,
3959 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003961#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003962 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003963#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003964#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003965 pmi->palette_size[0] = 0;
3966 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003967 palette_y_mode_ctx +=
3968 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003969 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003970 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003971#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003972
3973 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3974 x->use_default_intra_tx_type = 1;
3975 else
3976 x->use_default_intra_tx_type = 0;
3977
3978 /* Y Search for intra prediction mode */
3979 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003980 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003981 int this_rate, this_rate_tokenonly, s;
3982 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003983 if (mode_idx == FINAL_MODE_SEARCH) {
3984 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003985 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986 x->use_default_intra_tx_type = 0;
3987 } else {
hui sude0c70a2017-01-09 17:12:17 -08003988 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003990#if CONFIG_PVQ
3991 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003992#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003994 mbmi->angle_delta[0] = 0;
3995#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003996 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003997 if (best_model_rd != INT64_MAX &&
3998 this_model_rd > best_model_rd + (best_model_rd >> 1))
3999 continue;
4000 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
4001#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08004002 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
4003 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Joe Young830d4ce2017-05-30 17:48:13 -07004004 if (is_directional_mode && av1_use_angle_delta(bsize)) {
hui su45dc5972016-12-08 17:42:50 -08004005 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07004006 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
4007 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004008 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08004009 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004010 }
4011#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08004012 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08004013#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08004014 this_rate_tokenonly = this_rd_stats.rate;
4015 this_distortion = this_rd_stats.dist;
4016 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004017
4018 if (this_rate_tokenonly == INT_MAX) continue;
4019
hui sude0c70a2017-01-09 17:12:17 -08004020 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004021
hui sude0c70a2017-01-09 17:12:17 -08004022 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004023 // super_block_yrd above includes the cost of the tx_size in the
4024 // tokenonly rate, but for intra blocks, tx_size is always coded
4025 // (prediction granularity), so we account for it in the full rate,
4026 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08004027 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004028 }
Urvang Joshib100db72016-10-12 16:28:56 -07004029#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07004030 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08004031 this_rate +=
4032 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
4033 [palette_y_mode_ctx],
4034 0);
hui su9bc1d8d2017-03-24 12:36:03 -07004035 }
Urvang Joshib100db72016-10-12 16:28:56 -07004036#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004037#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08004038 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07004039 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
4040#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004041#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004042 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08004043#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07004044 const int p_angle =
4045 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07004046 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004047 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08004048 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08004049#endif // CONFIG_INTRA_INTERP
Joe Young830d4ce2017-05-30 17:48:13 -07004050 if (av1_use_angle_delta(bsize)) {
4051 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4052 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
4053 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 }
4055#endif // CONFIG_EXT_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07004056 this_rd = RDCOST(x->rdmult, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07004057#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07004058 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08004059 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004060 }
hui su5db97432016-10-14 16:10:14 -07004061#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004062
4063 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08004064 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004065 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07004066#if CONFIG_FILTER_INTRA
4067 beat_best_rd = 1;
4068#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004069 *rate = this_rate;
4070 *rate_tokenonly = this_rate_tokenonly;
4071 *distortion = this_distortion;
4072 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004073#if CONFIG_PVQ
4074 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004075#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004076 }
4077 }
4078
Yushin Cho77bba8d2016-11-04 16:36:56 -07004079#if CONFIG_PVQ
4080 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004081#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004082
Urvang Joshib100db72016-10-12 16:28:56 -07004083#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07004084 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08004085 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
4086 bmode_costs[DC_PRED], &best_mbmi,
4087 best_palette_color_map, &best_rd, &best_model_rd,
4088 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08004089 }
Urvang Joshib100db72016-10-12 16:28:56 -07004090#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004091
hui su5db97432016-10-14 16:10:14 -07004092#if CONFIG_FILTER_INTRA
4093 if (beat_best_rd) {
4094 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
4095 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08004096 &best_rd, &best_model_rd,
4097 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08004098 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004099 }
4100 }
hui su5db97432016-10-14 16:10:14 -07004101#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004102
hui sude0c70a2017-01-09 17:12:17 -08004103 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004104 return best_rd;
4105}
4106
Yue Chena1e48dc2016-08-29 17:29:33 -07004107// Return value 0: early termination triggered, no valid rd cost available;
4108// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08004109static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
4110 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4111 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07004112 MACROBLOCKD *const xd = &x->e_mbd;
4113 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4114 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
4115 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07004116 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08004117 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004118
4119 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08004120
Jingning Han31b6a4f2017-02-23 11:05:53 -08004121#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004122 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07004123
4124 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
4125 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08004126#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004127
Yushin Cho77bba8d2016-11-04 16:36:56 -07004128#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07004129 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07004130 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
4131 av1_subtract_plane(x, bsize, plane);
4132 }
Fergus Simpson4063a682017-02-28 16:52:22 -08004133#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07004134
Yushin Cho09de28b2016-06-21 14:51:23 -07004135 if (is_cost_valid) {
4136 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08004137 RD_STATS pn_rd_stats;
4138 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
4139 uv_tx_size, cpi->sf.use_fast_coef_costing);
4140 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07004141 is_cost_valid = 0;
4142 break;
4143 }
Angie Chiang284d7772016-11-08 11:06:45 -08004144 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Urvang Joshi70006e42017-06-14 16:08:55 -07004145 if (RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist) > ref_best_rd &&
4146 RDCOST(x->rdmult, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07004147 is_cost_valid = 0;
4148 break;
4149 }
Yue Chena1e48dc2016-08-29 17:29:33 -07004150 }
4151 }
4152
4153 if (!is_cost_valid) {
4154 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08004155 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004156 }
4157
4158 return is_cost_valid;
4159}
4160
Yaowu Xuc27fc142016-08-22 16:08:15 -07004161#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004162void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
4163 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07004164 int plane_bsize, const ENTROPY_CONTEXT *a,
4165 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07004166 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004167 MACROBLOCKD *xd = &x->e_mbd;
4168 const struct macroblock_plane *const p = &x->plane[plane];
4169 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han243b66b2017-06-23 12:11:47 -07004170
4171#if CONFIG_TXK_SEL
4172 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
4173 tx_size, a, l, 0, rd_stats);
4174 return;
4175#endif
4176
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177 int64_t tmp;
4178 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05004179 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004181 const SCAN_ORDER *const scan_order =
Angie Chiangbd99b382017-06-20 15:11:16 -07004182 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004183 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07004184 int bh = block_size_high[txm_bsize];
4185 int bw = block_size_wide[txm_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08004187 uint8_t *src =
4188 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
4189 uint8_t *dst =
4190 &pd->dst
4191 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004192#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004193 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
4194 uint8_t *rec_buffer;
4195#else
4196 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004197#endif // CONFIG_HIGHBITDEPTH
Timothy B. Terriberryd62e2a32017-06-10 16:04:21 -07004198 const int diff_stride = block_size_wide[plane_bsize];
Jingning Han9ca05b72017-01-03 14:41:36 -08004199 const int16_t *diff =
4200 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07004201 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08004202
4203 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204
Angie Chiang77368af2017-03-23 16:22:07 -07004205 int coeff_ctx = get_entropy_context(tx_size, a, l);
4206
Sarah Parker5680a012017-06-21 09:41:25 -07004207#if DISABLE_TRELLISQ_SEARCH
4208 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
4209 coeff_ctx, AV1_XFORM_QUANT_B);
4210
4211#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004212 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004213 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004214
Angie Chiang3511c372017-05-31 12:47:07 -07004215 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Sarah Parker5680a012017-06-21 09:41:25 -07004216#endif // DISABLE_TRELLISQ_SEARCH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004217
Angie Chiang808d8592017-04-06 18:36:55 -07004218// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004219#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004220 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4221 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004222 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07004223 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004224 } else {
4225 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004226 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07004227 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 }
4229#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004230 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07004231 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004232#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004233
Yushin Cho75b01002017-06-21 13:43:57 -07004234 tmp = pixel_diff_dist(x, plane, diff, diff_stride, blk_row, blk_col,
4235 plane_bsize, txm_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004237#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
4239 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004240#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07004241 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07004242 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004243
Angie Chiang41fffae2017-04-03 10:33:18 -07004244 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
4245 MAX_TX_SIZE, eob);
4246 if (eob > 0) {
Yushin Cho04749122017-05-25 14:19:07 -07004247#if CONFIG_DAALA_DIST
4248 if (plane == 0 && (bw < 8 && bh < 8)) {
4249 // Save sub8x8 luma decoded pixels
4250 // since 8x8 luma decoded pixels are not available for daala-dist
4251 // after recursive split of BLOCK_8x8 is done.
4252 const int pred_stride = block_size_wide[plane_bsize];
4253 const int pred_idx = (blk_row * pred_stride + blk_col)
4254 << tx_size_wide_log2[0];
4255 int16_t *decoded = &pd->pred[pred_idx];
4256 int i, j;
4257
Yushin Cho8ab875d2017-06-23 14:47:21 -07004258#if CONFIG_HIGHBITDEPTH
4259 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4260 for (j = 0; j < bh; j++)
4261 for (i = 0; i < bw; i++)
4262 decoded[j * pred_stride + i] =
4263 CONVERT_TO_SHORTPTR(rec_buffer)[j * MAX_TX_SIZE + i];
4264 } else {
4265#endif
4266 for (j = 0; j < bh; j++)
4267 for (i = 0; i < bw; i++)
4268 decoded[j * pred_stride + i] = rec_buffer[j * MAX_TX_SIZE + i];
4269#if CONFIG_HIGHBITDEPTH
4270 }
4271#endif // CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004272 }
4273#endif // CONFIG_DAALA_DIST
Yushin Cho75b01002017-06-21 13:43:57 -07004274 tmp = pixel_dist(cpi, x, plane, src, src_stride, rec_buffer, MAX_TX_SIZE,
4275 blk_row, blk_col, plane_bsize, txm_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004276 }
Angie Chiangb5dda482016-11-02 16:19:58 -07004277 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07004278 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07004279 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07004280 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07004281 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08004282
Angie Chiangd81fdb42016-11-03 12:20:58 -07004283#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08004284 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4285 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08004286#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07004287}
4288
Yaowu Xuf883b422016-08-30 14:01:10 -07004289static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08004290 int blk_col, int plane, int block, int block32,
4291 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07004292 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4293 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07004294 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004295 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004296 MACROBLOCKD *const xd = &x->e_mbd;
4297 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4298 struct macroblock_plane *const p = &x->plane[plane];
4299 struct macroblockd_plane *const pd = &xd->plane[plane];
4300 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4301 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07004302 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004303 [MAX_MIB_SIZE] =
4304 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07004305 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4306 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07004307 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004308 int64_t this_rd = INT64_MAX;
4309 ENTROPY_CONTEXT *pta = ta + blk_col;
4310 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004311 int coeff_ctx, i;
Jingning Han331662e2017-05-30 17:03:32 -07004312 int ctx = txfm_partition_context(tx_above + blk_col, tx_left + blk_row,
4313 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004314 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004315 int tmp_eob = 0;
4316 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07004317 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08004318 const int tx_size_ctx = txsize_sqr_map[tx_size];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004319#if CONFIG_TXK_SEL
4320 TX_TYPE best_tx_type = TX_TYPES;
4321 int txk_idx = block;
4322#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323
Jingning Han63cbf342016-11-09 15:37:48 -08004324 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08004325
Jingning Hand3fada82016-11-22 10:46:55 -08004326 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004327
4328 if (ref_best_rd < 0) {
4329 *is_cost_valid = 0;
4330 return;
4331 }
4332
Jingning Hance059e82016-10-31 16:27:28 -07004333 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004334
Angie Chiangc0feea82016-11-03 15:36:18 -07004335 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004336
4337 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4338
Jingning Han1c019f92016-11-21 12:53:32 -08004339 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4340 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004341
4342 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4343 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004344
4345 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4346 rd_stats_stack[block32].rate != INT_MAX) {
4347 *rd_stats = rd_stats_stack[block32];
4348 p->eobs[block] = !rd_stats->skip;
4349 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4350 } else {
4351 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004352 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004353 if (tx_size == TX_32X32) {
4354 rd_stats_stack[block32] = *rd_stats;
4355 }
4356 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004357
Urvang Joshi70006e42017-06-14 16:08:55 -07004358 if ((RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist) >=
4359 RDCOST(x->rdmult, zero_blk_rate, rd_stats->sse) ||
Angie Chiangb5dda482016-11-02 16:19:58 -07004360 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004361 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004362#if CONFIG_RD_DEBUG
4363 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4364 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004365#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004366 rd_stats->rate = zero_blk_rate;
4367 rd_stats->dist = rd_stats->sse;
4368 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4370 p->eobs[block] = 0;
4371 } else {
4372 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004373 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004374 }
4375
Jingning Han571189c2016-10-24 10:38:43 -07004376 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004377 rd_stats->rate +=
4378 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Urvang Joshi70006e42017-06-14 16:08:55 -07004379 this_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380 tmp_eob = p->eobs[block];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004381#if CONFIG_TXK_SEL
4382 best_tx_type = mbmi->txk_type[txk_idx];
4383#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004384 }
4385
Jingning Han571189c2016-10-24 10:38:43 -07004386 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004387 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4388 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004389 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004390 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004391 int this_cost_valid = 1;
4392 int64_t tmp_rd = 0;
Yushin Cho04749122017-05-25 14:19:07 -07004393#if CONFIG_DAALA_DIST
4394 int sub8x8_eob[4];
4395#endif
Angie Chiangd7246172016-11-03 11:49:15 -07004396 sum_rd_stats.rate =
4397 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004398
4399 assert(tx_size < TX_SIZES_ALL);
4400
Yaowu Xuc27fc142016-08-22 16:08:15 -07004401 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004402 int offsetr = blk_row + (i >> 1) * bsl;
4403 int offsetc = blk_col + (i & 0x01) * bsl;
4404
4405 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4406
Jingning Han63cbf342016-11-09 15:37:48 -08004407 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004408 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004409 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4410 rd_stats_stack);
Yushin Cho04749122017-05-25 14:19:07 -07004411#if CONFIG_DAALA_DIST
4412 if (plane == 0 && tx_size == TX_8X8) {
4413 sub8x8_eob[i] = p->eobs[block];
4414 }
4415#endif // CONFIG_DAALA_DIST
Angie Chiangc0feea82016-11-03 15:36:18 -07004416 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004417
Urvang Joshi70006e42017-06-14 16:08:55 -07004418 tmp_rd = RDCOST(x->rdmult, sum_rd_stats.rate, sum_rd_stats.dist);
Yushin Cho04749122017-05-25 14:19:07 -07004419#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07004420 if (this_rd < tmp_rd) break;
Yushin Cho04749122017-05-25 14:19:07 -07004421#endif
Jingning Han98d6a1f2016-11-03 12:47:47 -07004422 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004423 }
Yushin Cho04749122017-05-25 14:19:07 -07004424#if CONFIG_DAALA_DIST
4425 if (this_cost_valid && plane == 0 && tx_size == TX_8X8) {
4426 const int src_stride = p->src.stride;
4427 const int dst_stride = pd->dst.stride;
4428
4429 const uint8_t *src =
4430 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
4431 const uint8_t *dst =
4432 &pd->dst
4433 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
4434
4435 int64_t daala_dist;
4436 int qindex = x->qindex;
4437 const int pred_stride = block_size_wide[plane_bsize];
4438 const int pred_idx = (blk_row * pred_stride + blk_col)
4439 << tx_size_wide_log2[0];
4440 int16_t *pred = &pd->pred[pred_idx];
4441 int j;
4442 int qm = OD_HVS_QM;
4443 int use_activity_masking = 0;
4444 int row, col;
4445
Yushin Cho8ab875d2017-06-23 14:47:21 -07004446#if CONFIG_HIGHBITDEPTH
4447 uint8_t *pred8;
4448 DECLARE_ALIGNED(16, uint16_t, pred8_16[8 * 8]);
4449#else
Yushin Cho04749122017-05-25 14:19:07 -07004450 DECLARE_ALIGNED(16, uint8_t, pred8[8 * 8]);
Yushin Cho8ab875d2017-06-23 14:47:21 -07004451#endif // CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004452
4453#if CONFIG_PVQ
4454 use_activity_masking = x->daala_enc.use_activity_masking;
4455#endif
Yushin Cho8ab875d2017-06-23 14:47:21 -07004456 daala_dist = av1_daala_dist(xd, src, src_stride, dst, dst_stride, 8, 8, 8,
4457 8, qm, use_activity_masking, qindex) *
Yushin Cho04749122017-05-25 14:19:07 -07004458 16;
4459 sum_rd_stats.sse = daala_dist;
4460
Yushin Cho8ab875d2017-06-23 14:47:21 -07004461#if CONFIG_HIGHBITDEPTH
4462 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
4463 pred8 = CONVERT_TO_BYTEPTR(pred8_16);
4464 else
4465 pred8 = (uint8_t *)pred8_16;
4466#endif
Yushin Cho04749122017-05-25 14:19:07 -07004467
Yushin Cho8ab875d2017-06-23 14:47:21 -07004468#if CONFIG_HIGHBITDEPTH
4469 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4470 for (row = 0; row < 2; ++row) {
4471 for (col = 0; col < 2; ++col) {
4472 int idx = row * 2 + col;
4473 int eob = sub8x8_eob[idx];
4474
4475 if (eob > 0) {
4476 for (j = 0; j < 4; j++)
4477 for (i = 0; i < 4; i++)
4478 CONVERT_TO_SHORTPTR(pred8)
4479 [(row * 4 + j) * 8 + 4 * col + i] =
4480 pred[(row * 4 + j) * pred_stride + 4 * col + i];
4481 } else {
4482 for (j = 0; j < 4; j++)
4483 for (i = 0; i < 4; i++)
4484 CONVERT_TO_SHORTPTR(pred8)
4485 [(row * 4 + j) * 8 + 4 * col + i] = CONVERT_TO_SHORTPTR(
4486 dst)[(row * 4 + j) * dst_stride + 4 * col + i];
4487 }
Yushin Cho04749122017-05-25 14:19:07 -07004488 }
4489 }
Yushin Cho8ab875d2017-06-23 14:47:21 -07004490 } else {
4491#endif
4492 for (row = 0; row < 2; ++row) {
4493 for (col = 0; col < 2; ++col) {
4494 int idx = row * 2 + col;
4495 int eob = sub8x8_eob[idx];
4496
4497 if (eob > 0) {
4498 for (j = 0; j < 4; j++)
4499 for (i = 0; i < 4; i++)
4500 pred8[(row * 4 + j) * 8 + 4 * col + i] =
4501 pred[(row * 4 + j) * pred_stride + 4 * col + i];
4502 } else {
4503 for (j = 0; j < 4; j++)
4504 for (i = 0; i < 4; i++)
4505 pred8[(row * 4 + j) * 8 + 4 * col + i] =
4506 dst[(row * 4 + j) * dst_stride + 4 * col + i];
4507 }
4508 }
4509 }
4510#if CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004511 }
Yushin Cho8ab875d2017-06-23 14:47:21 -07004512#endif // CONFIG_HIGHBITDEPTH
4513 daala_dist = av1_daala_dist(xd, src, src_stride, pred8, 8, 8, 8, 8, 8, qm,
Yushin Cho04749122017-05-25 14:19:07 -07004514 use_activity_masking, qindex) *
4515 16;
4516 sum_rd_stats.dist = daala_dist;
4517 tmp_rd = RDCOST(x->rdmult, sum_rd_stats.rate, sum_rd_stats.dist);
4518 }
4519#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07004520 if (this_cost_valid) sum_rd = tmp_rd;
4521 }
4522
4523 if (this_rd < sum_rd) {
4524 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004525 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4526 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Jingning Han331662e2017-05-30 17:03:32 -07004527 txfm_partition_update(tx_above + blk_col, tx_left + blk_row, tx_size,
4528 tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004529 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004530 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4531 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004532 inter_tx_size[idy][idx] = tx_size;
4533 mbmi->tx_size = tx_size;
Jingning Hane3b81bc2017-06-23 11:43:52 -07004534#if CONFIG_TXK_SEL
4535 mbmi->txk_type[txk_idx] = best_tx_type;
4536#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004537 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004538 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004539 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004540 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004541 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4542 }
4543}
4544
Angie Chiangb5dda482016-11-02 16:19:58 -07004545static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4546 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004547 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004548 MACROBLOCKD *const xd = &x->e_mbd;
4549 int is_cost_valid = 1;
4550 int64_t this_rd = 0;
4551
4552 if (ref_best_rd < 0) is_cost_valid = 0;
4553
Angie Chiangc0feea82016-11-03 15:36:18 -07004554 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004555
4556 if (is_cost_valid) {
4557 const struct macroblockd_plane *const pd = &xd->plane[0];
4558 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004559 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4560 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004561 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004562 const int bh = tx_size_high_unit[max_tx_size];
4563 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004564 int idx, idy;
4565 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004566 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004567 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004568 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4569 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
Jingning Han331662e2017-05-30 17:03:32 -07004570 TXFM_CONTEXT tx_above[MAX_MIB_SIZE * 2];
4571 TXFM_CONTEXT tx_left[MAX_MIB_SIZE * 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004572
Angie Chiangb5dda482016-11-02 16:19:58 -07004573 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004574 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575
Jingning Han9ca05b72017-01-03 14:41:36 -08004576 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Jingning Han331662e2017-05-30 17:03:32 -07004577 memcpy(tx_above, xd->above_txfm_context, sizeof(TXFM_CONTEXT) * mi_width);
4578 memcpy(tx_left, xd->left_txfm_context, sizeof(TXFM_CONTEXT) * mi_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004579
4580 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004581 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004582 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004583 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004584 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004585 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004586 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Urvang Joshi70006e42017-06-14 16:08:55 -07004587 this_rd += AOMMIN(RDCOST(x->rdmult, pn_rd_stats.rate, pn_rd_stats.dist),
4588 RDCOST(x->rdmult, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004589 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004590 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004591 }
4592 }
4593 }
4594
Urvang Joshi70006e42017-06-14 16:08:55 -07004595 this_rd = AOMMIN(RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist),
4596 RDCOST(x->rdmult, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004597 if (this_rd > ref_best_rd) is_cost_valid = 0;
4598
4599 if (!is_cost_valid) {
4600 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004601 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004602 }
4603}
4604
Yaowu Xuf883b422016-08-30 14:01:10 -07004605static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004606 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004607 int64_t ref_best_rd, TX_TYPE tx_type,
4608 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004609 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610 MACROBLOCKD *const xd = &x->e_mbd;
4611 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004612 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004613 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4614 int s0 = av1_cost_bit(skip_prob, 0);
4615 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004617 int row, col;
4618 const int max_blocks_high = max_block_high(xd, bsize, 0);
4619 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004620
4621 mbmi->tx_type = tx_type;
Jingning Han63cbf342016-11-09 15:37:48 -08004622 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Jingning Han70bd76e2017-05-30 10:53:00 -07004623 mbmi->min_tx_size = get_min_tx_size(mbmi->inter_tx_size[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004624
Angie Chiangb5dda482016-11-02 16:19:58 -07004625 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004626
Jingning Hane67b38a2016-11-04 10:30:00 -07004627 for (row = 0; row < max_blocks_high / 2; ++row)
4628 for (col = 0; col < max_blocks_wide / 2; ++col)
4629 mbmi->min_tx_size = AOMMIN(
4630 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4631
Yaowu Xuc27fc142016-08-22 16:08:15 -07004632#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004633 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4634 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004636 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4637 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638 if (is_inter) {
4639 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004640 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004641 cpi->inter_tx_type_costs[ext_tx_set]
4642 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004643 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644 } else {
4645 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004646 rd_stats->rate +=
4647 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4648 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004649 }
4650 }
Jingning Han243b66b2017-06-23 12:11:47 -07004651#else // CONFIG_EXT_TX
4652#if !CONFIG_TXK_SEL
Jingning Hane67b38a2016-11-04 10:30:00 -07004653 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4654 rd_stats->rate +=
4655 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Jingning Han243b66b2017-06-23 12:11:47 -07004656#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004657#endif // CONFIG_EXT_TX
4658
Angie Chiangb5dda482016-11-02 16:19:58 -07004659 if (rd_stats->skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07004660 rd = RDCOST(x->rdmult, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004661 else
Urvang Joshi70006e42017-06-14 16:08:55 -07004662 rd = RDCOST(x->rdmult, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663
Angie Chiangb5dda482016-11-02 16:19:58 -07004664 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4665 !(rd_stats->skip))
Urvang Joshi70006e42017-06-14 16:08:55 -07004666 rd = AOMMIN(rd, RDCOST(x->rdmult, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004667
4668 return rd;
4669}
4670
Angie Chiangb5dda482016-11-02 16:19:58 -07004671static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4672 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004673 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004674 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004675 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4676 MACROBLOCKD *const xd = &x->e_mbd;
4677 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4678 int64_t rd = INT64_MAX;
4679 int64_t best_rd = INT64_MAX;
4680 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4681 const int is_inter = is_inter_block(mbmi);
4682 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004683 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004684 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004685 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004686 TX_TYPE txk_start = DCT_DCT;
4687#if CONFIG_TXK_SEL
4688 TX_TYPE txk_end = DCT_DCT + 1;
4689#else
4690 TX_TYPE txk_end = TX_TYPES;
4691#endif
Angie Chiangf1cb0752017-04-10 16:01:20 -07004692 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004693 int idx, idy;
4694 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004695 const int count32 =
4696 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004697#if CONFIG_EXT_PARTITION
4698 RD_STATS rd_stats_stack[16];
4699#else
Jingning Han63cbf342016-11-09 15:37:48 -08004700 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004701#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004702#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004703 const int ext_tx_set =
4704 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004705#endif // CONFIG_EXT_TX
4706
4707 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4708#if CONFIG_EXT_TX
4709 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4710#else
4711 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004712#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004713
Angie Chiangc0feea82016-11-03 15:36:18 -07004714 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004715
Jingning Han89d648b2016-11-22 11:22:08 -08004716 for (idx = 0; idx < count32; ++idx)
4717 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004718
Jingning Hane3b81bc2017-06-23 11:43:52 -07004719 for (tx_type = txk_start; tx_type < txk_end; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004720 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004721 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004722#if CONFIG_EXT_TX
4723 if (is_inter) {
4724 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4725 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4726 if (!do_tx_type_search(tx_type, prune)) continue;
4727 }
4728 } else {
4729 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4730 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4731 }
4732 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4733 }
4734#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4736 !do_tx_type_search(tx_type, prune))
4737 continue;
4738#endif // CONFIG_EXT_TX
4739 if (is_inter && x->use_default_inter_tx_type &&
4740 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4741 continue;
4742
Jingning Hane67b38a2016-11-04 10:30:00 -07004743 if (xd->lossless[mbmi->segment_id])
4744 if (tx_type != DCT_DCT) continue;
4745
Angie Chiangb5dda482016-11-02 16:19:58 -07004746 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004747 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004748
4749 if (rd < best_rd) {
4750 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004751 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004752 best_tx_type = mbmi->tx_type;
4753 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004754 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4756 for (idy = 0; idy < xd->n8_h; ++idy)
4757 for (idx = 0; idx < xd->n8_w; ++idx)
4758 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4759 }
4760 }
4761
4762 mbmi->tx_type = best_tx_type;
4763 for (idy = 0; idy < xd->n8_h; ++idy)
4764 for (idx = 0; idx < xd->n8_w; ++idx)
4765 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4766 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004767 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4769}
4770
Yaowu Xuf883b422016-08-30 14:01:10 -07004771static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004772 int blk_col, int plane, int block, TX_SIZE tx_size,
4773 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004774 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004775 MACROBLOCKD *const xd = &x->e_mbd;
4776 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4777 struct macroblock_plane *const p = &x->plane[plane];
4778 struct macroblockd_plane *const pd = &xd->plane[plane];
4779 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4780 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4781 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4782 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004783 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4784 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004785
Jingning Hand3fada82016-11-22 10:46:55 -08004786 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004787
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4789
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004790 plane_tx_size =
4791 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4792 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004793
4794 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004795 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004796 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4797 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004798 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004799 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004800
Jingning Han58224042016-10-27 16:35:32 -07004801 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004802 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004803 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004804 tl[i] = !(p->eobs[block] == 0);
4805 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004806 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4807 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004808 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004809 int i;
4810
4811 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004812
4813 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004814 int offsetr = blk_row + (i >> 1) * bsl;
4815 int offsetc = blk_col + (i & 0x01) * bsl;
4816
4817 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4818
4819 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4820 above_ctx, left_ctx, rd_stats);
4821 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004822 }
4823 }
4824}
4825
4826// Return value 0: early termination triggered, no valid rd cost available;
4827// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004828static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4829 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4830 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004831 MACROBLOCKD *const xd = &x->e_mbd;
4832 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4833 int plane;
4834 int is_cost_valid = 1;
4835 int64_t this_rd;
4836
4837 if (ref_best_rd < 0) is_cost_valid = 0;
4838
Angie Chiangc0feea82016-11-03 15:36:18 -07004839 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004840
Jingning Han31b6a4f2017-02-23 11:05:53 -08004841#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004842 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han52d2b402017-05-19 09:31:17 -07004843 bsize = scale_chroma_bsize(mbmi->sb_type, xd->plane[1].subsampling_x,
4844 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08004845#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004846
Yue Chena1e48dc2016-08-29 17:29:33 -07004847#if CONFIG_EXT_TX && CONFIG_RECT_TX
4848 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004849 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004850 }
4851#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4852
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004854 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004855 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004856 }
4857
Yaowu Xuc27fc142016-08-22 16:08:15 -07004858 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4859 const struct macroblockd_plane *const pd = &xd->plane[plane];
4860 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004861 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4862 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004863 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004864 const int bh = tx_size_high_unit[max_tx_size];
4865 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 int idx, idy;
4867 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004868 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4870 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004871 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004872 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004873
Jingning Han9ca05b72017-01-03 14:41:36 -08004874 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004875
4876 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004877 for (idx = 0; idx < mi_width; idx += bw) {
4878 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004879 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004880 block += step;
4881 }
4882 }
4883
Angie Chiangb5dda482016-11-02 16:19:58 -07004884 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885 is_cost_valid = 0;
4886 break;
4887 }
4888
Angie Chiang628d7c92016-11-03 16:24:56 -07004889 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004890
Urvang Joshi70006e42017-06-14 16:08:55 -07004891 this_rd = AOMMIN(RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist),
4892 RDCOST(x->rdmult, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004893
4894 if (this_rd > ref_best_rd) {
4895 is_cost_valid = 0;
4896 break;
4897 }
4898 }
4899
4900 if (!is_cost_valid) {
4901 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004902 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004903 }
4904
4905 return is_cost_valid;
4906}
4907#endif // CONFIG_VAR_TX
4908
Urvang Joshib100db72016-10-12 16:28:56 -07004909#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004910static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4911 int dc_mode_cost,
4912 uint8_t *best_palette_color_map,
4913 MB_MODE_INFO *const best_mbmi,
4914 int64_t *best_rd, int *rate,
4915 int *rate_tokenonly, int64_t *distortion,
4916 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004917 MACROBLOCKD *const xd = &x->e_mbd;
4918 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004919 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08004920 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004921 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004922 int this_rate;
4923 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004924 int colors_u, colors_v, colors;
4925 const int src_stride = x->plane[1].src.stride;
4926 const uint8_t *const src_u = x->plane[1].src.buf;
4927 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004928 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004929 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004930 int plane_block_width, plane_block_height, rows, cols;
4931 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4932 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004933 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4934
hui su83c26632017-01-24 17:19:06 -08004935 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004936#if CONFIG_FILTER_INTRA
4937 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4938#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004939
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004940#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004941 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004942 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4943 cpi->common.bit_depth);
4944 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4945 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004946 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004947#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004948 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4949 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004950#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004951 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004952#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004953
hui su33567b22017-04-30 16:40:19 -07004954#if CONFIG_PALETTE_DELTA_ENCODING
4955 const MODE_INFO *above_mi = xd->above_mi;
4956 const MODE_INFO *left_mi = xd->left_mi;
4957 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
4958 const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
4959#endif // CONFIG_PALETTE_DELTA_ENCODING
4960
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961 colors = colors_u > colors_v ? colors_u : colors_v;
4962 if (colors > 1 && colors <= 64) {
4963 int r, c, n, i, j;
4964 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004965 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004966 float lb_u, ub_u, val_u;
4967 float lb_v, ub_v, val_v;
4968 float *const data = x->palette_buffer->kmeans_data_buf;
4969 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004970
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004971#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004972 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4973 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4974 if (cpi->common.use_highbitdepth) {
4975 lb_u = src_u16[0];
4976 ub_u = src_u16[0];
4977 lb_v = src_v16[0];
4978 ub_v = src_v16[0];
4979 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004980#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004981 lb_u = src_u[0];
4982 ub_u = src_u[0];
4983 lb_v = src_v[0];
4984 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004985#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004986 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004987#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004988
Yaowu Xuc27fc142016-08-22 16:08:15 -07004989 for (r = 0; r < rows; ++r) {
4990 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004991#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004992 if (cpi->common.use_highbitdepth) {
4993 val_u = src_u16[r * src_stride + c];
4994 val_v = src_v16[r * src_stride + c];
4995 data[(r * cols + c) * 2] = val_u;
4996 data[(r * cols + c) * 2 + 1] = val_v;
4997 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004998#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004999 val_u = src_u[r * src_stride + c];
5000 val_v = src_v[r * src_stride + c];
5001 data[(r * cols + c) * 2] = val_u;
5002 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005003#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005004 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005005#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005006 if (val_u < lb_u)
5007 lb_u = val_u;
5008 else if (val_u > ub_u)
5009 ub_u = val_u;
5010 if (val_v < lb_v)
5011 lb_v = val_v;
5012 else if (val_v > ub_v)
5013 ub_v = val_v;
5014 }
5015 }
5016
5017 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
5018 --n) {
5019 for (i = 0; i < n; ++i) {
5020 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
5021 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
5022 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005023 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07005024#if CONFIG_PALETTE_DELTA_ENCODING
hui su33567b22017-04-30 16:40:19 -07005025 optimize_palette_colors(color_cache, n_cache, n, 2, centroids);
hui sud13c24a2017-04-07 16:13:07 -07005026 // Sort the U channel colors in ascending order.
5027 for (i = 0; i < 2 * (n - 1); i += 2) {
5028 int min_idx = i;
5029 float min_val = centroids[i];
5030 for (j = i + 2; j < 2 * n; j += 2)
5031 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
5032 if (min_idx != i) {
5033 float temp_u = centroids[i], temp_v = centroids[i + 1];
5034 centroids[i] = centroids[min_idx];
5035 centroids[i + 1] = centroids[min_idx + 1];
5036 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
5037 }
5038 }
5039 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
5040#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08005041 extend_palette_color_map(color_map, cols, rows, plane_block_width,
5042 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005043 pmi->palette_size[1] = n;
5044 for (i = 1; i < 3; ++i) {
5045 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005046#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005047 if (cpi->common.use_highbitdepth)
5048 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
5049 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
5050 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005051#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005052 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
5053 clip_pixel((int)centroids[j * 2 + i - 1]);
5054 }
5055 }
5056
Angie Chiang284d7772016-11-08 11:06:45 -08005057 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
5058 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005059 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08005060 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08005061 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07005062 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07005063 av1_cost_bit(
5064 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui su33567b22017-04-30 16:40:19 -07005065 this_rate += av1_palette_color_cost_uv(pmi,
5066#if CONFIG_PALETTE_DELTA_ENCODING
5067 color_cache, n_cache,
5068#endif // CONFIG_PALETTE_DELTA_ENCODING
5069 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070 for (i = 0; i < rows; ++i) {
5071 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07005072 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08005073 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08005074 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08005076 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
5077 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005078 }
5079 }
5080
Urvang Joshi70006e42017-06-14 16:08:55 -07005081 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005082 if (this_rd < *best_rd) {
5083 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08005084 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005085 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08005086 plane_block_width * plane_block_height *
5087 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005088 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005089 *distortion = tokenonly_rd_stats.dist;
5090 *rate_tokenonly = tokenonly_rd_stats.rate;
5091 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005092 }
5093 }
5094 }
hui su83c26632017-01-24 17:19:06 -08005095 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08005096 memcpy(color_map, best_palette_color_map,
5097 rows * cols * sizeof(best_palette_color_map[0]));
5098 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005099}
Urvang Joshib100db72016-10-12 16:28:56 -07005100#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005101
hui su5db97432016-10-14 16:10:14 -07005102#if CONFIG_FILTER_INTRA
5103// Return 1 if an filter intra mode is selected; return 0 otherwise.
5104static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
5105 int *rate, int *rate_tokenonly,
5106 int64_t *distortion, int *skippable,
5107 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108 MACROBLOCKD *const xd = &x->e_mbd;
5109 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07005110 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08005111 int this_rate;
5112 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07005113 FILTER_INTRA_MODE mode;
5114 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08005115 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116
hui su5db97432016-10-14 16:10:14 -07005117 av1_zero(filter_intra_mode_info);
5118 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005119 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07005120#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005121 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07005122#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005123
5124 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07005125 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08005126 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005127 continue;
5128
Angie Chiang284d7772016-11-08 11:06:45 -08005129 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07005130 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
5132 write_uniform_cost(FILTER_INTRA_MODES, mode);
Urvang Joshi70006e42017-06-14 16:08:55 -07005133 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005134 if (this_rd < *best_rd) {
5135 *best_rd = this_rd;
5136 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005137 *rate_tokenonly = tokenonly_rd_stats.rate;
5138 *distortion = tokenonly_rd_stats.dist;
5139 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07005140 filter_intra_mode_info = mbmi->filter_intra_mode_info;
5141 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005142 }
5143 }
5144
hui su5db97432016-10-14 16:10:14 -07005145 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07005147 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
5148 filter_intra_mode_info.use_filter_intra_mode[1];
5149 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
5150 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005151 return 1;
5152 } else {
5153 return 0;
5154 }
5155}
hui su5db97432016-10-14 16:10:14 -07005156#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005157
hui su5db97432016-10-14 16:10:14 -07005158#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08005159// Run RD calculation with given chroma intra prediction angle., and return
5160// the RD cost. Update the best mode info. if the RD cost is the best so far.
5161static int64_t pick_intra_angle_routine_sbuv(
5162 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
5163 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
5164 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005165 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005166 assert(!is_inter_block(mbmi));
Angie Chiang284d7772016-11-08 11:06:45 -08005167 int this_rate;
5168 int64_t this_rd;
5169 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005170
hui su45dc5972016-12-08 17:42:50 -08005171 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
5172 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08005173 this_rate = tokenonly_rd_stats.rate + rate_overhead;
Urvang Joshi70006e42017-06-14 16:08:55 -07005174 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005175 if (this_rd < *best_rd) {
5176 *best_rd = this_rd;
5177 *best_angle_delta = mbmi->angle_delta[1];
5178 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08005179 rd_stats->rate = tokenonly_rd_stats.rate;
5180 rd_stats->dist = tokenonly_rd_stats.dist;
5181 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005182 }
hui su45dc5972016-12-08 17:42:50 -08005183 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005184}
5185
hui su45dc5972016-12-08 17:42:50 -08005186// With given chroma directional intra prediction mode, pick the best angle
5187// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07005188static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07005189 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08005190 int64_t best_rd, int *rate,
5191 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005192 MACROBLOCKD *const xd = &x->e_mbd;
5193 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005194 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08005195 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07005196 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197
hui su45dc5972016-12-08 17:42:50 -08005198 rd_stats->rate = INT_MAX;
5199 rd_stats->skip = 0;
5200 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07005201 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005202
hui su0a6731f2017-04-26 15:23:47 -07005203 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08005204 for (i = 0; i < 2; ++i) {
5205 best_rd_in = (best_rd == INT64_MAX)
5206 ? INT64_MAX
5207 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
5208 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
5209 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
5210 best_rd_in, rate, rd_stats,
5211 &best_angle_delta, &best_rd);
5212 rd_cost[2 * angle_delta + i] = this_rd;
5213 if (angle_delta == 0) {
5214 if (this_rd == INT64_MAX) return 0;
5215 rd_cost[1] = this_rd;
5216 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005217 }
5218 }
hui su45dc5972016-12-08 17:42:50 -08005219 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005220
hui su45dc5972016-12-08 17:42:50 -08005221 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07005222 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08005223 int64_t rd_thresh;
5224 for (i = 0; i < 2; ++i) {
5225 int skip_search = 0;
5226 rd_thresh = best_rd + (best_rd >> 5);
5227 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
5228 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
5229 skip_search = 1;
5230 if (!skip_search) {
5231 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07005232 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
5233 rate, rd_stats, &best_angle_delta,
5234 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005235 }
5236 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005237 }
5238
5239 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08005240 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005241}
5242#endif // CONFIG_EXT_INTRA
5243
hui sueaddeee2017-05-30 12:19:38 -07005244static void init_sbuv_mode(MB_MODE_INFO *const mbmi) {
5245 mbmi->uv_mode = DC_PRED;
5246#if CONFIG_PALETTE
5247 mbmi->palette_mode_info.palette_size[1] = 0;
5248#endif // CONFIG_PALETTE
5249#if CONFIG_FILTER_INTRA
5250 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
5251#endif // CONFIG_FILTER_INTRA
5252}
5253
Urvang Joshi52648442016-10-13 17:27:51 -07005254static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
5255 int *rate, int *rate_tokenonly,
5256 int64_t *distortion, int *skippable,
5257 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005258 MACROBLOCKD *xd = &x->e_mbd;
5259 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005260 assert(!is_inter_block(mbmi));
hui su83c26632017-01-24 17:19:06 -08005261 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005262 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08005264 int this_rate;
5265 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005266#if CONFIG_PVQ
5267 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005268 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005269#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07005270#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08005271 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005272 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07005273#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005274
Yaowu Xuc27fc142016-08-22 16:08:15 -07005275 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08005276#if CONFIG_EXT_INTRA
5277 const int is_directional_mode =
5278 av1_is_directional_mode(mode, mbmi->sb_type);
5279#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08005280 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
5281 (1 << mode)))
5282 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005283
5284 mbmi->uv_mode = mode;
5285#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005286 mbmi->angle_delta[1] = 0;
Joe Young830d4ce2017-05-30 17:48:13 -07005287 if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
hui su0a6731f2017-04-26 15:23:47 -07005288 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
5289 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08005290 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
5291 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005292 continue;
5293 } else {
hui su83c26632017-01-24 17:19:06 -08005294#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08005295 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07005296#if CONFIG_PVQ
5297 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005298#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005299 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005300 }
hui su83c26632017-01-24 17:19:06 -08005301#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005302 }
hui su83c26632017-01-24 17:19:06 -08005303#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08005304 this_rate =
5305 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08005306
5307#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07005308 if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
hui su0a6731f2017-04-26 15:23:47 -07005309 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
5310 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08005311 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005312#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005313#if CONFIG_FILTER_INTRA
5314 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
5315 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
5316#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005317#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005318 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
5319 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07005320 this_rate += av1_cost_bit(
5321 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07005322#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005323
Yushin Cho77bba8d2016-11-04 16:36:56 -07005324#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07005325 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005326#endif // CONFIG_PVQ
Urvang Joshi70006e42017-06-14 16:08:55 -07005327 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005328
5329 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08005330 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005331 best_rd = this_rd;
5332 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005333 *rate_tokenonly = tokenonly_rd_stats.rate;
5334 *distortion = tokenonly_rd_stats.dist;
5335 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005336 }
5337 }
5338
Urvang Joshib100db72016-10-12 16:28:56 -07005339#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005340 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
5341 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08005342 rd_pick_palette_intra_sbuv(cpi, x,
5343 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
5344 best_palette_color_map, &best_mbmi, &best_rd,
5345 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005346 }
Urvang Joshib100db72016-10-12 16:28:56 -07005347#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005348
hui su5db97432016-10-14 16:10:14 -07005349#if CONFIG_FILTER_INTRA
5350 if (mbmi->sb_type >= BLOCK_8X8) {
5351 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08005352 skippable, bsize, &best_rd))
5353 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005354 }
hui su5db97432016-10-14 16:10:14 -07005355#endif // CONFIG_FILTER_INTRA
5356
hui su83c26632017-01-24 17:19:06 -08005357 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005358 // Make sure we actually chose a mode
5359 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005360 return best_rd;
5361}
5362
Urvang Joshi52648442016-10-13 17:27:51 -07005363static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
5365 TX_SIZE max_tx_size, int *rate_uv,
5366 int *rate_uv_tokenonly, int64_t *dist_uv,
5367 int *skip_uv, PREDICTION_MODE *mode_uv) {
5368 // Use an estimated rd for uv_intra based on DC_PRED if the
5369 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07005370 (void)ctx;
hui sueaddeee2017-05-30 12:19:38 -07005371 init_sbuv_mode(&x->e_mbd.mi[0]->mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08005372#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08005373#if CONFIG_CHROMA_2X2
5374 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
5375 bsize, max_tx_size);
5376#else
Jingning Han9ce464c2017-02-20 15:36:30 -08005377 if (x->skip_chroma_rd) {
5378 *rate_uv = 0;
5379 *rate_uv_tokenonly = 0;
5380 *dist_uv = 0;
5381 *skip_uv = 1;
5382 *mode_uv = DC_PRED;
5383 return;
5384 }
Jingning Han65113f32017-04-12 10:06:58 -07005385 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
5386 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07005387 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07005388 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08005389#endif // CONFIG_CHROMA_2X2
5390#else
5391 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
5392 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
5393#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
5395}
5396
Urvang Joshi52648442016-10-13 17:27:51 -07005397static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005398 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005399#if CONFIG_EXT_INTER
5400 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08005401 return cpi
5402 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Zoe Liu85b66462017-04-20 14:28:19 -07005403#if CONFIG_COMPOUND_SINGLEREF
5404 } else if (is_inter_singleref_comp_mode(mode)) {
5405 return cpi
5406 ->inter_singleref_comp_mode_cost[mode_context]
5407 [INTER_SINGLEREF_COMP_OFFSET(mode)];
5408#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005409 }
David Barkercb03dc32017-04-07 13:05:09 +01005410#endif
5411
David Barkercb03dc32017-04-07 13:05:09 +01005412 int mode_cost = 0;
5413 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
5414 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
5415
5416 assert(is_inter_mode(mode));
5417
5418 if (mode == NEWMV) {
5419 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
5420 return mode_cost;
5421 } else {
5422 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
5423 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
5424
5425 if (is_all_zero_mv) return mode_cost;
5426
5427 if (mode == ZEROMV) {
5428 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
5429 return mode_cost;
5430 } else {
5431 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
5432 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
5433
5434 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
5435 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
5436 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
5437
5438 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
5439 return mode_cost;
5440 }
5441 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442}
5443
Yue Chen5e606542017-05-24 17:03:17 -07005444#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005445static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
5446 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005447 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08005448 switch (comp_type) {
5449 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005450#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08005451 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005452#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08005453#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08005454 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08005455#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08005456 default: assert(0); return 0;
5457 }
5458}
Yue Chen5e606542017-05-24 17:03:17 -07005459#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005460
Yaowu Xuc27fc142016-08-22 16:08:15 -07005461typedef struct {
5462 int eobs;
5463 int brate;
5464 int byrate;
5465 int64_t bdist;
5466 int64_t bsse;
5467 int64_t brdcost;
5468 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005469 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005470#if CONFIG_EXT_INTER
5471 int_mv ref_mv[2];
5472#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005473
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005474#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08005475 ENTROPY_CONTEXT ta[4];
5476 ENTROPY_CONTEXT tl[4];
5477#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005478 ENTROPY_CONTEXT ta[2];
5479 ENTROPY_CONTEXT tl[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005480#endif // CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -07005481} SEG_RDSTAT;
5482
5483typedef struct {
5484 int_mv *ref_mv[2];
5485 int_mv mvp;
5486
5487 int64_t segment_rd;
5488 int r;
5489 int64_t d;
5490 int64_t sse;
5491 int segment_yrate;
5492 PREDICTION_MODE modes[4];
5493#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07005494#if CONFIG_COMPOUND_SINGLEREF
5495 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_SINGLEREF_COMP_MODES +
5496 INTER_COMPOUND_MODES];
5497#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005498 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
Zoe Liu85b66462017-04-20 14:28:19 -07005499#endif // CONFIG_COMPOUND_SINGLEREF
5500#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005501 SEG_RDSTAT rdstat[4][INTER_MODES];
5502#endif // CONFIG_EXT_INTER
5503 int mvthresh;
5504} BEST_SEG_INFO;
5505
Alex Converse0fa0f422017-04-24 12:51:14 -07005506static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5507 return (mv->row >> 3) < mv_limits->row_min ||
5508 (mv->row >> 3) > mv_limits->row_max ||
5509 (mv->col >> 3) < mv_limits->col_min ||
5510 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005511}
5512
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5514// TODO(aconverse): Find out if this is still productive then clean up or remove
5515static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005516 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005517#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005519#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005520 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005521 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5522 int mi_row, int mi_col) {
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005523 int_mv zeromv[2] = { {.as_int = 0 } };
Yushin Choc9751c52017-06-12 10:38:29 -07005524#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005525 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
Yushin Choc9751c52017-06-12 10:38:29 -07005526#endif
David Barker45390c12017-02-20 14:44:40 +00005527 (void)mi_row;
5528 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005529#if CONFIG_GLOBAL_MOTION
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005530 if (this_mode == ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005531#if CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005532 || this_mode == ZERO_ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005533#endif // CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005534 ) {
5535 for (int cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005536 zeromv[cur_frm].as_int =
5537 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005538 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005539 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005540 .as_int;
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005541 }
Sarah Parkerc2d38712017-01-24 15:15:41 -08005542 }
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005543#endif // CONFIG_GLOBAL_MOTION
5544
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545#if !CONFIG_EXT_INTER
5546 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005547#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005548 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005549 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005551 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005553 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005554 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5555 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5556 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005557
Yaowu Xuc27fc142016-08-22 16:08:15 -07005558 if (this_mode == NEARMV) {
5559 if (c1 > c3) return 0;
5560 } else if (this_mode == NEARESTMV) {
5561 if (c2 > c3) return 0;
5562 } else {
5563 assert(this_mode == ZEROMV);
5564 if (ref_frames[1] <= INTRA_FRAME) {
5565 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5566 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5567 return 0;
5568 } else {
5569 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5570 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5571 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5572 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5573 return 0;
5574 }
5575 }
5576 }
5577#if CONFIG_EXT_INTER
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005578 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005579 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005580 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5581 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005582 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5584 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005586
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005587 if (this_mode == NEAREST_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005588 if (c2 > c3) return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589 } else if (this_mode == NEAR_NEARMV) {
5590 if (c5 > c3) return 0;
5591 } else {
5592 assert(this_mode == ZERO_ZEROMV);
5593 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5594 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005595 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005596 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005597 return 0;
5598 }
5599 }
5600#endif // CONFIG_EXT_INTER
5601 return 1;
5602}
5603
Urvang Joshi52648442016-10-13 17:27:51 -07005604static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
Zoe Liu85b66462017-04-20 14:28:19 -07005605 BLOCK_SIZE bsize, int_mv *frame_mv,
5606#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5607 int_mv *frame_comp_mv,
5608#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5609 int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610#if CONFIG_EXT_INTER
David Barkerc155e012017-05-11 13:54:54 +01005611 int_mv *ref_mv_sub8x8[2], const uint8_t *mask,
5612 int mask_stride,
Fergus Simpson4063a682017-02-28 16:52:22 -08005613#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005615 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005616 const int pw = block_size_wide[bsize];
5617 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 MACROBLOCKD *xd = &x->e_mbd;
5619 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07005620// This function should only ever be called for compound modes
5621#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5622 if (!has_second_ref(mbmi)) {
5623 assert(is_inter_singleref_comp_mode(mbmi->mode));
5624 assert(frame_comp_mv);
5625 }
5626 assert(has_second_ref(mbmi) || is_inter_singleref_comp_mode(mbmi->mode));
5627 const int refs[2] = { mbmi->ref_frame[0], has_second_ref(mbmi)
5628 ? mbmi->ref_frame[1]
5629 : mbmi->ref_frame[0] };
5630#else
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005631 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005632 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Zoe Liu85b66462017-04-20 14:28:19 -07005633#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005634 int_mv ref_mv[2];
5635 int ite, ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 struct scale_factors sf;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005637#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005638 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5639 const int ic = block & 1;
5640 const int ir = (block - ic) >> 1;
Jingning Hancb637672017-06-22 09:14:40 -07005641 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005642 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5643 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005644#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005645 int is_global[2];
Zoe Liu85b66462017-04-20 14:28:19 -07005646#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5647 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5648#else
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005649 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005650#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005651 WarpedMotionParams *const wm =
5652 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5653 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5654 }
Zoe Liu85b66462017-04-20 14:28:19 -07005655#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5656 if (!has_second_ref(mbmi)) is_global[1] = is_global[0];
5657#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005658#endif // CONFIG_GLOBAL_MOTION
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005659#else // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5660 (void)block;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005661#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005662
5663 // Do joint motion search in compound mode to get more accurate mv.
5664 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5665 int last_besterr[2] = { INT_MAX, INT_MAX };
5666 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005667 av1_get_scaled_ref_frame(cpi, refs[0]),
5668 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005669 };
5670
5671// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005672#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005673 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5674 uint8_t *second_pred;
5675#else
5676 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005677#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005678
Jingning Han61418bb2017-01-23 17:12:48 -08005679#if CONFIG_EXT_INTER && CONFIG_CB4X4
5680 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005681#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005682
Zoe Liu85b66462017-04-20 14:28:19 -07005683#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5684 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5685#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005686 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005687#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Jingning Han61418bb2017-01-23 17:12:48 -08005688#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005689 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5690 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5691 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005692#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005693 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5694
5695 if (scaled_ref_frame[ref]) {
5696 int i;
5697 // Swap out the reference frame for a version that's been scaled to
5698 // match the resolution of the current frame, allowing the existing
5699 // motion search code to be used without additional modifications.
5700 for (i = 0; i < MAX_MB_PLANE; i++)
5701 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005702 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5703 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005704 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005705 }
5706
Zoe Liu85b66462017-04-20 14:28:19 -07005707#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5708 if (!has_second_ref(mbmi)) {
5709 assert(is_inter_singleref_comp_mode(mbmi->mode));
5710 // NOTE: For single ref comp mode, set up the 2nd set of ref_mv/pre_planes
5711 // all from the 1st reference frame, i.e. refs[0].
5712 ref_mv[1] = x->mbmi_ext->ref_mvs[refs[0]][0];
5713 if (scaled_ref_frame[0]) {
5714 int i;
5715 // Swap out the reference frame for a version that's been scaled to
5716 // match the resolution of the current frame, allowing the existing
5717 // motion search code to be used without additional modifications.
5718 for (i = 0; i < MAX_MB_PLANE; i++)
5719 backup_yv12[1][i] = xd->plane[i].pre[1];
5720 av1_setup_pre_planes(xd, 1, scaled_ref_frame[0], mi_row, mi_col, NULL);
5721 }
5722 }
5723#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5724
Yaowu Xuc27fc142016-08-22 16:08:15 -07005725// Since we have scaled the reference frames to match the size of the current
5726// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005727#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005728 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5729 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005730#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005731 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5732 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005733#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734
Zoe Liu85b66462017-04-20 14:28:19 -07005735// Allow joint search multiple times iteratively for each reference frame
5736// and break out of the search loop if it couldn't find a better mv.
5737#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5738 const int num_ites =
5739 (has_second_ref(mbmi) || mbmi->mode == SR_NEW_NEWMV) ? 4 : 1;
5740 const int start_ite = has_second_ref(mbmi) ? 0 : 1;
5741 for (ite = start_ite; ite < (start_ite + num_ites); ite++) {
5742#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005743 for (ite = 0; ite < 4; ite++) {
Zoe Liu85b66462017-04-20 14:28:19 -07005744#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005745 struct buf_2d ref_yv12[2];
5746 int bestsme = INT_MAX;
5747 int sadpb = x->sadperbit16;
5748 MV *const best_mv = &x->best_mv.as_mv;
5749 int search_range = 3;
5750
Alex Converse0fa0f422017-04-24 12:51:14 -07005751 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005752 int id = ite % 2; // Even iterations search in the first reference frame,
5753 // odd iterations search in the second. The predictor
5754 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005755 const int plane = 0;
David Barkere64d51a2017-06-09 14:52:42 +01005756 ConvolveParams conv_params = get_conv_params(!id, 0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005757#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5758 WarpTypesAllowed warp_types;
5759#if CONFIG_GLOBAL_MOTION
5760 warp_types.global_warp_allowed = is_global[!id];
5761#endif // CONFIG_GLOBAL_MOTION
5762#if CONFIG_WARPED_MOTION
5763 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5764#endif // CONFIG_WARPED_MOTION
5765#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766
5767 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005768 ref_yv12[0] = xd->plane[plane].pre[0];
5769 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005770
Yaowu Xuc27fc142016-08-22 16:08:15 -07005771// Get the prediction block from the 'other' reference frame.
Zoe Liu85b66462017-04-20 14:28:19 -07005772#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5773 MV *const the_other_mv = (has_second_ref(mbmi) || id)
5774 ? &frame_mv[refs[!id]].as_mv
5775 : &frame_comp_mv[refs[0]].as_mv;
5776#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5777
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005778#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5780 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005781 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005782 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
Zoe Liu85b66462017-04-20 14:28:19 -07005783#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5784 the_other_mv,
5785#else // !(CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF)
5786 &frame_mv[refs[!id]].as_mv,
5787#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5788 &sf, pw, ph, 0, mbmi->interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005789#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5790 &warp_types, p_col, p_row,
5791#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005792 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005793 } else {
5794 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005795#endif // CONFIG_HIGHBITDEPTH
Zoe Liu85b66462017-04-20 14:28:19 -07005796 av1_build_inter_predictor(
5797 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5798#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5799 the_other_mv,
5800#else // !(CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF)
5801 &frame_mv[refs[!id]].as_mv,
5802#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5803 &sf, pw, ph, &conv_params, mbmi->interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005804#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Zoe Liu85b66462017-04-20 14:28:19 -07005805 &warp_types, p_col, p_row, plane, !id,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005806#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Zoe Liu85b66462017-04-20 14:28:19 -07005807 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005808#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005810#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811
5812 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005813 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005814 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005815
Zoe Liu85b66462017-04-20 14:28:19 -07005816// Use the mv result from the single mode as mv predictor.
5817// Use the mv result from the single mode as mv predictor.
5818#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5819 if (!has_second_ref(mbmi) && id)
5820 *best_mv = frame_comp_mv[refs[0]].as_mv;
5821 else
5822#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5823 *best_mv = frame_mv[refs[id]].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005824
5825 best_mv->col >>= 3;
5826 best_mv->row >>= 3;
5827
Zoe Liu85b66462017-04-20 14:28:19 -07005828#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5829 if (!has_second_ref(mbmi))
5830 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
5831 else
5832#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5833 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005834
5835 // Small-range full-pixel motion search.
5836 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005837 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
David Barkerc155e012017-05-11 13:54:54 +01005838#if CONFIG_EXT_INTER
5839 mask, mask_stride, id,
5840#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005841 &ref_mv[id].as_mv, second_pred);
David Barkerc155e012017-05-11 13:54:54 +01005842 if (bestsme < INT_MAX) {
5843#if CONFIG_EXT_INTER
5844 if (mask)
5845 bestsme = av1_get_mvpred_mask_var(x, best_mv, &ref_mv[id].as_mv,
5846 second_pred, mask, mask_stride, id,
5847 &cpi->fn_ptr[bsize], 1);
5848 else
5849#endif
5850 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5851 second_pred, &cpi->fn_ptr[bsize], 1);
5852 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005853
Alex Converse0fa0f422017-04-24 12:51:14 -07005854 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005855
5856 if (bestsme < INT_MAX) {
5857 int dis; /* TODO: use dis in distortion calculation later. */
5858 unsigned int sse;
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005859 bestsme = cpi->find_fractional_mv_step(
5860 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5861 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5862 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5863 &dis, &sse, second_pred,
David Barkerc155e012017-05-11 13:54:54 +01005864#if CONFIG_EXT_INTER
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005865 mask, mask_stride, id,
David Barkerc155e012017-05-11 13:54:54 +01005866#endif
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005867 pw, ph, cpi->sf.use_upsampled_references);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005868 }
5869
5870 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005871 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005872
5873 if (bestsme < last_besterr[id]) {
Zoe Liu85b66462017-04-20 14:28:19 -07005874#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5875 // NOTE: For single ref comp mode, frame_mv stores the first mv and
5876 // frame_comp_mv stores the second mv.
5877 if (!has_second_ref(mbmi) && id)
5878 frame_comp_mv[refs[0]].as_mv = *best_mv;
5879 else
5880#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5881 frame_mv[refs[id]].as_mv = *best_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005882 last_besterr[id] = bestsme;
Zoe Liu85b66462017-04-20 14:28:19 -07005883#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5884 if (!has_second_ref(mbmi)) last_besterr[!id] = last_besterr[id];
5885#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886 } else {
5887 break;
5888 }
5889 }
5890
5891 *rate_mv = 0;
5892
Zoe Liu85b66462017-04-20 14:28:19 -07005893#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5894 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5895#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005896 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005897#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005898 if (scaled_ref_frame[ref]) {
5899 // Restore the prediction frame pointers to their unscaled versions.
5900 int i;
5901 for (i = 0; i < MAX_MB_PLANE; i++)
5902 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5903 }
Zoe Liu85b66462017-04-20 14:28:19 -07005904
5905#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5906 if (!has_second_ref(mbmi))
5907 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005908 else
Zoe Liu85b66462017-04-20 14:28:19 -07005909#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5910 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
5911
5912#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5913 if (!has_second_ref(mbmi)) {
5914 // NOTE: For single ref comp mode, i.e. !has_second_ref(mbmi) is true, the
5915 // first mv is stored in frame_mv[] and the second mv is stored in
5916 // frame_comp_mv[].
5917 if (compound_ref0_mode(mbmi->mode) == NEWMV) // SR_NEW_NEWMV
5918 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5919 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5920 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5921 assert(compound_ref1_mode(mbmi->mode) == NEWMV);
5922 *rate_mv += av1_mv_bit_cost(&frame_comp_mv[refs[0]].as_mv,
5923 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5924 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5925 } else {
5926#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5927#if CONFIG_EXT_INTER && !CONFIG_CB4X4
5928 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005929#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Zoe Liu85b66462017-04-20 14:28:19 -07005930 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5931 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5932 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5933#if CONFIG_EXT_INTER && !CONFIG_CB4X4
5934 else
5935 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5936 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5937 x->mvcost, MV_COST_WEIGHT);
5938#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
5939#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5940 }
5941#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005942 }
Zoe Liu85b66462017-04-20 14:28:19 -07005943
5944#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5945 if (!has_second_ref(mbmi)) {
5946 if (scaled_ref_frame[0]) {
5947 // Restore the prediction frame pointers to their unscaled versions.
5948 int i;
5949 for (i = 0; i < MAX_MB_PLANE; i++)
5950 xd->plane[i].pre[1] = backup_yv12[1][i];
5951 }
5952 }
5953#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954}
5955
Zoe Liuc082bbc2017-05-17 13:31:37 -07005956static void estimate_ref_frame_costs(
5957 const AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
5958 unsigned int *ref_costs_single,
5959#if CONFIG_EXT_COMP_REFS
5960 unsigned int (*ref_costs_comp)[TOTAL_REFS_PER_FRAME],
5961#else
5962 unsigned int *ref_costs_comp,
5963#endif // CONFIG_EXT_COMP_REFS
5964 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965 int seg_ref_active =
5966 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5967 if (seg_ref_active) {
5968 memset(ref_costs_single, 0,
5969 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
Zoe Liuc082bbc2017-05-17 13:31:37 -07005970#if CONFIG_EXT_COMP_REFS
5971 int ref_frame;
5972 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
5973 memset(ref_costs_comp[ref_frame], 0,
5974 TOTAL_REFS_PER_FRAME * sizeof((*ref_costs_comp)[0]));
5975#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005976 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
Zoe Liuc082bbc2017-05-17 13:31:37 -07005977#endif // CONFIG_EXT_COMP_REFS
5978
Yaowu Xuc27fc142016-08-22 16:08:15 -07005979 *comp_mode_p = 128;
5980 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005981 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5982 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005983
5984 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005985 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005986 *comp_mode_p = comp_inter_p;
5987 } else {
5988 *comp_mode_p = 128;
5989 }
5990
Yaowu Xuf883b422016-08-30 14:01:10 -07005991 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005992
5993 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005994 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5995 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005996#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005997 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5998 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5999 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006000#endif // CONFIG_EXT_REFS
6001
Yaowu Xuf883b422016-08-30 14:01:10 -07006002 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003
6004 ref_costs_single[LAST_FRAME] =
6005#if CONFIG_EXT_REFS
6006 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6007 ref_costs_single[BWDREF_FRAME] =
6008#endif // CONFIG_EXT_REFS
6009 ref_costs_single[GOLDEN_FRAME] =
6010 ref_costs_single[ALTREF_FRAME] = base_cost;
6011
6012#if CONFIG_EXT_REFS
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006013#if CONFIG_VAR_REFS
6014 // Test need to explicitly code (L,L2,L3,G) vs (BWD,ALT) branch node in
6015 // tree
6016 if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm)) {
6017#endif // CONFIG_VAR_REFS
6018 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6019 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6020 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6021 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6022 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6023 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6024#if CONFIG_VAR_REFS
6025 }
6026#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006027
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006028#if CONFIG_VAR_REFS
6029 // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree
6030 if (L_OR_L2(cm) && L3_OR_G(cm)) {
6031#endif // CONFIG_VAR_REFS
6032 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6033 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6034 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6035 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
6036#if CONFIG_VAR_REFS
6037 }
6038#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006039
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006040#if CONFIG_VAR_REFS
6041 // Test need to explicitly code (BWD) vs (ALT) branch node in tree
6042 if (BWD_AND_ALT(cm)) {
6043#endif // CONFIG_VAR_REFS
6044 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6045 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
6046#if CONFIG_VAR_REFS
6047 }
6048#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006050#if CONFIG_VAR_REFS
6051 // Test need to explicitly code (L) vs (L2) branch node in tree
6052 if (L_AND_L2(cm)) {
6053#endif // CONFIG_VAR_REFS
6054 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6055 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
6056#if CONFIG_VAR_REFS
6057 }
6058#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006059
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006060#if CONFIG_VAR_REFS
6061 // Test need to explicitly code (L3) vs (G) branch node in tree
6062 if (L3_AND_G(cm)) {
6063#endif // CONFIG_VAR_REFS
6064 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6065 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
6066#if CONFIG_VAR_REFS
6067 }
6068#endif // CONFIG_VAR_REFS
6069#else // !CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006070 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6071 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6072 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006073
Yaowu Xuf883b422016-08-30 14:01:10 -07006074 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6075 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006076#endif // CONFIG_EXT_REFS
6077 } else {
6078 ref_costs_single[LAST_FRAME] = 512;
6079#if CONFIG_EXT_REFS
6080 ref_costs_single[LAST2_FRAME] = 512;
6081 ref_costs_single[LAST3_FRAME] = 512;
6082 ref_costs_single[BWDREF_FRAME] = 512;
6083#endif // CONFIG_EXT_REFS
6084 ref_costs_single[GOLDEN_FRAME] = 512;
6085 ref_costs_single[ALTREF_FRAME] = 512;
6086 }
6087
6088 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006089 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006091 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6092 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6093 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094#endif // CONFIG_EXT_REFS
6095
Yaowu Xuf883b422016-08-30 14:01:10 -07006096 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006097
Zoe Liuc082bbc2017-05-17 13:31:37 -07006098#if CONFIG_EXT_COMP_REFS
6099 aom_prob comp_ref_type_p = av1_get_comp_reference_type_prob(cm, xd);
6100 unsigned int ref_bicomp_costs[TOTAL_REFS_PER_FRAME] = { 0 };
6101
6102 ref_bicomp_costs[LAST_FRAME] = ref_bicomp_costs[LAST2_FRAME] =
6103 ref_bicomp_costs[LAST3_FRAME] = ref_bicomp_costs[GOLDEN_FRAME] =
6104#if USE_UNI_COMP_REFS
6105 base_cost + av1_cost_bit(comp_ref_type_p, 1);
6106#else
6107 base_cost;
6108#endif // USE_UNI_COMP_REFS
6109 ref_bicomp_costs[BWDREF_FRAME] = ref_bicomp_costs[ALTREF_FRAME] = 0;
6110
6111 ref_bicomp_costs[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6112 ref_bicomp_costs[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6113 ref_bicomp_costs[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6114 ref_bicomp_costs[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
6115
6116 ref_bicomp_costs[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6117 ref_bicomp_costs[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
6118
6119 ref_bicomp_costs[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6120 ref_bicomp_costs[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
6121
6122 ref_bicomp_costs[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6123 ref_bicomp_costs[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
6124
6125 int ref0;
6126 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
6127 ref_costs_comp[ref0][BWDREF_FRAME] =
6128 ref_bicomp_costs[ref0] + ref_bicomp_costs[BWDREF_FRAME];
6129 ref_costs_comp[ref0][ALTREF_FRAME] =
6130 ref_bicomp_costs[ref0] + ref_bicomp_costs[ALTREF_FRAME];
6131 }
6132
6133 aom_prob uni_comp_ref_p = av1_get_pred_prob_uni_comp_ref_p(cm, xd);
6134 aom_prob uni_comp_ref_p1 = av1_get_pred_prob_uni_comp_ref_p1(cm, xd);
6135
6136 ref_costs_comp[LAST_FRAME][LAST2_FRAME] =
6137 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6138 av1_cost_bit(uni_comp_ref_p, 0) + av1_cost_bit(uni_comp_ref_p1, 0);
6139 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] =
6140 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6141 av1_cost_bit(uni_comp_ref_p, 0) + av1_cost_bit(uni_comp_ref_p1, 1);
6142
6143 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] =
6144 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6145 av1_cost_bit(uni_comp_ref_p, 1);
6146
6147#else // !CONFIG_EXT_COMP_REFS
6148
Yaowu Xuc27fc142016-08-22 16:08:15 -07006149 ref_costs_comp[LAST_FRAME] =
6150#if CONFIG_EXT_REFS
6151 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6152#endif // CONFIG_EXT_REFS
6153 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6154
6155#if CONFIG_EXT_REFS
6156 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6157#endif // CONFIG_EXT_REFS
6158
6159#if CONFIG_EXT_REFS
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006160#if CONFIG_VAR_REFS
6161 // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree
6162 if (L_OR_L2(cm) && L3_OR_G(cm)) {
6163#endif // CONFIG_VAR_REFS
6164 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6165 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6166 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6167 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
6168#if CONFIG_VAR_REFS
6169 }
6170#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006171
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006172#if CONFIG_VAR_REFS
6173 // Test need to explicitly code (L) vs (L2) branch node in tree
6174 if (L_AND_L2(cm)) {
6175#endif // CONFIG_VAR_REFS
6176 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6177 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
6178#if CONFIG_VAR_REFS
6179 }
6180#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006181
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006182#if CONFIG_VAR_REFS
6183 // Test need to explicitly code (L3) vs (G) branch node in tree
6184 if (L3_AND_G(cm)) {
6185#endif // CONFIG_VAR_REFS
6186 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6187 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
6188#if CONFIG_VAR_REFS
6189 }
6190#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006191
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006192// NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6193// more bit.
6194#if CONFIG_VAR_REFS
6195 // Test need to explicitly code (BWD) vs (ALT) branch node in tree
6196 if (BWD_AND_ALT(cm)) {
6197#endif // CONFIG_VAR_REFS
6198 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6199 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
6200#if CONFIG_VAR_REFS
6201 }
6202#endif // CONFIG_VAR_REFS
6203#else // !CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006204 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6205 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006206#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -07006207#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006208 } else {
Zoe Liuc082bbc2017-05-17 13:31:37 -07006209#if CONFIG_EXT_COMP_REFS
6210 int ref0;
6211 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
6212 ref_costs_comp[ref0][BWDREF_FRAME] = 512;
6213 ref_costs_comp[ref0][ALTREF_FRAME] = 512;
6214 }
6215 ref_costs_comp[LAST_FRAME][LAST2_FRAME] = 512;
6216 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] = 512;
6217 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] = 512;
6218#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006219 ref_costs_comp[LAST_FRAME] = 512;
6220#if CONFIG_EXT_REFS
6221 ref_costs_comp[LAST2_FRAME] = 512;
6222 ref_costs_comp[LAST3_FRAME] = 512;
6223 ref_costs_comp[BWDREF_FRAME] = 512;
6224 ref_costs_comp[ALTREF_FRAME] = 512;
6225#endif // CONFIG_EXT_REFS
6226 ref_costs_comp[GOLDEN_FRAME] = 512;
Zoe Liuc082bbc2017-05-17 13:31:37 -07006227#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006228 }
6229 }
6230}
6231
6232static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6233 int mode_index,
6234 int64_t comp_pred_diff[REFERENCE_MODES],
6235 int skippable) {
6236 MACROBLOCKD *const xd = &x->e_mbd;
6237
6238 // Take a snapshot of the coding context so it can be
6239 // restored if we decide to encode this way
6240 ctx->skip = x->skip;
6241 ctx->skippable = skippable;
6242 ctx->best_mode_index = mode_index;
6243 ctx->mic = *xd->mi[0];
6244 ctx->mbmi_ext = *x->mbmi_ext;
6245 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6246 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6247 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6248}
6249
clang-format55ce9e02017-02-15 22:27:12 -08006250static void setup_buffer_inter(
6251 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6252 BLOCK_SIZE block_size, int mi_row, int mi_col,
6253 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6254 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6255 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006256 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006257 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6258 MACROBLOCKD *const xd = &x->e_mbd;
6259 MODE_INFO *const mi = xd->mi[0];
6260 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6261 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6262 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6263
6264 assert(yv12 != NULL);
6265
6266 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6267 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006268 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006269
6270 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006271 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
6272 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006274 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006275#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006276 candidates, mi_row, mi_col, NULL, NULL,
6277 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006278
6279 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006280 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6281 &frame_nearest_mv[ref_frame],
6282 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006283
Jingning Han271bb2c2016-12-14 12:34:46 -08006284// Further refinement that is encode side only to test the top few candidates
6285// in full and choose the best as the centre point for subsequent searches.
6286// The current implementation doesn't support scaling.
6287#if CONFIG_CB4X4
6288 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6289 block_size);
6290#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006291 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6292 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6293 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006294#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006295}
6296
Urvang Joshi52648442016-10-13 17:27:51 -07006297static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6298 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006299#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006300 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006301#endif // CONFIG_EXT_INTER
6302 int *rate_mv) {
6303 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006304 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006305 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6306 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6307 int bestsme = INT_MAX;
6308 int step_param;
6309 int sadpb = x->sadperbit16;
6310 MV mvp_full;
6311#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07006312#if CONFIG_COMPOUND_SINGLEREF
6313 int ref =
6314 has_second_ref(mbmi) ? mbmi->ref_frame[ref_idx] : mbmi->ref_frame[0];
6315#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316 int ref = mbmi->ref_frame[ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006317#endif // CONFIG_COMPOUND_SINGLEREF
6318#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006319 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006320 int ref_idx = 0;
6321#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006322 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006323
Alex Converse0fa0f422017-04-24 12:51:14 -07006324 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006325 int cost_list[5];
6326
6327 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006328 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006329
6330 MV pred_mv[3];
6331 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6332 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6333 pred_mv[2] = x->pred_mv[ref];
6334
Yaowu Xuc27fc142016-08-22 16:08:15 -07006335 if (scaled_ref_frame) {
6336 int i;
6337 // Swap out the reference frame for a version that's been scaled to
6338 // match the resolution of the current frame, allowing the existing
6339 // motion search code to be used without additional modifications.
6340 for (i = 0; i < MAX_MB_PLANE; i++)
6341 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6342
Yaowu Xuf883b422016-08-30 14:01:10 -07006343 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006344 }
6345
Alex Converse0fa0f422017-04-24 12:51:14 -07006346 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006347
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006348 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006349
Yaowu Xuc27fc142016-08-22 16:08:15 -07006350 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006351 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006352 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6353 // Take wtd average of the step_params based on the last frame's
6354 // max mv magnitude and that based on the best ref mvs of the current
6355 // block for the given reference.
6356 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006357 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006358 2;
6359 } else {
6360 step_param = cpi->mv_step_param;
6361 }
6362
6363 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6364 int boffset =
6365 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006366 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6367 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006368 }
6369
6370 if (cpi->sf.adaptive_motion_search) {
6371 int bwl = b_width_log2_lookup[bsize];
6372 int bhl = b_height_log2_lookup[bsize];
6373 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6374
6375 if (tlevel < 5) step_param += 2;
6376
6377 // prev_mv_sad is not setup for dynamically scaled frames.
6378 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6379 int i;
6380 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6381 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6382 x->pred_mv[ref].row = 0;
6383 x->pred_mv[ref].col = 0;
6384 x->best_mv.as_int = INVALID_MV;
6385
6386 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006387 int j;
6388 for (j = 0; j < MAX_MB_PLANE; ++j)
6389 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 }
6391 return;
6392 }
6393 }
6394 }
6395 }
6396
Alex Converse0fa0f422017-04-24 12:51:14 -07006397 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006398
Yue Chene9638cc2016-10-10 12:37:54 -07006399#if CONFIG_MOTION_VAR
6400 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6401 mvp_full = mbmi->mv[0].as_mv;
6402 else
6403#endif // CONFIG_MOTION_VAR
6404 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006405
6406 mvp_full.col >>= 3;
6407 mvp_full.row >>= 3;
6408
6409 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6410
Yue Chene9638cc2016-10-10 12:37:54 -07006411#if CONFIG_MOTION_VAR
6412 switch (mbmi->motion_mode) {
6413 case SIMPLE_TRANSLATION:
6414#endif // CONFIG_MOTION_VAR
6415 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6416 sadpb, cond_cost_list(cpi, cost_list),
6417 &ref_mv, INT_MAX, 1);
6418#if CONFIG_MOTION_VAR
6419 break;
6420 case OBMC_CAUSAL:
6421 bestsme = av1_obmc_full_pixel_diamond(
6422 cpi, x, &mvp_full, step_param, sadpb,
6423 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6424 &(x->best_mv.as_mv), 0);
6425 break;
James Zern88896732017-06-23 15:55:09 -07006426 default: assert(0 && "Invalid motion mode!\n");
Yue Chene9638cc2016-10-10 12:37:54 -07006427 }
6428#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429
Alex Converse0fa0f422017-04-24 12:51:14 -07006430 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431
6432 if (bestsme < INT_MAX) {
6433 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006434#if CONFIG_MOTION_VAR
6435 switch (mbmi->motion_mode) {
6436 case SIMPLE_TRANSLATION:
6437#endif // CONFIG_MOTION_VAR
6438 if (cpi->sf.use_upsampled_references) {
6439 int best_mv_var;
6440 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6441 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006442 const int pw = block_size_wide[bsize];
6443 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006444
Yue Chene9638cc2016-10-10 12:37:54 -07006445 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006446 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6447 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6448 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01006449 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
6450#if CONFIG_EXT_INTER
6451 NULL, 0, 0,
6452#endif
6453 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006454
Yue Chene9638cc2016-10-10 12:37:54 -07006455 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07006456 const int minc =
6457 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6458 const int maxc =
6459 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6460 const int minr =
6461 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6462 const int maxr =
6463 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07006464 int this_var;
6465 MV best_mv = x->best_mv.as_mv;
6466
6467 x->best_mv = x->second_best_mv;
6468 if (x->best_mv.as_mv.row * 8 <= maxr &&
6469 x->best_mv.as_mv.row * 8 >= minr &&
6470 x->best_mv.as_mv.col * 8 <= maxc &&
6471 x->best_mv.as_mv.col * 8 >= minc) {
6472 this_var = cpi->find_fractional_mv_step(
6473 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6474 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6475 cpi->sf.mv.subpel_iters_per_step,
6476 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01006477 &dis, &x->pred_sse[ref], NULL,
6478#if CONFIG_EXT_INTER
6479 NULL, 0, 0,
6480#endif
6481 pw, ph, 1);
Yue Chene9638cc2016-10-10 12:37:54 -07006482 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6483 x->best_mv.as_mv = best_mv;
6484 }
6485 }
Yue Chene9638cc2016-10-10 12:37:54 -07006486 } else {
6487 cpi->find_fractional_mv_step(
6488 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6489 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6490 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01006491 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
6492#if CONFIG_EXT_INTER
6493 NULL, 0, 0,
6494#endif
6495 0, 0, 0);
Yue Chene9638cc2016-10-10 12:37:54 -07006496 }
6497#if CONFIG_MOTION_VAR
6498 break;
6499 case OBMC_CAUSAL:
6500 av1_find_best_obmc_sub_pixel_tree_up(
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006501 x, &x->best_mv.as_mv, &ref_mv, cm->allow_high_precision_mv,
6502 x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6503 cpi->sf.mv.subpel_iters_per_step, x->nmvjointcost, x->mvcost, &dis,
6504 &x->pred_sse[ref], 0, cpi->sf.use_upsampled_references);
Yue Chene9638cc2016-10-10 12:37:54 -07006505 break;
James Zern88896732017-06-23 15:55:09 -07006506 default: assert(0 && "Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006507 }
Yue Chene9638cc2016-10-10 12:37:54 -07006508#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006509 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006510 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6511 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006512
Yue Chene9638cc2016-10-10 12:37:54 -07006513#if CONFIG_MOTION_VAR
6514 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6515#else
6516 if (cpi->sf.adaptive_motion_search)
6517#endif // CONFIG_MOTION_VAR
6518 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006519
6520 if (scaled_ref_frame) {
6521 int i;
6522 for (i = 0; i < MAX_MB_PLANE; i++)
6523 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6524 }
6525}
6526
David Barkerac37fa32016-12-02 12:30:21 +00006527static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006528 int i;
6529 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00006530 xd->plane[i].dst.buf = dst.plane[i];
6531 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006532 }
6533}
6534
Yaowu Xuc27fc142016-08-22 16:08:15 -07006535#if CONFIG_EXT_INTER
David Barker8dd9b572017-05-12 16:31:38 +01006536static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x,
David Barkerf19f35f2017-05-22 16:33:22 +01006537 BLOCK_SIZE bsize, const MV *other_mv,
David Barker8dd9b572017-05-12 16:31:38 +01006538 int mi_row, int mi_col, const int block,
6539 int ref_idx, uint8_t *second_pred) {
6540 const AV1_COMMON *const cm = &cpi->common;
6541 const int pw = block_size_wide[bsize];
6542 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006543 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006544 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07006545#if CONFIG_COMPOUND_SINGLEREF
6546 const int other_ref =
6547 has_second_ref(mbmi) ? mbmi->ref_frame[!ref_idx] : mbmi->ref_frame[0];
6548#else // !CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006549 const int other_ref = mbmi->ref_frame[!ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006550#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006551 struct scale_factors sf;
6552#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6553 struct macroblockd_plane *const pd = &xd->plane[0];
6554 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
6555 const int ic = block & 1;
6556 const int ir = (block - ic) >> 1;
6557 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
6558 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
6559#if CONFIG_GLOBAL_MOTION
6560 WarpedMotionParams *const wm = &xd->global_motion[other_ref];
6561 int is_global = is_global_mv_block(xd->mi[0], block, wm->wmtype);
6562#endif // CONFIG_GLOBAL_MOTION
6563#else
6564 (void)block;
6565#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006566
Zoe Liu85b66462017-04-20 14:28:19 -07006567// This function should only ever be called for compound modes
6568#if CONFIG_COMPOUND_SINGLEREF
6569 assert(has_second_ref(mbmi) || is_inter_singleref_comp_mode(mbmi->mode));
6570#else // !CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006571 assert(has_second_ref(mbmi));
Zoe Liu85b66462017-04-20 14:28:19 -07006572#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07006573
David Barker8dd9b572017-05-12 16:31:38 +01006574 struct buf_2d backup_yv12[MAX_MB_PLANE];
6575 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
6576 av1_get_scaled_ref_frame(cpi, other_ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006577
6578 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01006579 int i;
6580 // Swap out the reference frame for a version that's been scaled to
6581 // match the resolution of the current frame, allowing the existing
6582 // motion search code to be used without additional modifications.
6583 for (i = 0; i < MAX_MB_PLANE; i++)
6584 backup_yv12[i] = xd->plane[i].pre[!ref_idx];
6585 av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
6586 }
6587
6588// Since we have scaled the reference frames to match the size of the current
6589// frame we must use a unit scaling factor during mode selection.
6590#if CONFIG_HIGHBITDEPTH
6591 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
6592 cm->height, cm->use_highbitdepth);
6593#else
6594 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
6595 cm->height);
6596#endif // CONFIG_HIGHBITDEPTH
6597
6598 struct buf_2d ref_yv12;
6599
6600 const int plane = 0;
David Barkere64d51a2017-06-09 14:52:42 +01006601 ConvolveParams conv_params = get_conv_params(!ref_idx, 0, plane);
David Barker8dd9b572017-05-12 16:31:38 +01006602#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6603 WarpTypesAllowed warp_types;
6604#if CONFIG_GLOBAL_MOTION
6605 warp_types.global_warp_allowed = is_global;
6606#endif // CONFIG_GLOBAL_MOTION
6607#if CONFIG_WARPED_MOTION
6608 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
6609#endif // CONFIG_WARPED_MOTION
6610#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6611
6612 // Initialized here because of compiler problem in Visual Studio.
6613 ref_yv12 = xd->plane[plane].pre[!ref_idx];
6614
6615// Get the prediction block from the 'other' reference frame.
6616#if CONFIG_HIGHBITDEPTH
6617 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6618 av1_highbd_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01006619 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
David Barkere64d51a2017-06-09 14:52:42 +01006620 0, mbmi->interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01006621#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6622 &warp_types, p_col, p_row,
6623#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6624 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
6625 } else {
6626#endif // CONFIG_HIGHBITDEPTH
6627 av1_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01006628 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
David Barkere64d51a2017-06-09 14:52:42 +01006629 &conv_params, mbmi->interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01006630#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6631 &warp_types, p_col, p_row, plane, !ref_idx,
6632#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6633 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
6634#if CONFIG_HIGHBITDEPTH
6635 }
6636#endif // CONFIG_HIGHBITDEPTH
6637
6638 if (scaled_ref_frame) {
6639 // Restore the prediction frame pointers to their unscaled versions.
6640 int i;
6641 for (i = 0; i < MAX_MB_PLANE; i++)
6642 xd->plane[i].pre[!ref_idx] = backup_yv12[i];
6643 }
6644}
6645
6646// Search for the best mv for one component of a compound,
6647// given that the other component is fixed.
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006648static void compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
6649 BLOCK_SIZE bsize, MV *this_mv,
6650 int mi_row, int mi_col,
6651 const uint8_t *second_pred,
6652 const uint8_t *mask, int mask_stride,
6653 int *rate_mv, int ref_idx) {
David Barker8dd9b572017-05-12 16:31:38 +01006654 const int pw = block_size_wide[bsize];
6655 const int ph = block_size_high[bsize];
6656 MACROBLOCKD *xd = &x->e_mbd;
6657 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07006658#if CONFIG_COMPOUND_SINGLEREF
6659 const int ref =
6660 has_second_ref(mbmi) ? mbmi->ref_frame[ref_idx] : mbmi->ref_frame[0];
6661#else
David Barker8dd9b572017-05-12 16:31:38 +01006662 const int ref = mbmi->ref_frame[ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006663#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006664 int_mv ref_mv = x->mbmi_ext->ref_mvs[ref][0];
David Barker8dd9b572017-05-12 16:31:38 +01006665 struct macroblockd_plane *const pd = &xd->plane[0];
6666
6667 struct buf_2d backup_yv12[MAX_MB_PLANE];
David Barker8dd9b572017-05-12 16:31:38 +01006668 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
6669 av1_get_scaled_ref_frame(cpi, ref);
6670
Ryan Lei1d1df182017-06-15 11:38:59 -07006671// Check that this is either an interinter or an interintra block
Zoe Liu85b66462017-04-20 14:28:19 -07006672#if CONFIG_COMPOUND_SINGLEREF
Ryan Lei1d1df182017-06-15 11:38:59 -07006673 assert(has_second_ref(mbmi) ||
Zoe Liu85b66462017-04-20 14:28:19 -07006674 // or a single ref comp pred mode
6675 is_inter_singleref_comp_mode(mbmi->mode) ||
David Barker8dd9b572017-05-12 16:31:38 +01006676 (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
Ryan Lei1d1df182017-06-15 11:38:59 -07006677#else
6678 assert(has_second_ref(mbmi) ||
6679 (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
6680#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006681
David Barker8dd9b572017-05-12 16:31:38 +01006682 if (scaled_ref_frame) {
6683 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006684 // Swap out the reference frame for a version that's been scaled to
6685 // match the resolution of the current frame, allowing the existing
6686 // motion search code to be used without additional modifications.
6687 for (i = 0; i < MAX_MB_PLANE; i++)
6688 backup_yv12[i] = xd->plane[i].pre[ref_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -07006689 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006690 }
6691
David Barker8dd9b572017-05-12 16:31:38 +01006692 struct buf_2d orig_yv12;
6693 int bestsme = INT_MAX;
6694 int sadpb = x->sadperbit16;
6695 MV *const best_mv = &x->best_mv.as_mv;
6696 int search_range = 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006697
David Barker8dd9b572017-05-12 16:31:38 +01006698 MvLimits tmp_mv_limits = x->mv_limits;
David Barker8dd9b572017-05-12 16:31:38 +01006699
6700 // Initialized here because of compiler problem in Visual Studio.
6701 if (ref_idx) {
David Barkerf19f35f2017-05-22 16:33:22 +01006702 orig_yv12 = pd->pre[0];
6703 pd->pre[0] = pd->pre[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006704 }
6705
David Barker8dd9b572017-05-12 16:31:38 +01006706 // Do compound motion search on the current reference frame.
6707 av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
6708
6709 // Use the mv result from the single mode as mv predictor.
David Barkerf19f35f2017-05-22 16:33:22 +01006710 *best_mv = *this_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006711
6712 best_mv->col >>= 3;
6713 best_mv->row >>= 3;
6714
Zoe Liu85b66462017-04-20 14:28:19 -07006715#if CONFIG_COMPOUND_SINGLEREF
6716 if (!has_second_ref(mbmi))
6717 av1_set_mvcost(x, ref, 0, mbmi->ref_mv_idx);
6718 else
6719#endif // CONFIG_COMPOUND_SINGLEREF
6720 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
David Barker8dd9b572017-05-12 16:31:38 +01006721
6722 // Small-range full-pixel motion search.
6723 bestsme = av1_refining_search_8p_c(x, sadpb, search_range,
6724 &cpi->fn_ptr[bsize], mask, mask_stride,
6725 ref_idx, &ref_mv.as_mv, second_pred);
6726 if (bestsme < INT_MAX) {
6727 if (mask)
6728 bestsme =
6729 av1_get_mvpred_mask_var(x, best_mv, &ref_mv.as_mv, second_pred, mask,
6730 mask_stride, ref_idx, &cpi->fn_ptr[bsize], 1);
6731 else
6732 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv.as_mv, second_pred,
6733 &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006734 }
6735
Alex Converse0fa0f422017-04-24 12:51:14 -07006736 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006737
6738 if (bestsme < INT_MAX) {
6739 int dis; /* TODO: use dis in distortion calculation later. */
David Barker8dd9b572017-05-12 16:31:38 +01006740 unsigned int sse;
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006741 bestsme = cpi->find_fractional_mv_step(
6742 x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
6743 &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
6744 x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask, mask_stride,
6745 ref_idx, pw, ph, cpi->sf.use_upsampled_references);
David Barker8dd9b572017-05-12 16:31:38 +01006746 }
6747
6748 // Restore the pointer to the first (possibly scaled) prediction buffer.
David Barkerf19f35f2017-05-22 16:33:22 +01006749 if (ref_idx) pd->pre[0] = orig_yv12;
David Barker8dd9b572017-05-12 16:31:38 +01006750
Yue Chenf03907a2017-05-31 12:04:04 -07006751 if (bestsme < INT_MAX) *this_mv = *best_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006752
6753 *rate_mv = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006754
6755 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01006756 // Restore the prediction frame pointers to their unscaled versions.
6757 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006758 for (i = 0; i < MAX_MB_PLANE; i++)
6759 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6760 }
David Barker8dd9b572017-05-12 16:31:38 +01006761
Zoe Liu85b66462017-04-20 14:28:19 -07006762#if CONFIG_COMPOUND_SINGLEREF
6763 if (!has_second_ref(mbmi))
6764 av1_set_mvcost(x, ref, 0, mbmi->ref_mv_idx);
6765 else
6766#endif // CONFIG_COMPOUND_SINGLEREF
6767 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
David Barkerf19f35f2017-05-22 16:33:22 +01006768 *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmvjointcost,
6769 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006770}
6771
David Barker8dd9b572017-05-12 16:31:38 +01006772// Wrapper for compound_single_motion_search, for the common case
6773// where the second prediction is also an inter mode.
6774static void compound_single_motion_search_interinter(
6775 const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *frame_mv,
Zoe Liu85b66462017-04-20 14:28:19 -07006776#if CONFIG_COMPOUND_SINGLEREF
6777 int_mv *frame_comp_mv,
6778#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006779 int mi_row, int mi_col, const uint8_t *mask, int mask_stride, int *rate_mv,
6780 const int block, int ref_idx) {
6781 MACROBLOCKD *xd = &x->e_mbd;
6782 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6783
Zoe Liu85b66462017-04-20 14:28:19 -07006784// This function should only ever be called for compound modes
6785#if CONFIG_COMPOUND_SINGLEREF
6786 int is_singleref_comp_mode =
6787 !has_second_ref(mbmi) && is_inter_singleref_comp_mode(mbmi->mode);
6788 assert(has_second_ref(mbmi) || is_singleref_comp_mode);
6789 if (is_singleref_comp_mode && ref_idx) assert(frame_comp_mv);
6790#else // !CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006791 assert(has_second_ref(mbmi));
Zoe Liu85b66462017-04-20 14:28:19 -07006792#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006793
6794// Prediction buffer from second frame.
6795#if CONFIG_HIGHBITDEPTH
David Barker8dd9b572017-05-12 16:31:38 +01006796 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
6797 uint8_t *second_pred;
6798 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6799 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
6800 else
6801 second_pred = (uint8_t *)second_pred_alloc_16;
6802#else
6803 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
6804#endif // CONFIG_HIGHBITDEPTH
6805
Zoe Liu85b66462017-04-20 14:28:19 -07006806#if CONFIG_COMPOUND_SINGLEREF
6807 MV *this_mv = has_second_ref(mbmi)
6808 ? &frame_mv[mbmi->ref_frame[ref_idx]].as_mv
6809 : (ref_idx ? &frame_comp_mv[mbmi->ref_frame[0]].as_mv
6810 : &frame_mv[mbmi->ref_frame[0]].as_mv);
6811 const MV *other_mv =
6812 has_second_ref(mbmi)
6813 ? &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv
6814 : (ref_idx ? &frame_mv[mbmi->ref_frame[0]].as_mv
6815 : &frame_comp_mv[mbmi->ref_frame[0]].as_mv);
6816#else // !CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006817 MV *this_mv = &frame_mv[mbmi->ref_frame[ref_idx]].as_mv;
6818 const MV *other_mv = &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv;
Zoe Liu85b66462017-04-20 14:28:19 -07006819#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006820
6821 build_second_inter_pred(cpi, x, bsize, other_mv, mi_row, mi_col, block,
David Barker8dd9b572017-05-12 16:31:38 +01006822 ref_idx, second_pred);
6823
David Barkerf19f35f2017-05-22 16:33:22 +01006824 compound_single_motion_search(cpi, x, bsize, this_mv, mi_row, mi_col,
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006825 second_pred, mask, mask_stride, rate_mv,
David Barkerf19f35f2017-05-22 16:33:22 +01006826 ref_idx);
David Barker8dd9b572017-05-12 16:31:38 +01006827}
6828
6829#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08006830static void do_masked_motion_search_indexed(
David Barkerc155e012017-05-11 13:54:54 +01006831 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006832 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006833 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006834 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6835 MACROBLOCKD *xd = &x->e_mbd;
6836 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6837 BLOCK_SIZE sb_type = mbmi->sb_type;
6838 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006839 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08006840
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006841 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006842
David Barker8dd9b572017-05-12 16:31:38 +01006843 int_mv frame_mv[TOTAL_REFS_PER_FRAME];
Zoe Liu85b66462017-04-20 14:28:19 -07006844#if CONFIG_COMPOUND_SINGLEREF
6845 int_mv frame_comp_mv[TOTAL_REFS_PER_FRAME];
6846#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006847 MV_REFERENCE_FRAME rf[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
6848 assert(bsize >= BLOCK_8X8 || CONFIG_CB4X4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006849
David Barker8dd9b572017-05-12 16:31:38 +01006850 frame_mv[rf[0]].as_int = cur_mv[0].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07006851#if CONFIG_COMPOUND_SINGLEREF
6852 if (!has_second_ref(mbmi))
6853 frame_comp_mv[rf[0]].as_int = cur_mv[1].as_int;
6854 else
6855#endif // CONFIG_COMPOUND_SINGLEREF
6856 frame_mv[rf[1]].as_int = cur_mv[1].as_int;
David Barkerf19f35f2017-05-22 16:33:22 +01006857 if (which == 0 || which == 1) {
Zoe Liu85b66462017-04-20 14:28:19 -07006858 compound_single_motion_search_interinter(
6859 cpi, x, bsize, frame_mv,
6860#if CONFIG_COMPOUND_SINGLEREF
6861 has_second_ref(mbmi) ? NULL : frame_comp_mv,
6862#endif // CONFIG_COMPOUND_SINGLEREF
6863 mi_row, mi_col, mask, mask_stride, rate_mv, 0, which);
David Barkerf19f35f2017-05-22 16:33:22 +01006864 } else if (which == 2) {
Zoe Liu85b66462017-04-20 14:28:19 -07006865 joint_motion_search(cpi, x, bsize, frame_mv,
6866#if CONFIG_COMPOUND_SINGLEREF
6867 has_second_ref(mbmi) ? NULL : frame_comp_mv,
6868#endif // CONFIG_COMPOUND_SINGLEREF
6869 mi_row, mi_col, NULL, mask, mask_stride, rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006870 }
David Barker8dd9b572017-05-12 16:31:38 +01006871 tmp_mv[0].as_int = frame_mv[rf[0]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07006872#if CONFIG_COMPOUND_SINGLEREF
6873 if (!has_second_ref(mbmi))
6874 tmp_mv[1].as_int = frame_comp_mv[rf[0]].as_int;
6875 else // comp ref
6876#endif // CONFIG_COMPOUND_SINGLEREF
6877 tmp_mv[1].as_int = frame_mv[rf[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006878}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006879#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006880#endif // CONFIG_EXT_INTER
6881
6882// In some situations we want to discount tha pparent cost of a new motion
6883// vector. Where there is a subtle motion field and especially where there is
6884// low spatial complexity then it can be hard to cover the cost of a new motion
6885// vector in a single block, even if that motion vector reduces distortion.
6886// However, once established that vector may be usable through the nearest and
6887// near mv modes to reduce distortion in subsequent blocks and also improve
6888// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006889static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006890 int_mv this_mv,
6891 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6892 int ref_frame) {
6893 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6894 (this_mv.as_int != 0) &&
6895 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6896 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6897 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6898 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6899}
6900
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006901#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6902#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006903
6904// TODO(jingning): this mv clamping function should be block size dependent.
6905static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6906 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6907 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6908 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6909 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6910}
6911
6912#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006913#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07006914static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006915 const BLOCK_SIZE bsize, const uint8_t *pred0,
6916 int stride0, const uint8_t *pred1, int stride1) {
6917 const struct macroblock_plane *const p = &x->plane[0];
6918 const uint8_t *src = p->src.buf;
6919 int src_stride = p->src.stride;
6920 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08006921 const int bw = block_size_wide[bsize];
6922 const int bh = block_size_high[bsize];
Yue Chenf03907a2017-05-31 12:04:04 -07006923 uint32_t esq[2][4];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006924 int64_t tl, br;
6925
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006926#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006927 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6928 pred0 = CONVERT_TO_BYTEPTR(pred0);
6929 pred1 = CONVERT_TO_BYTEPTR(pred1);
6930 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006931#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006932
Yue Chenf03907a2017-05-31 12:04:04 -07006933 cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6934 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2, stride0,
6935 &esq[0][1]);
6936 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6937 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6938 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6939 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6940 &esq[0][3]);
6941 cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6942 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2, stride1,
6943 &esq[1][1]);
6944 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6945 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6946 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6947 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6948 &esq[1][3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006949
6950 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6951 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6952 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6953 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6954 return (tl + br > 0);
6955}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006956#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006957#endif // CONFIG_EXT_INTER
6958
6959#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006960static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006961 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006962 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006963 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6964 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006965 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006966 const MACROBLOCKD *xd = &x->e_mbd;
6967 int bsl = mi_width_log2_lookup[bsize];
6968 int pred_filter_search =
6969 cpi->sf.cb_pred_filter_search
6970 ? (((mi_row + mi_col) >> bsl) +
6971 get_chessboard_index(cm->current_video_frame)) &
6972 0x1
6973 : 0;
6974 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6975 const int is_comp_pred = has_second_ref(mbmi);
6976 const int this_mode = mbmi->mode;
6977 int refs[2] = { mbmi->ref_frame[0],
6978 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006979 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006980 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006981 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6982 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6983
6984#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006985 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006986#else
6987 if ((this_mode != NEWMV) || (af == lf))
6988#endif // CONFIG_EXT_INTER
6989 best_filter = af;
6990 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006991 if (is_comp_pred) {
6992 if (cpi->sf.adaptive_mode_search) {
6993#if CONFIG_EXT_INTER
6994 switch (this_mode) {
6995 case NEAREST_NEARESTMV:
6996 if (single_filter[NEARESTMV][refs[0]] ==
6997 single_filter[NEARESTMV][refs[1]])
6998 best_filter = single_filter[NEARESTMV][refs[0]];
6999 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007000 case NEAR_NEARMV:
7001 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
7002 best_filter = single_filter[NEARMV][refs[0]];
7003 break;
7004 case ZERO_ZEROMV:
7005 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7006 best_filter = single_filter[ZEROMV][refs[0]];
7007 break;
7008 case NEW_NEWMV:
7009 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7010 best_filter = single_filter[NEWMV][refs[0]];
7011 break;
7012 case NEAREST_NEWMV:
7013 if (single_filter[NEARESTMV][refs[0]] ==
7014 single_filter[NEWMV][refs[1]])
7015 best_filter = single_filter[NEARESTMV][refs[0]];
7016 break;
7017 case NEAR_NEWMV:
7018 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7019 best_filter = single_filter[NEARMV][refs[0]];
7020 break;
7021 case NEW_NEARESTMV:
7022 if (single_filter[NEWMV][refs[0]] ==
7023 single_filter[NEARESTMV][refs[1]])
7024 best_filter = single_filter[NEWMV][refs[0]];
7025 break;
7026 case NEW_NEARMV:
7027 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7028 best_filter = single_filter[NEWMV][refs[0]];
7029 break;
7030 default:
7031 if (single_filter[this_mode][refs[0]] ==
7032 single_filter[this_mode][refs[1]])
7033 best_filter = single_filter[this_mode][refs[0]];
7034 break;
7035 }
7036#else
7037 if (single_filter[this_mode][refs[0]] ==
7038 single_filter[this_mode][refs[1]])
7039 best_filter = single_filter[this_mode][refs[0]];
7040#endif // CONFIG_EXT_INTER
7041 }
7042 }
Angie Chiang75c22092016-10-25 12:19:16 -07007043 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7044 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007045 }
7046 return best_filter;
7047}
Fergus Simpson4063a682017-02-28 16:52:22 -08007048#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007049
7050#if CONFIG_EXT_INTER
7051// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007052#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007053static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007054 const BLOCK_SIZE bsize, const uint8_t *const p0,
7055 const uint8_t *const p1, int *const best_wedge_sign,
7056 int *const best_wedge_index) {
7057 const MACROBLOCKD *const xd = &x->e_mbd;
7058 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007059 const int bw = block_size_wide[bsize];
7060 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007061 const int N = bw * bh;
7062 int rate;
7063 int64_t dist;
7064 int64_t rd, best_rd = INT64_MAX;
7065 int wedge_index;
7066 int wedge_sign;
7067 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7068 const uint8_t *mask;
7069 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007070#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007071 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7072 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7073#else
7074 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007075#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007076
7077 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7078 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7079 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7080 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7081
7082 int64_t sign_limit;
7083
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007084#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007085 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007086 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007087 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007088 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007089 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007090 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007091 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7092 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007093#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007094 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007095 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7096 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7097 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007098 }
7099
Yaowu Xuf883b422016-08-30 14:01:10 -07007100 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7101 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007102 (1 << WEDGE_WEIGHT_BITS) / 2;
7103
Jingning Han61418bb2017-01-23 17:12:48 -08007104 if (N < 64)
7105 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7106 else
7107 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007108
7109 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007110 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007111
7112 // TODO(jingning): Make sse2 functions support N = 16 case
7113 if (N < 64)
7114 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7115 else
7116 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007117
Yaowu Xuf883b422016-08-30 14:01:10 -07007118 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007119 if (N < 64)
7120 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7121 else
7122 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007123 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7124
7125 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007126 rd = RDCOST(x->rdmult, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007127
7128 if (rd < best_rd) {
7129 *best_wedge_index = wedge_index;
7130 *best_wedge_sign = wedge_sign;
7131 best_rd = rd;
7132 }
7133 }
7134
7135 return best_rd;
7136}
7137
7138// Choose the best wedge index the specified sign
7139static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007140 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007141 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7142 const int wedge_sign, int *const best_wedge_index) {
7143 const MACROBLOCKD *const xd = &x->e_mbd;
7144 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007145 const int bw = block_size_wide[bsize];
7146 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007147 const int N = bw * bh;
7148 int rate;
7149 int64_t dist;
7150 int64_t rd, best_rd = INT64_MAX;
7151 int wedge_index;
7152 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7153 const uint8_t *mask;
7154 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007155#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007156 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7157 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7158#else
7159 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007160#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007161
7162 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7163 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7164
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007165#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007166 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007167 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007168 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007169 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007170 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7171 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007172#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007173 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007174 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7175 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007176 }
7177
7178 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007179 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007180 if (N < 64)
7181 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7182 else
7183 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007184 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7185
7186 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007187 rd = RDCOST(x->rdmult, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007188
7189 if (rd < best_rd) {
7190 *best_wedge_index = wedge_index;
7191 best_rd = rd;
7192 }
7193 }
7194
7195 return best_rd;
7196}
7197
Yaowu Xuf883b422016-08-30 14:01:10 -07007198static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007199 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007200 const BLOCK_SIZE bsize,
7201 const uint8_t *const p0,
7202 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007203 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007204 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007205 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007206
7207 int64_t rd;
7208 int wedge_index = -1;
7209 int wedge_sign = 0;
7210
Sarah Parker42d96102017-01-31 21:05:27 -08007211 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007212 assert(cpi->common.allow_masked_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007213
7214 if (cpi->sf.fast_wedge_sign_estimate) {
7215 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7216 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7217 } else {
7218 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7219 }
7220
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007221 mbmi->wedge_sign = wedge_sign;
7222 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007223 return rd;
7224}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007225#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007226
Sarah Parker569edda2016-12-14 14:57:38 -08007227#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07007228static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007229 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07007230 const uint8_t *const p0,
7231 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007232 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08007233 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7234 const struct buf_2d *const src = &x->plane[0].src;
7235 const int bw = block_size_wide[bsize];
7236 const int bh = block_size_high[bsize];
7237 const int N = bw * bh;
7238 int rate;
7239 uint64_t sse;
7240 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07007241 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007242 SEG_MASK_TYPE cur_mask_type;
7243 int64_t best_rd = INT64_MAX;
7244 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007245#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007246 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7247 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7248#else
7249 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007250#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007251 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7252 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7253 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7254
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007255#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007256 if (hbd) {
7257 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7258 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7259 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7260 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7261 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7262 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7263 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007264#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007265 {
7266 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7267 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7268 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7269 }
7270
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007271 // try each mask type and its inverse
7272 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007273// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007274#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007275 if (hbd)
7276 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007277 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007278 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7279 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007280#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007281 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
7282 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007283
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007284 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007285 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007286 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007287
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007288 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007289 rd0 = RDCOST(x->rdmult, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007290
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007291 if (rd0 < best_rd) {
7292 best_mask_type = cur_mask_type;
7293 best_rd = rd0;
7294 }
7295 }
Sarah Parker569edda2016-12-14 14:57:38 -08007296
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007297 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007298 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007299#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007300 if (hbd)
7301 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007302 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007303 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7304 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007305#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007306 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
7307 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007308
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007309 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007310}
7311#endif // CONFIG_COMPOUND_SEGMENT
7312
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007313#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07007314static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007315 const MACROBLOCK *const x,
7316 const BLOCK_SIZE bsize,
7317 const uint8_t *const p0,
7318 const uint8_t *const p1) {
7319 const MACROBLOCKD *const xd = &x->e_mbd;
7320 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7321
7322 int64_t rd;
7323 int wedge_index = -1;
7324
7325 assert(is_interintra_wedge_used(bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007326 assert(cpi->common.allow_interintra_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007327
7328 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7329
7330 mbmi->interintra_wedge_sign = 0;
7331 mbmi->interintra_wedge_index = wedge_index;
7332 return rd;
7333}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007334#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08007335
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007336#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007337static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07007338 const BLOCK_SIZE bsize,
7339 const uint8_t *const p0,
7340 const uint8_t *const p1) {
7341 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007342 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07007343 switch (compound_type) {
7344#if CONFIG_WEDGE
7345 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
7346#endif // CONFIG_WEDGE
7347#if CONFIG_COMPOUND_SEGMENT
7348 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
7349#endif // CONFIG_COMPOUND_SEGMENT
7350 default: assert(0); return 0;
7351 }
7352}
7353
David Barkerc155e012017-05-11 13:54:54 +01007354static int interinter_compound_motion_search(
7355 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7356 const BLOCK_SIZE bsize, const int this_mode, int mi_row, int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007357 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007358 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7359 int_mv tmp_mv[2];
David Barkerc155e012017-05-11 13:54:54 +01007360 int tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007361 const INTERINTER_COMPOUND_DATA compound_data = {
7362#if CONFIG_WEDGE
7363 mbmi->wedge_index,
7364 mbmi->wedge_sign,
7365#endif // CONFIG_WEDGE
7366#if CONFIG_COMPOUND_SEGMENT
7367 mbmi->mask_type,
7368 xd->seg_mask,
7369#endif // CONFIG_COMPOUND_SEGMENT
7370 mbmi->interinter_compound_type
7371 };
Zoe Liu85b66462017-04-20 14:28:19 -07007372#if CONFIG_COMPOUND_SINGLEREF
7373 // NOTE: Mode is needed to identify the compound mode prediction, regardless
7374 // of comp refs or single ref.
7375 mbmi->mode = this_mode;
7376#endif // CONFIG_COMPOUND_SINGLEREF
7377
7378 if (this_mode == NEW_NEWMV
7379#if CONFIG_COMPOUND_SINGLEREF
7380 || this_mode == SR_NEW_NEWMV
7381#endif // CONFIG_COMPOUND_SINGLEREF
7382 ) {
David Barkerc155e012017-05-11 13:54:54 +01007383 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7384 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007385 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7386 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7387 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
David Barkerc155e012017-05-11 13:54:54 +01007388 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7389 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007390 mbmi->mv[0].as_int = tmp_mv[0].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007391 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV
7392#if CONFIG_COMPOUND_SINGLEREF
7393 // || this_mode == SR_NEAREST_NEWMV
7394 || this_mode == SR_NEAR_NEWMV || this_mode == SR_ZERO_NEWMV
7395#endif // CONFIG_COMPOUND_SINGLEREF
7396 ) {
David Barkerc155e012017-05-11 13:54:54 +01007397 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7398 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007399 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7400 }
7401 return tmp_rate_mv;
7402}
7403
Sarah Parkerddcea392017-04-25 15:57:22 -07007404static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007405 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7406 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7407 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7408 int *strides, int mi_row, int mi_col) {
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007409 const AV1_COMMON *const cm = &cpi->common;
Sarah Parker569edda2016-12-14 14:57:38 -08007410 MACROBLOCKD *xd = &x->e_mbd;
7411 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7412 int rate_sum;
7413 int64_t dist_sum;
7414 int64_t best_rd_cur = INT64_MAX;
7415 int64_t rd = INT64_MAX;
7416 int tmp_skip_txfm_sb;
7417 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007418 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08007419
Sarah Parkerddcea392017-04-25 15:57:22 -07007420 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Urvang Joshi70006e42017-06-14 16:08:55 -07007421 best_rd_cur += RDCOST(x->rdmult, rs2 + rate_mv, 0);
Sarah Parker569edda2016-12-14 14:57:38 -08007422
Sarah Parker2e604882017-01-17 17:31:25 -08007423 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07007424 use_masked_motion_search(compound_type)) {
David Barkerc155e012017-05-11 13:54:54 +01007425 *out_rate_mv = interinter_compound_motion_search(cpi, x, cur_mv, bsize,
7426 this_mode, mi_row, mi_col);
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007427 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007428 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7429 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07007430 rd = RDCOST(x->rdmult, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007431 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007432 mbmi->mv[0].as_int = cur_mv[0].as_int;
7433 mbmi->mv[1].as_int = cur_mv[1].as_int;
7434 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007435 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7436#if CONFIG_SUPERTX
7437 0, 0,
7438#endif // CONFIG_SUPERTX
7439 preds0, strides, preds1,
7440 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007441 }
7442 av1_subtract_plane(x, bsize, 0);
7443 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7444 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7445 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07007446 rd = RDCOST(x->rdmult, rs2 + *out_rate_mv + rate_sum, dist_sum);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007447 best_rd_cur = rd;
7448
7449 } else {
David Barker426a9972017-01-27 11:03:11 +00007450 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7451#if CONFIG_SUPERTX
7452 0, 0,
7453#endif // CONFIG_SUPERTX
7454 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007455 av1_subtract_plane(x, bsize, 0);
7456 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7457 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7458 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07007459 rd = RDCOST(x->rdmult, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007460 best_rd_cur = rd;
7461 }
7462 return best_rd_cur;
7463}
Sarah Parkerddcea392017-04-25 15:57:22 -07007464#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007465#endif // CONFIG_EXT_INTER
7466
Fergus Simpson073c6f32017-02-17 12:13:48 -08007467typedef struct {
7468#if CONFIG_MOTION_VAR
7469 // Inter prediction buffers and respective strides
7470 uint8_t *above_pred_buf[MAX_MB_PLANE];
7471 int above_pred_stride[MAX_MB_PLANE];
7472 uint8_t *left_pred_buf[MAX_MB_PLANE];
7473 int left_pred_stride[MAX_MB_PLANE];
7474#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007475 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007476#if CONFIG_EXT_INTER
7477 // Pointer to array of motion vectors to use for each ref and their rates
7478 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007479 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007480 // Pointer to array of predicted rate-distortion
7481 // Should point to first of 2 arrays in 2D array
7482 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007483#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007484 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007485} HandleInterModeArgs;
7486
Fergus Simpson45509632017-02-22 15:30:50 -08007487static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7488 const BLOCK_SIZE bsize,
7489 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
Zoe Liu85b66462017-04-20 14:28:19 -07007490#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7491 int_mv (*const mode_comp_mv)[TOTAL_REFS_PER_FRAME],
7492#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007493 const int mi_row, const int mi_col,
7494 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007495 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007496 const MACROBLOCKD *const xd = &x->e_mbd;
7497 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7498 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7499 const int is_comp_pred = has_second_ref(mbmi);
7500 const PREDICTION_MODE this_mode = mbmi->mode;
7501#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007502 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7503#endif // CONFIG_EXT_INTER
7504 int_mv *const frame_mv = mode_mv[this_mode];
Zoe Liu85b66462017-04-20 14:28:19 -07007505#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7506 int_mv *const frame_comp_mv = mode_comp_mv[this_mode];
7507#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007508 const int refs[2] = { mbmi->ref_frame[0],
7509 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7510 int i;
7511
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007512 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007513
7514 if (is_comp_pred) {
7515#if CONFIG_EXT_INTER
7516 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007517 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007518 }
7519
7520 if (this_mode == NEW_NEWMV) {
7521 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7522 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7523
7524 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu85b66462017-04-20 14:28:19 -07007525 joint_motion_search(cpi, x, bsize, frame_mv,
7526#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7527 NULL, // int_mv *frame_comp_mv
7528#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7529 mi_row, mi_col, NULL, NULL, 0, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007530 } else {
7531 *rate_mv = 0;
7532 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007533 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007534 *rate_mv += av1_mv_bit_cost(
7535 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7536 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7537 }
7538 }
7539 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7540 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01007541 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7542 frame_mv[refs[0]].as_int =
7543 mode_mv[compound_ref0_mode(this_mode)][refs[0]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007544 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7545#if CONFIG_COMPOUND_SINGLEREF
7546 NULL,
7547#endif // CONFIG_COMPOUND_SINGLEREF
7548 mi_row, mi_col, NULL, 0,
7549 rate_mv, 0, 1);
David Barker8dd9b572017-05-12 16:31:38 +01007550 } else {
7551 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
7552 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
7553 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
7554 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7555 }
Fergus Simpson45509632017-02-22 15:30:50 -08007556 } else {
David Barkercb03dc32017-04-07 13:05:09 +01007557 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08007558 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01007559 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7560 frame_mv[refs[1]].as_int =
7561 mode_mv[compound_ref1_mode(this_mode)][refs[1]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007562 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7563#if CONFIG_COMPOUND_SINGLEREF
7564 NULL,
7565#endif // CONFIG_COMPOUND_SINGLEREF
7566 mi_row, mi_col, NULL, 0,
7567 rate_mv, 0, 0);
David Barker8dd9b572017-05-12 16:31:38 +01007568 } else {
7569 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
7570 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7571 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7572 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7573 }
Fergus Simpson45509632017-02-22 15:30:50 -08007574 }
Zoe Liu85b66462017-04-20 14:28:19 -07007575#else // !CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007576 // Initialize mv using single prediction mode result.
7577 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7578 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7579
7580 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07007581 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007582 } else {
7583 *rate_mv = 0;
7584 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007585 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007586 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
7587 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7588 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7589 }
7590 }
7591#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07007592#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7593 } else if (is_inter_singleref_comp_mode(this_mode)) {
7594 // Single ref comp mode
7595 const int mode0 = compound_ref0_mode(this_mode);
7596
7597 single_newmv[refs[0]].as_int = args->single_newmv[refs[0]].as_int;
7598 frame_mv[refs[0]].as_int = (mode0 == NEWMV)
7599 ? single_newmv[refs[0]].as_int
7600 : mode_mv[mode0][refs[0]].as_int;
7601 assert(compound_ref1_mode(this_mode) == NEWMV);
7602 frame_comp_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7603
7604 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7605 if (this_mode == SR_NEW_NEWMV) {
7606 joint_motion_search(cpi, x, bsize, frame_mv, frame_comp_mv, mi_row,
7607 mi_col, NULL, NULL, 0, rate_mv, 0);
7608 } else {
7609 assert( // this_mode == SR_NEAREST_NEWMV ||
7610 this_mode == SR_NEAR_NEWMV || this_mode == SR_ZERO_NEWMV);
7611 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7612 frame_comp_mv, mi_row, mi_col,
7613 NULL, 0, rate_mv, 0, 1);
7614 }
7615 } else {
7616 *rate_mv = 0;
7617 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
7618 if (mode0 == NEWMV)
7619 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7620 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7621 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7622 *rate_mv += av1_mv_bit_cost(&frame_comp_mv[refs[0]].as_mv,
7623 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7624 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7625 }
7626#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007627 } else {
7628#if CONFIG_EXT_INTER
7629 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007630 x->best_mv = args->single_newmv[refs[0]];
7631 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08007632 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007633 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
7634 args->single_newmv[refs[0]] = x->best_mv;
7635 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08007636 }
7637#else
7638 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
7639 single_newmv[refs[0]] = x->best_mv;
7640#endif // CONFIG_EXT_INTER
7641
7642 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7643
7644 frame_mv[refs[0]] = x->best_mv;
7645 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7646
7647 // Estimate the rate implications of a new mv but discount this
7648 // under certain circumstances where we want to help initiate a weak
7649 // motion field, where the distortion gain for a single block may not
7650 // be enough to overcome the cost of a new mv.
7651 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
7652 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
7653 }
7654 }
7655
7656 return 0;
7657}
7658
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007659int64_t interpolation_filter_search(
7660 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
7661 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
7662 BUFFER_SET *const orig_dst,
7663 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
7664 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
7665 int64_t *const skip_sse_sb) {
7666 const AV1_COMMON *cm = &cpi->common;
7667 MACROBLOCKD *const xd = &x->e_mbd;
7668 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7669 int i;
7670 int tmp_rate;
7671 int64_t tmp_dist;
7672
7673 (void)single_filter;
7674
7675 InterpFilter assign_filter = SWITCHABLE;
7676
7677 if (cm->interp_filter == SWITCHABLE) {
7678#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007679 assign_filter = av1_is_interp_needed(xd)
7680 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
7681 single_filter)
7682 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007683#endif // !CONFIG_DUAL_FILTER
7684 } else {
7685 assign_filter = cm->interp_filter;
7686 }
7687
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007688 set_default_interp_filters(mbmi, assign_filter);
7689
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007690 *switchable_rate = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007691 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007692 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
7693 skip_txfm_sb, skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07007694 *rd = RDCOST(x->rdmult, *switchable_rate + tmp_rate, tmp_dist);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007695
7696 if (assign_filter == SWITCHABLE) {
7697 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007698 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007699#if CONFIG_DUAL_FILTER
7700 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7701#else
7702 const int filter_set_size = SWITCHABLE_FILTERS;
7703#endif // CONFIG_DUAL_FILTER
7704 int best_in_temp = 0;
7705#if CONFIG_DUAL_FILTER
7706 InterpFilter best_filter[4];
7707 av1_copy(best_filter, mbmi->interp_filter);
7708#else
7709 InterpFilter best_filter = mbmi->interp_filter;
7710#endif // CONFIG_DUAL_FILTER
7711 restore_dst_buf(xd, *tmp_dst);
7712 // EIGHTTAP_REGULAR mode is calculated beforehand
7713 for (i = 1; i < filter_set_size; ++i) {
7714 int tmp_skip_sb = 0;
7715 int64_t tmp_skip_sse = INT64_MAX;
7716 int tmp_rs;
7717 int64_t tmp_rd;
7718#if CONFIG_DUAL_FILTER
7719 mbmi->interp_filter[0] = filter_sets[i][0];
7720 mbmi->interp_filter[1] = filter_sets[i][1];
7721 mbmi->interp_filter[2] = filter_sets[i][0];
7722 mbmi->interp_filter[3] = filter_sets[i][1];
7723#else
7724 mbmi->interp_filter = (InterpFilter)i;
7725#endif // CONFIG_DUAL_FILTER
7726 tmp_rs = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007727 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007728 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7729 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
Urvang Joshi70006e42017-06-14 16:08:55 -07007730 tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007731
7732 if (tmp_rd < *rd) {
7733 *rd = tmp_rd;
7734 *switchable_rate = av1_get_switchable_rate(cpi, xd);
7735#if CONFIG_DUAL_FILTER
7736 av1_copy(best_filter, mbmi->interp_filter);
7737#else
7738 best_filter = mbmi->interp_filter;
7739#endif // CONFIG_DUAL_FILTER
7740 *skip_txfm_sb = tmp_skip_sb;
7741 *skip_sse_sb = tmp_skip_sse;
7742 best_in_temp = !best_in_temp;
7743 if (best_in_temp) {
7744 restore_dst_buf(xd, *orig_dst);
7745 } else {
7746 restore_dst_buf(xd, *tmp_dst);
7747 }
7748 }
7749 }
7750 if (best_in_temp) {
7751 restore_dst_buf(xd, *tmp_dst);
7752 } else {
7753 restore_dst_buf(xd, *orig_dst);
7754 }
7755#if CONFIG_DUAL_FILTER
7756 av1_copy(mbmi->interp_filter, best_filter);
7757#else
7758 mbmi->interp_filter = best_filter;
7759#endif // CONFIG_DUAL_FILTER
7760 } else {
7761#if CONFIG_DUAL_FILTER
7762 for (i = 0; i < 4; ++i)
7763 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
7764#else
7765 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
7766#endif // CONFIG_DUAL_FILTER
7767 }
7768 }
7769
7770 return 0;
7771}
7772
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007773// TODO(afergs): Refactor the MBMI references in here - there's four
7774// TODO(afergs): Refactor optional args - add them to a struct or remove
7775static int64_t motion_mode_rd(
7776 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
7777 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
7778 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
7779 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
7780 const int *refs, int rate_mv,
7781#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07007782 // only used when WARPED_MOTION is on?
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007783 int_mv *const single_newmv,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007784#if CONFIG_EXT_INTER
Yunqing Wang562a3932017-06-20 12:20:45 -07007785 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi, int rate_mv_bmc,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007786#endif // CONFIG_EXT_INTER
7787#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7788 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
7789 const AV1_COMMON *const cm = &cpi->common;
7790 MACROBLOCKD *xd = &x->e_mbd;
7791 MODE_INFO *mi = xd->mi[0];
7792 MB_MODE_INFO *mbmi = &mi->mbmi;
7793 const int is_comp_pred = has_second_ref(mbmi);
7794 const PREDICTION_MODE this_mode = mbmi->mode;
7795
7796 (void)mode_mv;
7797 (void)mi_row;
7798 (void)mi_col;
7799 (void)args;
7800 (void)refs;
7801 (void)rate_mv;
7802 (void)is_comp_pred;
7803 (void)this_mode;
7804
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007805#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7806 MOTION_MODE motion_mode, last_motion_mode_allowed;
7807 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7808 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
7809 MB_MODE_INFO base_mbmi, best_mbmi;
7810#if CONFIG_VAR_TX
7811 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7812#endif // CONFIG_VAR_TX
7813#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7814
7815#if CONFIG_WARPED_MOTION
7816 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
7817#endif // CONFIG_WARPED_MOTION
7818
7819#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7820 av1_invalid_rd_stats(&best_rd_stats);
7821#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7822
7823 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
7824#if CONFIG_WARPED_MOTION
7825 aom_clear_system_state();
7826 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
7827#if CONFIG_EXT_INTER
7828 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
7829#endif // CONFIG_EXT_INTER
7830#endif // CONFIG_WARPED_MOTION
7831#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7832 rate2_nocoeff = rd_stats->rate;
7833 last_motion_mode_allowed = motion_mode_allowed(
7834#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7835 0, xd->global_motion,
7836#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7837 mi);
7838 base_mbmi = *mbmi;
7839#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7840
7841#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7842 int64_t best_rd = INT64_MAX;
7843 for (motion_mode = SIMPLE_TRANSLATION;
7844 motion_mode <= last_motion_mode_allowed; motion_mode++) {
7845 int64_t tmp_rd = INT64_MAX;
7846 int tmp_rate;
7847 int64_t tmp_dist;
7848#if CONFIG_EXT_INTER
7849 int tmp_rate2 =
7850 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
7851#else
7852 int tmp_rate2 = rate2_nocoeff;
7853#endif // CONFIG_EXT_INTER
7854
7855 *mbmi = base_mbmi;
7856 mbmi->motion_mode = motion_mode;
7857#if CONFIG_MOTION_VAR
7858 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007859#if CONFIG_EXT_INTER
7860 *mbmi = *best_bmc_mbmi;
7861 mbmi->motion_mode = OBMC_CAUSAL;
7862#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07007863 if (!is_comp_pred &&
7864#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7865 !is_inter_singleref_comp_mode(this_mode) &&
7866#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7867 have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007868 int tmp_rate_mv = 0;
7869
7870 single_motion_search(cpi, x, bsize, mi_row, mi_col,
7871#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07007872 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007873#endif // CONFIG_EXT_INTER
7874 &tmp_rate_mv);
7875 mbmi->mv[0].as_int = x->best_mv.as_int;
7876 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7877 refs[0])) {
7878 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7879 }
7880#if CONFIG_EXT_INTER
7881 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7882#else
7883 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7884#endif // CONFIG_EXT_INTER
7885#if CONFIG_DUAL_FILTER
7886 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7887 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7888 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7889 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7890#endif // CONFIG_DUAL_FILTER
Jingning Hanc44009c2017-05-06 11:36:49 -07007891 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007892#if CONFIG_EXT_INTER
7893 } else {
Jingning Hanc44009c2017-05-06 11:36:49 -07007894 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007895#endif // CONFIG_EXT_INTER
7896 }
7897 av1_build_obmc_inter_prediction(
7898 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
7899 args->left_pred_buf, args->left_pred_stride);
7900 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7901 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7902 }
7903#endif // CONFIG_MOTION_VAR
7904
7905#if CONFIG_WARPED_MOTION
7906 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007907#if CONFIG_EXT_INTER
7908 *mbmi = *best_bmc_mbmi;
7909 mbmi->motion_mode = WARPED_CAUSAL;
7910#endif // CONFIG_EXT_INTER
7911 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
7912#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07007913 for (int dir = 0; dir < 4; ++dir)
7914 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
7915 ? EIGHTTAP_REGULAR
7916 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007917#else
7918 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
7919 : cm->interp_filter;
7920#endif // CONFIG_DUAL_FILTER
7921
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007922 if (!find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
7923 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
7924 &mbmi->wm_params[0], mi_row, mi_col)) {
7925 // Refine MV for NEWMV mode
7926 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
7927 int tmp_rate_mv = 0;
7928 const int_mv mv0 = mbmi->mv[0];
7929 WarpedMotionParams wm_params0 = mbmi->wm_params[0];
7930
7931 // Refine MV in a small range.
7932 av1_refine_warped_mv(cpi, x, bsize, mi_row, mi_col, pts, pts_inref);
7933
7934 // Keep the refined MV and WM parameters.
7935 if (mv0.as_int != mbmi->mv[0].as_int) {
7936 const int ref = refs[0];
7937 const MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7938
7939 tmp_rate_mv =
7940 av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv, x->nmvjointcost,
7941 x->mvcost, MV_COST_WEIGHT);
7942
7943 if (cpi->sf.adaptive_motion_search)
7944 x->pred_mv[ref] = mbmi->mv[0].as_mv;
7945
7946 single_newmv[ref] = mbmi->mv[0];
7947
7948 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7949 refs[0])) {
7950 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7951 }
7952#if CONFIG_EXT_INTER
7953 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7954#else
7955 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7956#endif // CONFIG_EXT_INTER
7957#if CONFIG_DUAL_FILTER
7958 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7959 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7960 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7961 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7962#endif // CONFIG_DUAL_FILTER
7963 } else {
7964 // Restore the old MV and WM parameters.
7965 mbmi->mv[0] = mv0;
7966 mbmi->wm_params[0] = wm_params0;
7967 }
7968 }
7969
Jingning Hanc44009c2017-05-06 11:36:49 -07007970 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007971 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7972 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7973 } else {
7974 continue;
7975 }
7976 }
7977#endif // CONFIG_WARPED_MOTION
7978 x->skip = 0;
7979
7980 rd_stats->dist = 0;
7981 rd_stats->sse = 0;
7982 rd_stats->skip = 1;
7983 rd_stats->rate = tmp_rate2;
7984 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
7985#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7986 if (last_motion_mode_allowed == WARPED_CAUSAL)
7987#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7988 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7989#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7990 else
7991 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
7992#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7993 }
7994#if CONFIG_WARPED_MOTION
7995 if (mbmi->motion_mode == WARPED_CAUSAL) {
7996 rd_stats->rate -= rs;
7997 }
7998#endif // CONFIG_WARPED_MOTION
7999#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8000 if (!*skip_txfm_sb) {
8001 int64_t rdcosty = INT64_MAX;
8002 int is_cost_valid_uv = 0;
8003
8004 // cost and distortion
8005 av1_subtract_plane(x, bsize, 0);
8006#if CONFIG_VAR_TX
8007 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8008 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8009 } else {
8010 int idx, idy;
8011 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8012 for (idy = 0; idy < xd->n8_h; ++idy)
8013 for (idx = 0; idx < xd->n8_w; ++idx)
8014 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8015 memset(x->blk_skip[0], rd_stats_y->skip,
8016 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8017 }
8018#else
8019 /* clang-format off */
8020 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8021/* clang-format on */
8022#endif // CONFIG_VAR_TX
8023
8024 if (rd_stats_y->rate == INT_MAX) {
8025 av1_invalid_rd_stats(rd_stats);
8026#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8027 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8028 continue;
8029 } else {
8030#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8031 restore_dst_buf(xd, *orig_dst);
8032 return INT64_MAX;
8033#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8034 }
8035#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8036 }
8037
8038 av1_merge_rd_stats(rd_stats, rd_stats_y);
8039
Urvang Joshi70006e42017-06-14 16:08:55 -07008040 rdcosty = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
8041 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, 0, rd_stats->sse));
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008042/* clang-format off */
8043#if CONFIG_VAR_TX
8044 is_cost_valid_uv =
8045 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8046#else
8047 is_cost_valid_uv =
8048 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8049#endif // CONFIG_VAR_TX
8050 if (!is_cost_valid_uv) {
8051#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8052 continue;
8053#else
8054 restore_dst_buf(xd, *orig_dst);
8055 return INT64_MAX;
8056#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8057 }
8058 /* clang-format on */
8059 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8060#if CONFIG_RD_DEBUG
8061 // record transform block coefficient cost
8062 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8063 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8064 // here because we already collect the coefficient cost. Move this part to
8065 // other place when we need to compare non-coefficient cost.
8066 mbmi->rd_stats = *rd_stats;
8067#endif // CONFIG_RD_DEBUG
8068#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8069 if (rd_stats->skip) {
8070 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8071 rd_stats_y->rate = 0;
8072 rd_stats_uv->rate = 0;
8073 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8074 mbmi->skip = 0;
8075 // here mbmi->skip temporarily plays a role as what this_skip2 does
8076 } else if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshi70006e42017-06-14 16:08:55 -07008077 (RDCOST(x->rdmult,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008078 rd_stats_y->rate + rd_stats_uv->rate +
8079 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8080 rd_stats->dist) >=
Urvang Joshi70006e42017-06-14 16:08:55 -07008081 RDCOST(x->rdmult, av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008082 rd_stats->sse))) {
8083 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8084 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8085 rd_stats->dist = rd_stats->sse;
8086 rd_stats_y->rate = 0;
8087 rd_stats_uv->rate = 0;
8088 mbmi->skip = 1;
8089 } else {
8090 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8091 mbmi->skip = 0;
8092 }
8093 *disable_skip = 0;
8094#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8095 } else {
8096 x->skip = 1;
8097 *disable_skip = 1;
8098 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8099
8100// The cost of skip bit needs to be added.
8101#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8102 mbmi->skip = 0;
8103#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8104 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8105
8106 rd_stats->dist = *skip_sse_sb;
8107 rd_stats->sse = *skip_sse_sb;
8108 rd_stats_y->rate = 0;
8109 rd_stats_uv->rate = 0;
8110 rd_stats->skip = 1;
8111 }
8112
8113#if CONFIG_GLOBAL_MOTION
8114 if (this_mode == ZEROMV
8115#if CONFIG_EXT_INTER
8116 || this_mode == ZERO_ZEROMV
8117#endif // CONFIG_EXT_INTER
8118 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008119 if (is_nontrans_global_motion(xd)) {
8120 rd_stats->rate -= rs;
8121#if CONFIG_DUAL_FILTER
8122 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8123 ? EIGHTTAP_REGULAR
8124 : cm->interp_filter;
8125 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8126 ? EIGHTTAP_REGULAR
8127 : cm->interp_filter;
8128#else
8129 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8130 ? EIGHTTAP_REGULAR
8131 : cm->interp_filter;
8132#endif // CONFIG_DUAL_FILTER
8133 }
8134 }
8135#endif // CONFIG_GLOBAL_MOTION
8136
8137#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Urvang Joshi70006e42017-06-14 16:08:55 -07008138 tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008139 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8140 best_mbmi = *mbmi;
8141 best_rd = tmp_rd;
8142 best_rd_stats = *rd_stats;
8143 best_rd_stats_y = *rd_stats_y;
8144 best_rd_stats_uv = *rd_stats_uv;
8145#if CONFIG_VAR_TX
8146 for (int i = 0; i < MAX_MB_PLANE; ++i)
8147 memcpy(best_blk_skip[i], x->blk_skip[i],
8148 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8149#endif // CONFIG_VAR_TX
8150 best_xskip = x->skip;
8151 best_disable_skip = *disable_skip;
8152 }
8153 }
8154
8155 if (best_rd == INT64_MAX) {
8156 av1_invalid_rd_stats(rd_stats);
8157 restore_dst_buf(xd, *orig_dst);
8158 return INT64_MAX;
8159 }
8160 *mbmi = best_mbmi;
8161 *rd_stats = best_rd_stats;
8162 *rd_stats_y = best_rd_stats_y;
8163 *rd_stats_uv = best_rd_stats_uv;
8164#if CONFIG_VAR_TX
8165 for (int i = 0; i < MAX_MB_PLANE; ++i)
8166 memcpy(x->blk_skip[i], best_blk_skip[i],
8167 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8168#endif // CONFIG_VAR_TX
8169 x->skip = best_xskip;
8170 *disable_skip = best_disable_skip;
8171#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8172
8173 restore_dst_buf(xd, *orig_dst);
8174 return 0;
8175}
8176
Zoe Liu85b66462017-04-20 14:28:19 -07008177static int64_t handle_inter_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
8178 BLOCK_SIZE bsize, RD_STATS *rd_stats,
8179 RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8180 int *disable_skip,
8181 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
8182#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8183 int_mv (*mode_comp_mv)[TOTAL_REFS_PER_FRAME],
8184#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8185 int mi_row, int mi_col,
8186 HandleInterModeArgs *args,
8187 const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008188 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008189 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008190 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008191 MODE_INFO *mi = xd->mi[0];
8192 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008193 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8194 const int is_comp_pred = has_second_ref(mbmi);
8195 const int this_mode = mbmi->mode;
Zoe Liu85b66462017-04-20 14:28:19 -07008196#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8197 const int is_singleref_comp_mode = is_inter_singleref_comp_mode(this_mode);
8198#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008199 int_mv *frame_mv = mode_mv[this_mode];
Zoe Liu85b66462017-04-20 14:28:19 -07008200#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8201 // The comp mv for the compound mode in single ref
8202 int_mv *frame_comp_mv = mode_comp_mv[this_mode];
8203#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008204 int i;
8205 int refs[2] = { mbmi->ref_frame[0],
8206 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8207 int_mv cur_mv[2];
8208 int rate_mv = 0;
8209#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008210 int pred_exists = 1;
Yue Chen5e606542017-05-24 17:03:17 -07008211#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Jingning Hanae5cfde2016-11-30 12:01:44 -08008212 const int bw = block_size_wide[bsize];
Yue Chen5e606542017-05-24 17:03:17 -07008213#endif // ONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008214 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008215#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008216 const unsigned int *const interintra_mode_cost =
8217 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008218#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008219 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07008220 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008221#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008222 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008223#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008224#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008225 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8226#else
8227 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008228#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008229 uint8_t *tmp_buf;
8230
Yue Chencb60b182016-10-13 15:18:22 -07008231#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008232#if CONFIG_EXT_INTER
8233 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008234 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008235 int rate_mv_bmc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008236#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008237#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008238 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008239 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008240 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008241
8242 int skip_txfm_sb = 0;
8243 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008244 int16_t mode_ctx;
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07008245#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
8246 // dummy fillers
8247 mbmi->ncobmc_mode[0] = NO_OVERLAP;
8248 mbmi->ncobmc_mode[1] = NO_OVERLAP;
8249#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008250
8251#if CONFIG_EXT_INTER
Yue Chen5e606542017-05-24 17:03:17 -07008252#if CONFIG_INTERINTRA
8253 int compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008254 mbmi->use_wedge_interintra = 0;
Yue Chen5e606542017-05-24 17:03:17 -07008255#endif
8256#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
8257 int compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008258 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yue Chen5e606542017-05-24 17:03:17 -07008259#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008260
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008261#if CONFIG_INTERINTRA
8262 if (!cm->allow_interintra_compound && is_comp_interintra_pred)
8263 return INT64_MAX;
8264#endif // CONFIG_INTERINTRA
8265
Yaowu Xuc27fc142016-08-22 16:08:15 -07008266 // is_comp_interintra_pred implies !is_comp_pred
8267 assert(!is_comp_interintra_pred || (!is_comp_pred));
8268 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8269 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8270#endif // CONFIG_EXT_INTER
8271
Yaowu Xuc27fc142016-08-22 16:08:15 -07008272#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07008273#if CONFIG_COMPOUND_SINGLEREF
8274 if (is_comp_pred || is_singleref_comp_mode)
8275#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008276 if (is_comp_pred)
Zoe Liu85b66462017-04-20 14:28:19 -07008277#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008278 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8279 else
8280#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008281 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8282 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008283
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008284#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008285 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8286 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8287 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008288#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008289 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008290 // Make sure that we didn't leave the plane destination buffers set
8291 // to tmp_buf at the end of the last iteration
8292 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008293
Yue Chen69f18e12016-09-08 14:48:15 -07008294#if CONFIG_WARPED_MOTION
8295 mbmi->num_proj_ref[0] = 0;
8296 mbmi->num_proj_ref[1] = 0;
8297#endif // CONFIG_WARPED_MOTION
8298
Yaowu Xuc27fc142016-08-22 16:08:15 -07008299 if (is_comp_pred) {
8300 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8301 frame_mv[refs[1]].as_int == INVALID_MV)
8302 return INT64_MAX;
Zoe Liu85b66462017-04-20 14:28:19 -07008303#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8304 } else if (is_singleref_comp_mode) {
8305 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8306 frame_comp_mv[refs[0]].as_int == INVALID_MV)
8307 return INT64_MAX;
8308#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008309 }
8310
Yue Chene9638cc2016-10-10 12:37:54 -07008311 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008312 if (have_newmv_in_inter_mode(this_mode)) {
Zoe Liu85b66462017-04-20 14:28:19 -07008313 const int64_t ret_val =
8314 handle_newmv(cpi, x, bsize, mode_mv,
8315#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8316 mode_comp_mv,
8317#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8318 mi_row, mi_col, &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008319 if (ret_val != 0)
8320 return ret_val;
8321 else
8322 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008323 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008324 for (i = 0; i < is_comp_pred + 1; ++i) {
8325 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07008326 // Clip "next_nearest" so that it does not extend to far out of image
8327 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008328 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008329 mbmi->mv[i].as_int = cur_mv[i].as_int;
8330 }
8331
Zoe Liu85b66462017-04-20 14:28:19 -07008332#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8333 if (!is_comp_pred && is_singleref_comp_mode) {
8334 cur_mv[1] = frame_comp_mv[refs[0]];
8335 // Clip "next_nearest" so that it does not extend to far out of image
8336 if (this_mode != NEWMV) clamp_mv2(&cur_mv[1].as_mv, xd);
8337 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
8338 mbmi->mv[1].as_int = cur_mv[1].as_int;
8339 }
8340#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8341
Yaowu Xuc27fc142016-08-22 16:08:15 -07008342#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008343 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008344#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008345 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008346#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008347 {
8348#if !CONFIG_EXT_INTER
8349 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008350#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008351 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8352 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8353 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8354
8355 for (i = 0; i < 2; ++i) {
8356 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008357 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008358 mbmi->mv[i].as_int = cur_mv[i].as_int;
8359 }
8360 }
8361 }
8362
8363#if CONFIG_EXT_INTER
8364 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Zoe Liu85b66462017-04-20 14:28:19 -07008365#if CONFIG_COMPOUND_SINGLEREF
8366 if (this_mode == NEAREST_NEWMV || // this_mode == SR_NEAREST_NEWMV ||
8367 this_mode == SR_NEAREST_NEARMV) {
8368#else // !CONFIG_COMPOUND_SINGLEREF
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008369 if (this_mode == NEAREST_NEWMV) {
Zoe Liu85b66462017-04-20 14:28:19 -07008370#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008371 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8372
8373 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8374 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008375 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008376 mbmi->mv[0].as_int = cur_mv[0].as_int;
8377 }
8378
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008379 if (this_mode == NEW_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8381
8382 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8383 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008384 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008385 mbmi->mv[1].as_int = cur_mv[1].as_int;
8386 }
8387 }
8388
8389 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01008390 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Zoe Liu85b66462017-04-20 14:28:19 -07008391 if (this_mode == NEAR_NEWMV ||
8392#if CONFIG_COMPOUND_SINGLEREF
8393 this_mode == SR_NEAR_NEWMV ||
8394#endif // CONFIG_COMPOUND_SINGLEREF
8395 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008396 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008397
8398 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8399 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008400 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008401 mbmi->mv[0].as_int = cur_mv[0].as_int;
8402 }
8403
Zoe Liu85b66462017-04-20 14:28:19 -07008404 if (this_mode == NEW_NEARMV ||
8405#if CONFIG_COMPOUND_SINGLEREF
8406 this_mode == SR_NEAREST_NEARMV ||
8407#endif // CONFIG_COMPOUND_SINGLEREF
8408 this_mode == NEAR_NEARMV) {
8409#if CONFIG_COMPOUND_SINGLEREF
8410 if (this_mode == SR_NEAREST_NEARMV)
8411 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8412 else
8413#endif // CONFIG_COMPOUND_SINGLEREF
8414 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008415
8416 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8417 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008418 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008419 mbmi->mv[1].as_int = cur_mv[1].as_int;
8420 }
8421 }
Zoe Liu85b66462017-04-20 14:28:19 -07008422#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008423 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008424 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008425 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8426 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8427 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8428 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8429
8430 for (i = 0; i < 2; ++i) {
8431 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008432 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008433 mbmi->mv[i].as_int = cur_mv[i].as_int;
8434 }
8435 }
8436 }
8437#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008438
8439 // do first prediction into the destination buffer. Do the next
8440 // prediction into a temporary buffer. Then keep track of which one
8441 // of these currently holds the best predictor, and use the other
8442 // one for future predictions. In the end, copy from tmp_buf to
8443 // dst if necessary.
8444 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008445 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8446 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008447 }
8448 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008449 orig_dst.plane[i] = xd->plane[i].dst.buf;
8450 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008451 }
8452
8453 // We don't include the cost of the second reference here, because there
8454 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8455 // words if you present them in that order, the second one is always known
8456 // if the first is known.
8457 //
8458 // Under some circumstances we discount the cost of new mv mode to encourage
8459 // initiation of a motion field.
8460 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8461 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01008462#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008463 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01008464 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8465 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
8466 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008467#else
Angie Chiang76159122016-11-09 12:13:22 -08008468 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8469 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008470#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008471 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008472 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008473 }
8474
Urvang Joshi70006e42017-06-14 16:08:55 -07008475 if (RDCOST(x->rdmult, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008476#if CONFIG_EXT_INTER
8477 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8478#else
8479 mbmi->mode != NEARESTMV
8480#endif // CONFIG_EXT_INTER
8481 )
8482 return INT64_MAX;
8483
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008484 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008485 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8486 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008487 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008488
Yaowu Xuc27fc142016-08-22 16:08:15 -07008489#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008490#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008491 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008492 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008493 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008494 rate_mv_bmc = rate_mv;
Yue Chen69f18e12016-09-08 14:48:15 -07008495#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008496
Yue Chen5e606542017-05-24 17:03:17 -07008497#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Zoe Liu85b66462017-04-20 14:28:19 -07008498#if CONFIG_COMPOUND_SINGLEREF
8499 if (is_comp_pred || is_singleref_comp_mode) {
8500#else
Sarah Parker6fdc8532016-11-16 17:47:13 -08008501 if (is_comp_pred) {
Zoe Liu85b66462017-04-20 14:28:19 -07008502#endif // CONFIG_COMPOUND_SINGLEREF
Urvang Joshi368fbc92016-10-17 16:31:34 -07008503 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008504 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008505 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8506 INTERINTER_COMPOUND_DATA best_compound_data;
8507 int_mv best_mv[2];
8508 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008509 int tmp_skip_txfm_sb;
8510 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07008511 int compound_type_cost[COMPOUND_TYPES];
Yaowu Xu5e8007f2017-06-28 12:39:18 -07008512 DECLARE_ALIGNED(16, uint8_t, pred0[2 * MAX_SB_SQUARE]);
8513 DECLARE_ALIGNED(16, uint8_t, pred1[2 * MAX_SB_SQUARE]);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008514 uint8_t *preds0[1] = { pred0 };
8515 uint8_t *preds1[1] = { pred1 };
8516 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008517 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008518 int masked_compound_used = is_any_masked_compound_used(bsize);
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008519#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
8520 masked_compound_used = masked_compound_used && cm->allow_masked_compound;
8521#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008522 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008523
Sarah Parker6fdc8532016-11-16 17:47:13 -08008524 best_mv[0].as_int = cur_mv[0].as_int;
8525 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008526 memset(&best_compound_data, 0, sizeof(best_compound_data));
8527#if CONFIG_COMPOUND_SEGMENT
8528 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
8529 best_compound_data.seg_mask = tmp_mask_buf;
8530#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008531
Zoe Liu85b66462017-04-20 14:28:19 -07008532#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8533 // TODO(zoeliu): To further check whether the following setups are needed.
8534 // Single ref compound mode: Prepare the 2nd ref frame predictor the same as
8535 // the 1st one.
8536 if (!is_comp_pred && is_singleref_comp_mode) {
8537 xd->block_refs[1] = xd->block_refs[0];
8538 for (i = 0; i < MAX_MB_PLANE; i++)
8539 xd->plane[i].pre[1] = xd->plane[i].pre[0];
8540 }
8541#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8542
Sarah Parker42d96102017-01-31 21:05:27 -08008543 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07008544 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8545 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008546 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008547 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008548 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008549 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008550 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008551 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008552
Sarah Parker6fdc8532016-11-16 17:47:13 -08008553 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008554 if (cur_type != COMPOUND_AVERAGE && !masked_compound_used) break;
Yue Chene2518252017-06-05 12:36:46 -07008555 if (!is_interinter_compound_used(cur_type, bsize)) continue;
Sarah Parker2e604882017-01-17 17:31:25 -08008556 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008557 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008558 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008559 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008560 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008561 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008562 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08008563 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008564
Sarah Parker6fdc8532016-11-16 17:47:13 -08008565 switch (cur_type) {
8566 case COMPOUND_AVERAGE:
Jingning Hanc44009c2017-05-06 11:36:49 -07008567 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8568 bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008569 av1_subtract_plane(x, bsize, 0);
8570 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8571 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8572 INT64_MAX);
8573 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008574 best_rd_cur = RDCOST(x->rdmult, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008575 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008576 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008577#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008578 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008579 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8580 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008581 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00008582 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8583 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008584 }
8585 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008586#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08008587#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008588 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008589 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8590 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008591 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08008592 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8593 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008594 }
8595 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008596#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008597 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008598 }
Sarah Parker2e604882017-01-17 17:31:25 -08008599
8600 if (best_rd_cur < best_rd_compound) {
8601 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008602#if CONFIG_WEDGE
8603 best_compound_data.wedge_index = mbmi->wedge_index;
8604 best_compound_data.wedge_sign = mbmi->wedge_sign;
8605#endif // CONFIG_WEDGE
8606#if CONFIG_COMPOUND_SEGMENT
8607 best_compound_data.mask_type = mbmi->mask_type;
8608 memcpy(best_compound_data.seg_mask, xd->seg_mask,
8609 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8610#endif // CONFIG_COMPOUND_SEGMENT
8611 best_compound_data.interinter_compound_type =
8612 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08008613 if (have_newmv_in_inter_mode(this_mode)) {
8614 if (use_masked_motion_search(cur_type)) {
8615 best_tmp_rate_mv = tmp_rate_mv;
8616 best_mv[0].as_int = mbmi->mv[0].as_int;
8617 best_mv[1].as_int = mbmi->mv[1].as_int;
8618 } else {
8619 best_mv[0].as_int = cur_mv[0].as_int;
8620 best_mv[1].as_int = cur_mv[1].as_int;
8621 }
8622 }
8623 }
8624 // reset to original mvs for next iteration
8625 mbmi->mv[0].as_int = cur_mv[0].as_int;
8626 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008627 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008628#if CONFIG_WEDGE
8629 mbmi->wedge_index = best_compound_data.wedge_index;
8630 mbmi->wedge_sign = best_compound_data.wedge_sign;
8631#endif // CONFIG_WEDGE
8632#if CONFIG_COMPOUND_SEGMENT
8633 mbmi->mask_type = best_compound_data.mask_type;
8634 memcpy(xd->seg_mask, best_compound_data.seg_mask,
8635 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8636#endif // CONFIG_COMPOUND_SEGMENT
8637 mbmi->interinter_compound_type =
8638 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008639 if (have_newmv_in_inter_mode(this_mode)) {
8640 mbmi->mv[0].as_int = best_mv[0].as_int;
8641 mbmi->mv[1].as_int = best_mv[1].as_int;
8642 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8643 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008644 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008645 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8646 rate_mv = best_tmp_rate_mv;
8647 }
8648 }
8649
8650 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008651 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008652 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008653 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008654
8655 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008656
Yue Chen5e606542017-05-24 17:03:17 -07008657 compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008658 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008659 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01008660 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008661 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01008662 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008663 }
Yue Chen5e606542017-05-24 17:03:17 -07008664#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008665
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008666#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008667 if (is_comp_interintra_pred) {
8668 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8669 int64_t best_interintra_rd = INT64_MAX;
8670 int rmode, rate_sum;
8671 int64_t dist_sum;
8672 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008673 int tmp_rate_mv = 0;
8674 int tmp_skip_txfm_sb;
8675 int64_t tmp_skip_sse_sb;
8676 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8677 uint8_t *intrapred;
8678
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008679#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008680 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8681 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8682 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008683#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008684 intrapred = intrapred_;
8685
Emil Keyder01770b32017-01-20 18:03:11 -05008686 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008687 for (j = 0; j < MAX_MB_PLANE; j++) {
8688 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8689 xd->plane[j].dst.stride = bw;
8690 }
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008691 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst, bsize);
David Barkerac37fa32016-12-02 12:30:21 +00008692 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008693 mbmi->ref_frame[1] = INTRA_FRAME;
8694 mbmi->use_wedge_interintra = 0;
8695
8696 for (j = 0; j < INTERINTRA_MODES; ++j) {
8697 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8698 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008699 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8700 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008701 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008702 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8703 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008704 rd = RDCOST(x->rdmult, tmp_rate_mv + rate_sum + rmode, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008705 if (rd < best_interintra_rd) {
8706 best_interintra_rd = rd;
8707 best_interintra_mode = mbmi->interintra_mode;
8708 }
8709 }
8710 mbmi->interintra_mode = best_interintra_mode;
8711 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008712 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8713 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008714 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8715 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008716 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8717 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8718 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008719 rd = RDCOST(x->rdmult, rate_mv + rmode + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008720 best_interintra_rd = rd;
8721
8722 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008723 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008724 return INT64_MAX;
8725 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008726#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008727 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008728 int64_t best_interintra_rd_nowedge = INT64_MAX;
8729 int64_t best_interintra_rd_wedge = INT64_MAX;
8730 int_mv tmp_mv;
8731 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008732 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008733 rd = RDCOST(x->rdmult, rmode + rate_mv + rwedge + rate_sum, dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07008734 best_interintra_rd_nowedge = best_interintra_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008735
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008736 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07008737 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8738 mbmi->use_wedge_interintra = 1;
8739
Yaowu Xuf883b422016-08-30 14:01:10 -07008740 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8741 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008742
8743 best_interintra_rd_wedge =
8744 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8745
8746 best_interintra_rd_wedge +=
Urvang Joshi70006e42017-06-14 16:08:55 -07008747 RDCOST(x->rdmult, rmode + rate_mv + rwedge, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008748 // Refine motion vector.
8749 if (have_newmv_in_inter_mode(this_mode)) {
8750 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008751 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008752 mbmi->interintra_wedge_index, 1, bsize);
David Barkerf19f35f2017-05-22 16:33:22 +01008753 tmp_mv.as_int = x->mbmi_ext->ref_mvs[refs[0]][0].as_int;
8754 compound_single_motion_search(cpi, x, bsize, &tmp_mv.as_mv, mi_row,
8755 mi_col, intrapred, mask, bw,
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07008756 &tmp_rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008757 mbmi->mv[0].as_int = tmp_mv.as_int;
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008758 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8759 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008760 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8761 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008762 rd = RDCOST(x->rdmult, rmode + tmp_rate_mv + rwedge + rate_sum,
8763 dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07008764 if (rd >= best_interintra_rd_wedge) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008765 tmp_mv.as_int = cur_mv[0].as_int;
8766 tmp_rate_mv = rate_mv;
8767 }
8768 } else {
8769 tmp_mv.as_int = cur_mv[0].as_int;
8770 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008771 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008772 }
8773 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008774 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008775 rd =
8776 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8777 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8778 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008779 rd = RDCOST(x->rdmult, rmode + tmp_rate_mv + rwedge + rate_sum,
8780 dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 best_interintra_rd_wedge = rd;
8782 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8783 mbmi->use_wedge_interintra = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008784 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008785 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008786 rate_mv = tmp_rate_mv;
8787 } else {
8788 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008789 mbmi->mv[0].as_int = cur_mv[0].as_int;
8790 }
8791 } else {
8792 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008793 }
8794 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008795#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008796
8797 pred_exists = 0;
Yue Chen5e606542017-05-24 17:03:17 -07008798 compmode_interintra_cost =
8799 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1) +
Fergus Simpson073c6f32017-02-17 12:13:48 -08008800 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008801 if (is_interintra_wedge_used(bsize)) {
Yue Chen5e606542017-05-24 17:03:17 -07008802 compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008803 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8804 if (mbmi->use_wedge_interintra) {
Yue Chen5e606542017-05-24 17:03:17 -07008805 compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008806 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008807 }
8808 }
8809 } else if (is_interintra_allowed(mbmi)) {
Yue Chen5e606542017-05-24 17:03:17 -07008810 compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008811 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008812 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008813#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008814
Angie Chiang75c22092016-10-25 12:19:16 -07008815 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008816 int tmp_rate;
8817 int64_t tmp_dist;
Jingning Hanc44009c2017-05-06 11:36:49 -07008818 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008819 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8820 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008821 rd = RDCOST(x->rdmult, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008822 }
Angie Chiang75c22092016-10-25 12:19:16 -07008823#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008824
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008825 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008826#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008827 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008828#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008829 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008830#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008831
8832#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008833 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008834 if (is_comp_pred) {
8835 const int mode0 = compound_ref0_mode(this_mode);
8836 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008837 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8838 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008839 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008840 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008841 return INT64_MAX;
8842 }
8843 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008844 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008845 }
8846 }
8847#endif // CONFIG_EXT_INTER
8848
8849 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8850 // if current pred_error modeled rd is substantially more than the best
8851 // so far, do not bother doing full rd
8852 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008853 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008854 return INT64_MAX;
8855 }
8856 }
8857
Yue Chen5e606542017-05-24 17:03:17 -07008858#if CONFIG_EXT_INTER
8859#if CONFIG_INTERINTRA
8860 rd_stats->rate += compmode_interintra_cost;
8861#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8862 rate2_bmc_nocoeff += compmode_interintra_cost;
8863#endif
8864#endif
8865#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
8866 rd_stats->rate += compmode_interinter_cost;
8867#endif
8868#endif
8869
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008870 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
8871 disable_skip, mode_mv, mi_row, mi_col, args,
8872 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07008873#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07008874 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008875#if CONFIG_EXT_INTER
Yunqing Wang562a3932017-06-20 12:20:45 -07008876 rate2_bmc_nocoeff, &best_bmc_mbmi, rate_mv_bmc,
Yue Chen69f18e12016-09-08 14:48:15 -07008877#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008878#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008879 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
8880 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08008881
Yaowu Xuc27fc142016-08-22 16:08:15 -07008882 return 0; // The rate-distortion cost will be re-calculated by caller.
8883}
8884
Alex Converse28744302017-04-13 14:46:22 -07008885#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07008886static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008887 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07008888 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07008889 const AV1_COMMON *const cm = &cpi->common;
8890 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
8891
Alex Converse28744302017-04-13 14:46:22 -07008892 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07008893 const TileInfo *tile = &xd->tile;
Alex Converse7c412ea2017-06-01 15:16:22 -07008894#if CONFIG_EC_ADAPT
8895 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
8896#else
8897 FRAME_CONTEXT *const ec_ctx = cm->fc;
8898#endif // CONFIG_EC_ADAPT
Alex Converse3d8adf32017-04-24 12:35:42 -07008899 MODE_INFO *const mi = xd->mi[0];
8900 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
8901 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
8902 const int w = block_size_wide[bsize];
8903 const int h = block_size_high[bsize];
8904 const int sb_row = mi_row / MAX_MIB_SIZE;
Alex Converse861d7072017-05-15 14:19:53 -07008905 const int sb_col = mi_col / MAX_MIB_SIZE;
Alex Converse3d8adf32017-04-24 12:35:42 -07008906
Alex Converse44c2bad2017-05-11 09:36:10 -07008907 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8908 MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
8909 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8910 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8911 mbmi_ext->ref_mv_stack[ref_frame],
8912#if CONFIG_EXT_INTER
8913 mbmi_ext->compound_mode_context,
8914#endif // CONFIG_EXT_INTER
8915 candidates, mi_row, mi_col, NULL, NULL,
8916 mbmi_ext->mode_context);
8917
8918 int_mv nearestmv, nearmv;
8919 av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
8920
8921 int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
8922 if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
8923 mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
Alex Converse3d8adf32017-04-24 12:35:42 -07008924
Alex Converse3d8adf32017-04-24 12:35:42 -07008925 struct buf_2d yv12_mb[MAX_MB_PLANE];
8926 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
8927 for (int i = 0; i < MAX_MB_PLANE; ++i) {
8928 xd->plane[i].pre[0] = yv12_mb[i];
8929 }
8930
Alex Converse861d7072017-05-15 14:19:53 -07008931 enum IntrabcMotionDirection {
8932 IBC_MOTION_ABOVE,
8933 IBC_MOTION_LEFT,
8934 IBC_MOTION_DIRECTIONS
8935 };
Alex Converse3d8adf32017-04-24 12:35:42 -07008936
Alex Converse3d8adf32017-04-24 12:35:42 -07008937 MB_MODE_INFO *mbmi = &mi->mbmi;
8938 MB_MODE_INFO best_mbmi = *mbmi;
8939 RD_STATS best_rdcost = *rd_cost;
8940 int best_skip = x->skip;
Alex Converse861d7072017-05-15 14:19:53 -07008941
8942 for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
8943 dir < IBC_MOTION_DIRECTIONS; ++dir) {
8944 const MvLimits tmp_mv_limits = x->mv_limits;
8945 switch (dir) {
8946 case IBC_MOTION_ABOVE:
8947 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8948 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
8949 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8950 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
8951 break;
8952 case IBC_MOTION_LEFT:
8953 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8954 x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
8955 // TODO(aconverse@google.com): Minimize the overlap between above and
8956 // left areas.
8957 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8958 int bottom_coded_mi_edge =
8959 AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
8960 x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
8961 break;
8962 default: assert(0);
8963 }
8964 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
8965 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
8966 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
8967 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
8968 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
8969
8970 if (x->mv_limits.col_max < x->mv_limits.col_min ||
8971 x->mv_limits.row_max < x->mv_limits.row_min) {
8972 x->mv_limits = tmp_mv_limits;
8973 continue;
8974 }
8975
8976 int step_param = cpi->mv_step_param;
8977 MV mvp_full = dv_ref.as_mv;
8978 mvp_full.col >>= 3;
8979 mvp_full.row >>= 3;
8980 int sadpb = x->sadperbit16;
8981 int cost_list[5];
8982 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
8983 sadpb, cond_cost_list(cpi, cost_list),
8984 &dv_ref.as_mv, INT_MAX, 1);
8985
8986 x->mv_limits = tmp_mv_limits;
8987 if (bestsme == INT_MAX) continue;
8988 mvp_full = x->best_mv.as_mv;
8989 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
8990 if (mv_check_bounds(&x->mv_limits, &dv)) continue;
8991 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
8992
Alex Converse3d8adf32017-04-24 12:35:42 -07008993#if CONFIG_PALETTE
Alex Converse861d7072017-05-15 14:19:53 -07008994 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
Alex Converse3d8adf32017-04-24 12:35:42 -07008995#endif
Alex Converse861d7072017-05-15 14:19:53 -07008996 mbmi->use_intrabc = 1;
8997 mbmi->mode = DC_PRED;
8998 mbmi->uv_mode = DC_PRED;
8999 mbmi->mv[0].as_mv = dv;
Alex Converse3d8adf32017-04-24 12:35:42 -07009000#if CONFIG_DUAL_FILTER
Alex Converse861d7072017-05-15 14:19:53 -07009001 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07009002#else
Alex Converse861d7072017-05-15 14:19:53 -07009003 mbmi->interp_filter = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07009004#endif
Alex Converse861d7072017-05-15 14:19:53 -07009005 mbmi->skip = 0;
9006 x->skip = 0;
9007 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Alex Converse3d8adf32017-04-24 12:35:42 -07009008
Alex Conversed5d9b6c2017-05-23 15:23:45 -07009009 assert(x->mvcost == x->mv_cost_stack[0]);
9010 // TODO(aconverse@google.com): The full motion field defining discount
9011 // in MV_COST_WEIGHT is too large. Explore other values.
Alex Converse861d7072017-05-15 14:19:53 -07009012 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
Alex Conversed5d9b6c2017-05-23 15:23:45 -07009013 x->mvcost, MV_COST_WEIGHT_SUB);
9014 const int rate_mode = av1_cost_bit(ec_ctx->intrabc_prob, 1);
Alex Converse3d8adf32017-04-24 12:35:42 -07009015
Alex Converse861d7072017-05-15 14:19:53 -07009016 RD_STATS rd_stats, rd_stats_uv;
9017 av1_subtract_plane(x, bsize, 0);
9018 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
9019 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
9020 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
Alex Converse3d8adf32017-04-24 12:35:42 -07009021#if CONFIG_RD_DEBUG
Alex Converse861d7072017-05-15 14:19:53 -07009022 mbmi->rd_stats = rd_stats;
Alex Converse3d8adf32017-04-24 12:35:42 -07009023#endif
9024
Alex Conversee16b2662017-05-24 14:00:00 -07009025#if CONFIG_VAR_TX
9026 // TODO(aconverse@google.com): Evaluate allowing VAR TX on intrabc blocks
9027 const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
9028 const int height = block_size_high[bsize] >> tx_size_high_log2[0];
9029 int idx, idy;
9030 for (idy = 0; idy < height; ++idy)
9031 for (idx = 0; idx < width; ++idx)
9032 mbmi->inter_tx_size[idy >> 1][idx >> 1] = mbmi->tx_size;
9033 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
9034#endif // CONFIG_VAR_TX
9035
Alex Converse861d7072017-05-15 14:19:53 -07009036 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Alex Converse3d8adf32017-04-24 12:35:42 -07009037
Alex Converse861d7072017-05-15 14:19:53 -07009038 RD_STATS rdc_noskip;
9039 av1_init_rd_stats(&rdc_noskip);
9040 rdc_noskip.rate =
9041 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
9042 rdc_noskip.dist = rd_stats.dist;
Urvang Joshi70006e42017-06-14 16:08:55 -07009043 rdc_noskip.rdcost = RDCOST(x->rdmult, rdc_noskip.rate, rdc_noskip.dist);
Alex Converse861d7072017-05-15 14:19:53 -07009044 if (rdc_noskip.rdcost < best_rd) {
9045 best_rd = rdc_noskip.rdcost;
9046 best_mbmi = *mbmi;
9047 best_skip = x->skip;
9048 best_rdcost = rdc_noskip;
9049 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009050
Alex Converse861d7072017-05-15 14:19:53 -07009051 x->skip = 1;
9052 mbmi->skip = 1;
9053 RD_STATS rdc_skip;
9054 av1_init_rd_stats(&rdc_skip);
9055 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
9056 rdc_skip.dist = rd_stats.sse;
Urvang Joshi70006e42017-06-14 16:08:55 -07009057 rdc_skip.rdcost = RDCOST(x->rdmult, rdc_skip.rate, rdc_skip.dist);
Alex Converse861d7072017-05-15 14:19:53 -07009058 if (rdc_skip.rdcost < best_rd) {
9059 best_rd = rdc_skip.rdcost;
9060 best_mbmi = *mbmi;
9061 best_skip = x->skip;
9062 best_rdcost = rdc_skip;
9063 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009064 }
9065 *mbmi = best_mbmi;
9066 *rd_cost = best_rdcost;
9067 x->skip = best_skip;
9068 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07009069}
9070#endif // CONFIG_INTRABC
9071
Urvang Joshi52648442016-10-13 17:27:51 -07009072void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009073 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07009074 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9075 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009076 MACROBLOCKD *const xd = &x->e_mbd;
Luc Trudeau14fc5042017-06-16 12:40:29 -04009077 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009078 struct macroblockd_plane *const pd = xd->plane;
9079 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9080 int y_skip = 0, uv_skip = 0;
9081 int64_t dist_y = 0, dist_uv = 0;
9082 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009083 const int unify_bsize = CONFIG_CB4X4;
9084
Yaowu Xuc27fc142016-08-22 16:08:15 -07009085 ctx->skip = 0;
Luc Trudeau14fc5042017-06-16 12:40:29 -04009086 mbmi->ref_frame[0] = INTRA_FRAME;
9087 mbmi->ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07009088#if CONFIG_INTRABC
Luc Trudeau14fc5042017-06-16 12:40:29 -04009089 mbmi->use_intrabc = 0;
9090 mbmi->mv[0].as_int = 0;
Alex Converse28744302017-04-13 14:46:22 -07009091#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07009092
Alex Conversed1b6fad2017-04-26 15:39:37 -07009093 const int64_t intra_yrd =
9094 (bsize >= BLOCK_8X8 || unify_bsize)
9095 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9096 &y_skip, bsize, best_rd)
9097 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
9098 &dist_y, &y_skip, best_rd);
9099
9100 if (intra_yrd < best_rd) {
Luc Trudeau14fc5042017-06-16 12:40:29 -04009101#if CONFIG_CFL
9102 // Perform one extra txfm_rd_in_plane() call, this time with the best value
9103 // so we can store reconstructed luma values
9104 RD_STATS this_rd_stats;
9105
Luc Trudeau780d2492017-06-15 22:26:41 -04009106#if CONFIG_CB4X4
9107 // Don't store the luma value if no chroma is associated.
9108 // Don't worry, we will store this reconstructed luma in the following
9109 // encode dry-run the chroma plane will never know.
9110 x->cfl_store_y = !x->skip_chroma_rd;
9111#else
Luc Trudeau14fc5042017-06-16 12:40:29 -04009112 x->cfl_store_y = 1;
Luc Trudeau780d2492017-06-15 22:26:41 -04009113#endif
Luc Trudeau14fc5042017-06-16 12:40:29 -04009114
9115 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, AOM_PLANE_Y,
9116 mbmi->sb_type, mbmi->tx_size,
9117 cpi->sf.use_fast_coef_costing);
9118
9119 x->cfl_store_y = 0;
9120#endif
9121 max_uv_tx_size = uv_txsize_lookup[bsize][mbmi->tx_size][pd[1].subsampling_x]
9122 [pd[1].subsampling_y];
9123 init_sbuv_mode(mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08009124#if CONFIG_CB4X4
Alex Conversed1b6fad2017-04-26 15:39:37 -07009125 if (!x->skip_chroma_rd)
9126 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9127 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009128#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07009129 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9130 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009131#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009132
Alex Conversed1b6fad2017-04-26 15:39:37 -07009133 if (y_skip && uv_skip) {
9134 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
9135 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9136 rd_cost->dist = dist_y + dist_uv;
9137 } else {
9138 rd_cost->rate =
9139 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9140 rd_cost->dist = dist_y + dist_uv;
9141 }
Urvang Joshi70006e42017-06-14 16:08:55 -07009142 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Yushin Cho63927c42017-05-23 15:41:05 -07009143#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9144 rd_cost->dist_y = dist_y;
9145#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009146 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07009147 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009148 }
9149
Alex Converse28744302017-04-13 14:46:22 -07009150#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07009151 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
9152 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07009153 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
9154 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07009155 assert(rd_cost->rate != INT_MAX);
Urvang Joshi70006e42017-06-14 16:08:55 -07009156 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07009157 }
9158#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07009159 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07009160
Yaowu Xuc27fc142016-08-22 16:08:15 -07009161 ctx->mic = *xd->mi[0];
9162 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009163}
9164
Yaowu Xuc27fc142016-08-22 16:08:15 -07009165// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009166int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009167 return (cpi->oxcf.pass == 2) &&
9168 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9169 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9170}
9171
9172// Checks to see if a super block is on a horizontal image edge.
9173// In most cases this is the "real" edge unless there are formatting
9174// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009175int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009176 int top_edge = 0;
9177 int bottom_edge = cpi->common.mi_rows;
9178 int is_active_h_edge = 0;
9179
9180 // For two pass account for any formatting bars detected.
9181 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009182 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009183
9184 // The inactive region is specified in MBs not mi units.
9185 // The image edge is in the following MB row.
9186 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9187
9188 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009189 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009190 }
9191
9192 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9193 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9194 is_active_h_edge = 1;
9195 }
9196 return is_active_h_edge;
9197}
9198
9199// Checks to see if a super block is on a vertical image edge.
9200// In most cases this is the "real" edge unless there are formatting
9201// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009202int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009203 int left_edge = 0;
9204 int right_edge = cpi->common.mi_cols;
9205 int is_active_v_edge = 0;
9206
9207 // For two pass account for any formatting bars detected.
9208 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009209 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009210
9211 // The inactive region is specified in MBs not mi units.
9212 // The image edge is in the following MB row.
9213 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9214
9215 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009216 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009217 }
9218
9219 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9220 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9221 is_active_v_edge = 1;
9222 }
9223 return is_active_v_edge;
9224}
9225
9226// Checks to see if a super block is at the edge of the active image.
9227// In most cases this is the "real" edge unless there are formatting
9228// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009229int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009230 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9231 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009232}
9233
Urvang Joshib100db72016-10-12 16:28:56 -07009234#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009235static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009236 MACROBLOCKD *const xd = &x->e_mbd;
9237 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9238 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9239 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009240 int src_stride = x->plane[1].src.stride;
9241 const uint8_t *const src_u = x->plane[1].src.buf;
9242 const uint8_t *const src_v = x->plane[2].src.buf;
9243 float *const data = x->palette_buffer->kmeans_data_buf;
9244 float centroids[2 * PALETTE_MAX_SIZE];
9245 uint8_t *const color_map = xd->plane[1].color_index_map;
9246 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009247#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009248 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9249 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009250#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009251 int plane_block_width, plane_block_height, rows, cols;
9252 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9253 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009254 (void)cpi;
9255
9256 for (r = 0; r < rows; ++r) {
9257 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009258#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009259 if (cpi->common.use_highbitdepth) {
9260 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9261 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9262 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009263#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009264 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9265 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009266#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009267 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009268#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009269 }
9270 }
9271
9272 for (r = 1; r < 3; ++r) {
9273 for (c = 0; c < pmi->palette_size[1]; ++c) {
9274 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9275 }
9276 }
9277
Yaowu Xuf883b422016-08-30 14:01:10 -07009278 av1_calc_indices(data, centroids, color_map, rows * cols,
9279 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009280 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9281 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009282}
Urvang Joshib100db72016-10-12 16:28:56 -07009283#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009284
hui su5db97432016-10-14 16:10:14 -07009285#if CONFIG_FILTER_INTRA
9286static void pick_filter_intra_interframe(
9287 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009288 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9289 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9290 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009291#if CONFIG_EXT_INTRA
9292 int8_t *uv_angle_delta,
9293#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009294#if CONFIG_PALETTE
9295 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9296#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009297 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9298 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9299 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9300#if CONFIG_SUPERTX
9301 int *returnrate_nocoef,
9302#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009303 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009304 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009305 MACROBLOCKD *const xd = &x->e_mbd;
9306 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009307#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009308 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009309#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009310 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9311 int dc_mode_index;
9312 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009313 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9314 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009315 TX_SIZE uv_tx;
9316
9317 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009318 if (av1_mode_order[i].mode == DC_PRED &&
9319 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009320 break;
9321 dc_mode_index = i;
9322 assert(i < MAX_MODES);
9323
9324 // TODO(huisu): use skip_mask for further speedup.
9325 (void)skip_mask;
9326 mbmi->mode = DC_PRED;
9327 mbmi->uv_mode = DC_PRED;
9328 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009329 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009330 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9331 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009332 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009333 return;
hui su5db97432016-10-14 16:10:14 -07009334 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009335 if (rate_y == INT_MAX) return;
9336
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009337 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9338 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009339 if (rate_uv_intra[uv_tx] == INT_MAX) {
9340 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9341 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9342 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009343#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009344 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009345#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009346 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9347#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009348 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009349#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009350 }
9351
9352 rate_uv = rate_uv_tokenonly[uv_tx];
9353 distortion_uv = dist_uv[uv_tx];
9354 skippable = skippable && skip_uv[uv_tx];
9355 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009356#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009357 if (cm->allow_screen_content_tools) {
9358 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9359 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9360 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9361 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9362 }
Urvang Joshib100db72016-10-12 16:28:56 -07009363#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009364#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009365 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009366#endif // CONFIG_EXT_INTRA
9367 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9368 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9369 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9370 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9371 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009372 }
9373
9374 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9375 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009376#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07009377 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
9378 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07009379 rate2 += av1_cost_bit(
9380 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009381#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009382
9383 if (!xd->lossless[mbmi->segment_id]) {
9384 // super_block_yrd above includes the cost of the tx_size in the
9385 // tokenonly rate, but for intra blocks, tx_size is always coded
9386 // (prediction granularity), so we account for it in the full rate,
9387 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009388 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009389 }
9390
hui su5db97432016-10-14 16:10:14 -07009391 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9392 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9393 rate2 += write_uniform_cost(
9394 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9395#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07009396 if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
9397 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07009398 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9399 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009400 }
hui su5db97432016-10-14 16:10:14 -07009401#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009402 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009403 rate2 +=
9404 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9405 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9406 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9407 rate2 +=
9408 write_uniform_cost(FILTER_INTRA_MODES,
9409 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009410 }
9411 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009412 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9413 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414
9415 rate2 += ref_costs_single[INTRA_FRAME];
9416
9417 if (skippable) {
9418 rate2 -= (rate_y + rate_uv);
9419 rate_y = 0;
9420 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009421 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009422 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009423 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009424 }
Urvang Joshi70006e42017-06-14 16:08:55 -07009425 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009426
9427 if (this_rd < *best_intra_rd) {
9428 *best_intra_rd = this_rd;
9429 *best_intra_mode = mbmi->mode;
9430 }
9431 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009432 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009433
9434 if (this_rd < *best_rd) {
9435 *best_mode_index = dc_mode_index;
9436 mbmi->mv[0].as_int = 0;
9437 rd_cost->rate = rate2;
9438#if CONFIG_SUPERTX
9439 if (x->skip)
9440 *returnrate_nocoef = rate2;
9441 else
9442 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009443 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9444 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9445 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009446#endif // CONFIG_SUPERTX
9447 rd_cost->dist = distortion2;
9448 rd_cost->rdcost = this_rd;
9449 *best_rd = this_rd;
9450 *best_mbmode = *mbmi;
9451 *best_skip2 = 0;
9452 *best_mode_skippable = skippable;
9453 }
9454}
hui su5db97432016-10-14 16:10:14 -07009455#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009456
Yue Chencb60b182016-10-13 15:18:22 -07009457#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009458static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9459 const MACROBLOCKD *xd, int mi_row,
9460 int mi_col, const uint8_t *above,
9461 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009462 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009463#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009464
Urvang Joshi52648442016-10-13 17:27:51 -07009465void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009466 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009467 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009468#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009469 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009470#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009471 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9472 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009473 const AV1_COMMON *const cm = &cpi->common;
9474 const RD_OPT *const rd_opt = &cpi->rd;
9475 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009476 MACROBLOCKD *const xd = &x->e_mbd;
9477 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009478#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009479 const int try_palette =
9480 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009481 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009482#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009483 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9484 const struct segmentation *const seg = &cm->seg;
9485 PREDICTION_MODE this_mode;
9486 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9487 unsigned char segment_id = mbmi->segment_id;
9488 int comp_pred, i, k;
9489 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Zoe Liu85b66462017-04-20 14:28:19 -07009490#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
9491 int_mv frame_comp_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9492#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009493 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009494 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009495#if CONFIG_EXT_INTER
9496 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
9497 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009498#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9500 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009501 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009502#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009503 AOM_LAST2_FLAG,
9504 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009505#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009506 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009507#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009508 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009509#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009510 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009511 };
9512 int64_t best_rd = best_rd_so_far;
9513 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9514 int64_t best_pred_diff[REFERENCE_MODES];
9515 int64_t best_pred_rd[REFERENCE_MODES];
9516 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009517 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9518 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009519 int best_mode_skippable = 0;
9520 int midx, best_mode_index = -1;
9521 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -07009522#if CONFIG_EXT_COMP_REFS
9523 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME][TOTAL_REFS_PER_FRAME];
9524#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009525 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -07009526#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009527 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009528 int64_t best_intra_rd = INT64_MAX;
9529 unsigned int best_pred_sse = UINT_MAX;
9530 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009531 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9532 int64_t dist_uvs[TX_SIZES_ALL];
9533 int skip_uvs[TX_SIZES_ALL];
9534 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009535#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009536 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009537#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009538#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009539 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009540 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009541 uint8_t directional_mode_skip_mask[INTRA_MODES];
9542#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009543#if CONFIG_FILTER_INTRA
9544 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009545 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009546#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009547 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009548 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9549 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9550 int best_skip2 = 0;
9551 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009552 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Yue Chen4d26acb2017-05-01 12:28:34 -07009553#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009554 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9555 int64_t best_single_inter_rd = INT64_MAX;
Yue Chen4d26acb2017-05-01 12:28:34 -07009556#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009557 int mode_skip_start = sf->mode_skip_start + 1;
9558 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9559 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9560 int64_t mode_threshold[MAX_MODES];
9561 int *mode_map = tile_data->mode_map[bsize];
9562 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009563#if CONFIG_PVQ
9564 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009565#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009566
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009567 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009568#if CONFIG_MOTION_VAR
9569 { NULL },
9570 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9571 { NULL },
9572 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9573#endif // CONFIG_MOTION_VAR
9574#if CONFIG_EXT_INTER
9575 NULL,
9576 NULL,
9577 NULL,
Fergus Simpson073c6f32017-02-17 12:13:48 -08009578#else // CONFIG_EXT_INTER
9579 NULL,
9580#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009581 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009582 };
9583
Urvang Joshib100db72016-10-12 16:28:56 -07009584#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009585 const int rows = block_size_high[bsize];
9586 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009587#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9588#if CONFIG_PALETTE
9589 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009590 const MODE_INFO *above_mi = xd->above_mi;
9591 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009592#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009593#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009594 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9595 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9596 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9597 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009598
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009599#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009600 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9601 int len = sizeof(uint16_t);
Jingning Hand064cf02017-06-01 10:00:39 -07009602 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(x->above_pred_buf);
9603 args.above_pred_buf[1] =
9604 CONVERT_TO_BYTEPTR(x->above_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009605 args.above_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07009606 CONVERT_TO_BYTEPTR(x->above_pred_buf + 2 * MAX_SB_SQUARE * len);
9607 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(x->left_pred_buf);
9608 args.left_pred_buf[1] =
9609 CONVERT_TO_BYTEPTR(x->left_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009610 args.left_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07009611 CONVERT_TO_BYTEPTR(x->left_pred_buf + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009612 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009613#endif // CONFIG_HIGHBITDEPTH
Jingning Hand064cf02017-06-01 10:00:39 -07009614 args.above_pred_buf[0] = x->above_pred_buf;
9615 args.above_pred_buf[1] = x->above_pred_buf + MAX_SB_SQUARE;
9616 args.above_pred_buf[2] = x->above_pred_buf + 2 * MAX_SB_SQUARE;
9617 args.left_pred_buf[0] = x->left_pred_buf;
9618 args.left_pred_buf[1] = x->left_pred_buf + MAX_SB_SQUARE;
9619 args.left_pred_buf[2] = x->left_pred_buf + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009620#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009621 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009622#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009623#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009624
Yaowu Xuf883b422016-08-30 14:01:10 -07009625 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009626
Urvang Joshib100db72016-10-12 16:28:56 -07009627#if CONFIG_PALETTE
9628 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07009629 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009630 if (above_mi)
9631 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9632 if (left_mi)
9633 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9634 }
Urvang Joshib100db72016-10-12 16:28:56 -07009635#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009636
Yaowu Xuc27fc142016-08-22 16:08:15 -07009637 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9638 &comp_mode_p);
9639
9640 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009641 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009642 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9643 for (i = 0; i < MB_MODE_COUNT; ++i) {
9644 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009645 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009646 }
9647 }
9648
9649 rd_cost->rate = INT_MAX;
9650#if CONFIG_SUPERTX
9651 *returnrate_nocoef = INT_MAX;
9652#endif // CONFIG_SUPERTX
9653
Zoe Liud1ac0322017-06-05 13:59:12 -07009654#if CONFIG_SPEED_REFS
9655 memset(x->mbmi_ext->ref_mvs, 0, sizeof(x->mbmi_ext->ref_mvs));
9656#endif // CONFIG_SPEED_REFS
9657
Yaowu Xuc27fc142016-08-22 16:08:15 -07009658 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9659 x->pred_mv_sad[ref_frame] = INT_MAX;
9660 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009661#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009662 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009663#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009664 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9665 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9666 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9667 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9668 }
9669 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009670#if CONFIG_GLOBAL_MOTION
9671 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009672 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009673 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9674 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009675 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009676#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009677 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009678#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009679#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009680 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Zoe Liu85b66462017-04-20 14:28:19 -07009681#if CONFIG_COMPOUND_SINGLEREF
9682 frame_mv[SR_NEW_NEWMV][ref_frame].as_int = INVALID_MV;
9683 frame_comp_mv[SR_NEW_NEWMV][ref_frame].as_int = INVALID_MV;
9684#endif // CONFIG_COMPOUND_SINGLEREF
Sarah Parkerc2d38712017-01-24 15:15:41 -08009685#if CONFIG_GLOBAL_MOTION
9686 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009687 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009688 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9689 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009690 .as_int;
9691#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009692 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009693#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009694#endif // CONFIG_EXT_INTER
9695 }
9696
Yaowu Xuc27fc142016-08-22 16:08:15 -07009697 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9698 MODE_INFO *const mi = xd->mi[0];
9699 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9700 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009701 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9702 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009703#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009704 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009705#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009706 candidates, mi_row, mi_col, NULL, NULL,
9707 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009708 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9709 MV_REFERENCE_FRAME rf[2];
9710 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009711 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9712 frame_mv[ZEROMV][rf[0]].as_int ||
9713 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9714 frame_mv[ZEROMV][rf[0]].as_int ||
9715 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9716 frame_mv[ZEROMV][rf[1]].as_int ||
9717 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009718 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9719 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009720 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009721
Yue Chencb60b182016-10-13 15:18:22 -07009722#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009723 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Jingning Hanad586b92017-05-23 10:24:57 -07009724
Yue Chenf7ba6472017-04-19 11:08:58 -07009725 if (check_num_overlappable_neighbors(mbmi) &&
9726 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009727 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9728 args.above_pred_buf, dst_width1,
9729 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009730 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009731 args.left_pred_buf, dst_width2,
9732 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07009733 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
9734 mi_col);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009735 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9736 args.above_pred_stride[0], args.left_pred_buf[0],
9737 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009738 }
Yue Chencb60b182016-10-13 15:18:22 -07009739#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009740
9741 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9742 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9743// Skip checking missing references in both single and compound reference
9744// modes. Note that a mode will be skipped iff both reference frames
9745// are masked out.
Zoe Liuc082bbc2017-05-17 13:31:37 -07009746#if CONFIG_EXT_COMP_REFS
9747 ref_frame_skip_mask[0] |= (1 << ref_frame);
9748 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9749#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07009750#if CONFIG_EXT_REFS
9751 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9752 ref_frame_skip_mask[0] |= (1 << ref_frame);
9753 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9754 } else {
9755#endif // CONFIG_EXT_REFS
9756 ref_frame_skip_mask[0] |= (1 << ref_frame);
9757 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9758#if CONFIG_EXT_REFS
9759 }
9760#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -07009761#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07009762 } else {
9763 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9764 // Skip fixed mv modes for poor references
9765 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9766 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9767 break;
9768 }
9769 }
9770 }
9771 // If the segment reference frame feature is enabled....
9772 // then do nothing if the current ref frame is not allowed..
9773 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9774 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9775 ref_frame_skip_mask[0] |= (1 << ref_frame);
9776 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9777 }
9778 }
9779
9780 // Disable this drop out case if the ref frame
9781 // segment level feature is enabled for this segment. This is to
9782 // prevent the possibility that we end up unable to pick any mode.
9783 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9784 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9785 // unless ARNR filtering is enabled in which case we want
9786 // an unfiltered alternative. We allow near/nearest as well
9787 // because they may result in zero-zero MVs but be cheaper.
9788 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009789 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009790 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9791#if CONFIG_EXT_REFS
9792 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9793 (1 << BWDREF_FRAME) |
9794#endif // CONFIG_EXT_REFS
9795 (1 << GOLDEN_FRAME);
9796 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9797 // TODO(zoeliu): To further explore whether following needs to be done for
9798 // BWDREF_FRAME as well.
9799 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009800#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009801 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009802 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009803 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009804 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009805#else
9806 zeromv.as_int = 0;
9807#endif // CONFIG_GLOBAL_MOTION
9808 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009809 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009810 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009811 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9812#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009813 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009814 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009815 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009816 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
Zoe Liu85b66462017-04-20 14:28:19 -07009817#if CONFIG_COMPOUND_SINGLEREF
9818 if (frame_mv[SR_NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int ||
9819 frame_comp_mv[SR_NEAREST_NEARMV][ALTREF_FRAME].as_int !=
9820 zeromv.as_int)
9821 mode_skip_mask[ALTREF_FRAME] |= (1 << SR_NEAREST_NEARMV);
9822#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009823#endif // CONFIG_EXT_INTER
9824 }
9825 }
9826
9827 if (cpi->rc.is_src_frame_alt_ref) {
9828 if (sf->alt_ref_search_fp) {
9829 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9830 mode_skip_mask[ALTREF_FRAME] = 0;
9831 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9832 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9833 }
9834 }
9835
9836 if (sf->alt_ref_search_fp)
9837 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9838 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9839 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9840
9841 if (sf->adaptive_mode_search) {
9842 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9843 cpi->rc.frames_since_golden >= 3)
Yaowu Xu36bad472017-05-16 18:29:53 -07009844 if ((x->pred_mv_sad[GOLDEN_FRAME] >> 1) > x->pred_mv_sad[LAST_FRAME])
Yaowu Xuc27fc142016-08-22 16:08:15 -07009845 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9846 }
9847
9848 if (bsize > sf->max_intra_bsize) {
9849 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9850 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9851 }
9852
9853 mode_skip_mask[INTRA_FRAME] |=
9854 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9855
9856 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9857 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9858 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9859
9860 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9861 while (midx > 4) {
9862 uint8_t end_pos = 0;
9863 for (i = 5; i < midx; ++i) {
9864 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9865 uint8_t tmp = mode_map[i];
9866 mode_map[i] = mode_map[i - 1];
9867 mode_map[i - 1] = tmp;
9868 end_pos = i;
9869 }
9870 }
9871 midx = end_pos;
9872 }
9873
9874 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9875 x->use_default_intra_tx_type = 1;
9876 else
9877 x->use_default_intra_tx_type = 0;
9878
9879 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9880 x->use_default_inter_tx_type = 1;
9881 else
9882 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009883#if CONFIG_PVQ
9884 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009885#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009886#if CONFIG_EXT_INTER
9887 for (i = 0; i < MB_MODE_COUNT; ++i)
9888 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9889 modelled_rd[i][ref_frame] = INT64_MAX;
9890#endif // CONFIG_EXT_INTER
9891
9892 for (midx = 0; midx < MAX_MODES; ++midx) {
9893 int mode_index;
9894 int mode_excluded = 0;
9895 int64_t this_rd = INT64_MAX;
9896 int disable_skip = 0;
9897 int compmode_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009898 int rate2 = 0, rate_y = 0, rate_uv = 0;
9899 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -07009900#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9901 int64_t distortion2_y = 0;
9902 int64_t total_sse_y = INT64_MAX;
9903#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009904 int skippable = 0;
9905 int this_skip2 = 0;
9906 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009907 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009908#if CONFIG_PVQ
9909 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009910#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009911 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009912 this_mode = av1_mode_order[mode_index].mode;
9913 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9914 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009915 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009916
9917#if CONFIG_EXT_INTER
9918 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9919 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -08009920 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009921 if (!is_interintra_allowed_bsize(bsize)) continue;
9922 }
9923
9924 if (is_inter_compound_mode(this_mode)) {
9925 frame_mv[this_mode][ref_frame].as_int =
9926 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9927 frame_mv[this_mode][second_ref_frame].as_int =
9928 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07009929#if CONFIG_COMPOUND_SINGLEREF
9930 } else if (is_inter_singleref_comp_mode(this_mode)) {
9931 frame_mv[this_mode][ref_frame].as_int =
9932 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9933 frame_comp_mv[this_mode][ref_frame].as_int =
9934 frame_mv[compound_ref1_mode(this_mode)][ref_frame].as_int;
9935#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009936 }
9937#endif // CONFIG_EXT_INTER
9938
9939 // Look at the reference frame of the best mode so far and set the
9940 // skip mask to look at a subset of the remaining modes.
9941 if (midx == mode_skip_start && best_mode_index >= 0) {
9942 switch (best_mbmode.ref_frame[0]) {
9943 case INTRA_FRAME: break;
9944 case LAST_FRAME:
9945 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9946 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9947 break;
9948#if CONFIG_EXT_REFS
9949 case LAST2_FRAME:
9950 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9951 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9952 break;
9953 case LAST3_FRAME:
9954 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9955 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9956 break;
9957#endif // CONFIG_EXT_REFS
9958 case GOLDEN_FRAME:
9959 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9960 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9961 break;
9962#if CONFIG_EXT_REFS
9963 case BWDREF_FRAME:
9964 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9965 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9966 break;
9967#endif // CONFIG_EXT_REFS
9968 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9969#if CONFIG_EXT_REFS
9970 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9971#endif // CONFIG_EXT_REFS
9972 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009973 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009974 case TOTAL_REFS_PER_FRAME:
9975 assert(0 && "Invalid Reference frame");
9976 break;
9977 }
9978 }
9979
9980 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009981 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009982 continue;
9983
Zoe Liuc082bbc2017-05-17 13:31:37 -07009984#if CONFIG_EXT_COMP_REFS
9985// TODO(zoeliu): Following toggle between #if 0/1 and the bug will manifest
9986// itself.
9987#if 0
9988 if (!(cpi->ref_frame_flags & flag_list[ref_frame]) ||
9989 (second_ref_frame > INTRA_FRAME &&
9990 (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))))
9991 printf("Frame=%d, bsize=%d, (mi_row,mi_col)=(%d,%d), ref_frame=%d, "
9992 "second_ref_frame=%d\n", cm->current_video_frame, bsize, mi_row,
9993 mi_col, ref_frame, second_ref_frame);
9994
9995 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) continue;
9996 if (second_ref_frame > INTRA_FRAME &&
9997 (!(cpi->ref_frame_flags & flag_list[second_ref_frame])))
9998 continue;
9999#endif // 0
10000
10001#if !USE_UNI_COMP_REFS
10002 // NOTE(zoeliu): Temporarily disable uni-directional comp refs
10003 if (second_ref_frame > INTRA_FRAME) {
10004 if (!((ref_frame < BWDREF_FRAME) ^ (second_ref_frame < BWDREF_FRAME)))
10005 continue;
10006 }
10007 assert(second_ref_frame <= INTRA_FRAME ||
10008 ((ref_frame < BWDREF_FRAME) ^ (second_ref_frame < BWDREF_FRAME)));
10009#endif // !USE_UNI_COMP_REFS
10010#endif // CONFIG_EXT_COMP_REFS
10011
Yaowu Xuc27fc142016-08-22 16:08:15 -070010012 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
10013
10014 // Test best rd so far against threshold for trying this mode.
10015 if (best_mode_skippable && sf->schedule_mode_search)
10016 mode_threshold[mode_index] <<= 1;
10017
10018 if (best_rd < mode_threshold[mode_index]) continue;
10019
Yunqing Wangff4fa062017-04-21 10:56:08 -070010020 // This is only used in motion vector unit test.
10021 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
10022
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +020010023#if CONFIG_ONE_SIDED_COMPOUND // Changes LL bitstream
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020010024#if CONFIG_EXT_REFS
10025 if (cpi->oxcf.pass == 0) {
10026 // Complexity-compression trade-offs
10027 // if (ref_frame == ALTREF_FRAME) continue;
10028 // if (ref_frame == BWDREF_FRAME) continue;
10029 if (second_ref_frame == ALTREF_FRAME) continue;
10030 // if (second_ref_frame == BWDREF_FRAME) continue;
10031 }
10032#endif
10033#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010034 comp_pred = second_ref_frame > INTRA_FRAME;
10035 if (comp_pred) {
10036 if (!cpi->allow_comp_inter_inter) continue;
10037
10038 // Skip compound inter modes if ARF is not available.
10039 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10040
10041 // Do not allow compound prediction if the segment level reference frame
10042 // feature is in use as in this case there can only be one reference.
10043 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10044
10045 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10046 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10047 continue;
10048
10049 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10050 } else {
10051 if (ref_frame != INTRA_FRAME)
10052 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10053 }
10054
10055 if (ref_frame == INTRA_FRAME) {
10056 if (sf->adaptive_mode_search)
10057 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10058 continue;
10059
10060 if (this_mode != DC_PRED) {
10061 // Disable intra modes other than DC_PRED for blocks with low variance
10062 // Threshold for intra skipping based on source variance
10063 // TODO(debargha): Specialize the threshold for super block sizes
10064 const unsigned int skip_intra_var_thresh = 64;
10065 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10066 x->source_variance < skip_intra_var_thresh)
10067 continue;
10068 // Only search the oblique modes if the best so far is
10069 // one of the neighboring directional modes
10070 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10071 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10072 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10073 continue;
10074 }
10075 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10076 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10077 }
10078 }
Sarah Parkere5299862016-08-16 14:57:37 -070010079#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010080 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010081 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010082 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010083#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010084 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010085#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010086 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10087 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010088#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010089 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010090#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010091 frame_mv, this_mode, ref_frames, bsize, -1,
10092 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010093 continue;
10094 }
10095
10096 mbmi->mode = this_mode;
10097 mbmi->uv_mode = DC_PRED;
10098 mbmi->ref_frame[0] = ref_frame;
10099 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010100#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010101 pmi->palette_size[0] = 0;
10102 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010103#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010104#if CONFIG_FILTER_INTRA
10105 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10106 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10107#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010108 // Evaluate all sub-pel filters irrespective of whether we can use
10109 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010110
10111 set_default_interp_filters(mbmi, cm->interp_filter);
10112
Yaowu Xuc27fc142016-08-22 16:08:15 -070010113 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010114 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010115
10116 x->skip = 0;
10117 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10118
10119 // Select prediction reference frames.
10120 for (i = 0; i < MAX_MB_PLANE; i++) {
10121 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10122 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10123 }
10124
Zoe Liu85b66462017-04-20 14:28:19 -070010125#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10126 // Single ref compound mode
10127 if (!comp_pred && is_inter_singleref_comp_mode(mbmi->mode)) {
10128 xd->block_refs[1] = xd->block_refs[0];
10129 for (i = 0; i < MAX_MB_PLANE; i++)
10130 xd->plane[i].pre[1] = xd->plane[i].pre[0];
10131 }
10132#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10133
Yue Chen4d26acb2017-05-01 12:28:34 -070010134#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010135 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yue Chen4d26acb2017-05-01 12:28:34 -070010136#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010137
10138 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010139 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010140 TX_SIZE uv_tx;
10141 struct macroblockd_plane *const pd = &xd->plane[1];
10142#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010143 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Joe Young830d4ce2017-05-30 17:48:13 -070010144 if (is_directional_mode && av1_use_angle_delta(bsize)) {
hui su45dc5972016-12-08 17:42:50 -080010145 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010146 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010147 if (!angle_stats_ready) {
10148 const int src_stride = x->plane[0].src.stride;
10149 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010150#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010151 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -070010152 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010153 directional_mode_skip_mask);
10154 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010155#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -070010156 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010157 directional_mode_skip_mask);
10158 angle_stats_ready = 1;
10159 }
10160 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010161 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -070010162 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
10163 intra_mode_cost[mbmi->mode], best_rd,
10164 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010165 } else {
10166 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010167 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010168 }
10169#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010170 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010171#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010172 rate_y = rd_stats_y.rate;
10173 distortion_y = rd_stats_y.dist;
10174 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010175
10176 if (rate_y == INT_MAX) continue;
10177
hui su5db97432016-10-14 16:10:14 -070010178#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010179 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010180#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010181
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010182 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10183 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010184 if (rate_uv_intra[uv_tx] == INT_MAX) {
10185 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010186 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10187 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010188#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010189 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010190#endif // CONFIG_PALETTE
10191
Yaowu Xuc27fc142016-08-22 16:08:15 -070010192#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010193 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10194#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010195#if CONFIG_FILTER_INTRA
10196 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10197#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010198 }
10199
10200 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010201 distortion_uv = dist_uvs[uv_tx];
10202 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010203 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010204#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010205 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010206 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10207 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10208 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10209 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10210 }
Urvang Joshib100db72016-10-12 16:28:56 -070010211#endif // CONFIG_PALETTE
10212
Yaowu Xuc27fc142016-08-22 16:08:15 -070010213#if CONFIG_EXT_INTRA
10214 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010215#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010216#if CONFIG_FILTER_INTRA
10217 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10218 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10219 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10220 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10221 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10222 }
10223#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010224
Jingning Han36fe3202017-02-20 22:31:49 -080010225#if CONFIG_CB4X4
10226 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10227 if (!x->skip_chroma_rd)
10228 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10229#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010230 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10231 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010232#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010233
Urvang Joshib100db72016-10-12 16:28:56 -070010234#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010235 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010236 rate2 += av1_cost_bit(
10237 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -070010238 }
Urvang Joshib100db72016-10-12 16:28:56 -070010239#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010240
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010241 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010242 // super_block_yrd above includes the cost of the tx_size in the
10243 // tokenonly rate, but for intra blocks, tx_size is always coded
10244 // (prediction granularity), so we account for it in the full rate,
10245 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010246 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010247 }
10248#if CONFIG_EXT_INTRA
10249 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -080010250#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010251 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -070010252 const int p_angle =
10253 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -070010254 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010255 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010256#endif // CONFIG_INTRA_INTERP
Joe Young830d4ce2017-05-30 17:48:13 -070010257 if (av1_use_angle_delta(bsize)) {
10258 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10259 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
10260 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010261 }
Joe Young830d4ce2017-05-30 17:48:13 -070010262 if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
10263 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -070010264 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10265 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010266 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010267#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010268#if CONFIG_FILTER_INTRA
10269 if (mbmi->mode == DC_PRED) {
10270 rate2 +=
10271 av1_cost_bit(cm->fc->filter_intra_probs[0],
10272 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10273 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10274 rate2 += write_uniform_cost(
10275 FILTER_INTRA_MODES,
10276 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10277 }
10278 }
10279 if (mbmi->uv_mode == DC_PRED) {
10280 rate2 +=
10281 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10282 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10283 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10284 rate2 += write_uniform_cost(
10285 FILTER_INTRA_MODES,
10286 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10287 }
10288#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -070010289 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010290 rate2 += intra_cost_penalty;
10291 distortion2 = distortion_y + distortion_uv;
Yushin Cho63927c42017-05-23 15:41:05 -070010292#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10293 if (bsize < BLOCK_8X8) distortion2_y = distortion_y;
10294#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010295 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010296 int_mv backup_ref_mv[2];
10297
Jingning Hanc41a5492017-02-24 11:18:52 -080010298#if !SUB8X8_COMP_REF
Jingning Han69d21012017-05-14 16:51:27 -070010299 if (bsize == BLOCK_4X4 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010300#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010301
Yaowu Xuc27fc142016-08-22 16:08:15 -070010302 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10303 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yue Chen4d26acb2017-05-01 12:28:34 -070010304#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010305 if (second_ref_frame == INTRA_FRAME) {
10306 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010307 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010308// TODO(debargha|geza.lore):
10309// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010310#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010311 mbmi->angle_delta[0] = 0;
10312 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010313#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010314 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010315#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010316#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010317#if CONFIG_FILTER_INTRA
10318 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10319 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10320#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010321 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010322#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010323 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010324 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010325
David Barker404b2e82017-03-27 13:07:47 +010010326#if CONFIG_EXT_INTER
10327 if (comp_pred) {
10328 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +010010329 int ref_mv_idx = 0;
10330 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10331 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10332 // mbmi->ref_mv_idx (like NEWMV)
10333 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10334 ref_mv_idx = 1;
10335
10336 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10337 int_mv this_mv =
10338 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +010010339 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10340 xd->n8_h << MI_SIZE_LOG2, xd);
10341 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10342 }
David Barker3dfba992017-04-03 16:10:09 +010010343 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10344 int_mv this_mv =
10345 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +010010346 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10347 xd->n8_h << MI_SIZE_LOG2, xd);
10348 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10349 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010350 }
Zoe Liu85b66462017-04-20 14:28:19 -070010351#if CONFIG_COMPOUND_SINGLEREF
10352 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
10353 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
10354 // TODO(zoeliu): To further investigate which ref_mv_idx should be
10355 // chosen for the mode of SR_NEAR_NEWMV.
10356 int ref_mv_idx = 0;
10357 // Special case: SR_NEAR_NEWMV mode use
10358 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10359 // mbmi->ref_mv_idx (like NEWMV)
10360 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx = 1;
10361
10362 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
10363 compound_ref1_mode(mbmi->mode) == NEWMV) {
10364 int_mv this_mv =
10365 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10366 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10367 xd->n8_h << MI_SIZE_LOG2, xd);
10368 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10369 }
10370 }
10371#endif // CONFIG_COMPOUND_SINGLEREF
David Barker404b2e82017-03-27 13:07:47 +010010372 } else {
10373#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -070010374 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +010010375 int ref;
10376 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10377 int_mv this_mv =
10378 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10379 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10380 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10381 xd->n8_h << MI_SIZE_LOG2, xd);
10382 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10383 }
10384 }
10385#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010386 }
David Barker404b2e82017-03-27 13:07:47 +010010387#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010388 {
10389 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10390 av1_init_rd_stats(&rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010391#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10392 // While av1 master uses rd_stats_y.rate through out the codebase,
10393 // which is set when handle_inter_moden is called, the daala-dist code
10394 // in rd_pick_partition() for cb4x4 and sub8x8 blocks need to know
10395 // .dist_y which comes from rd_stats_y.dist and rd_stats_y.sse.
10396 // The problem is rd_stats_y.dist and rd_stats_y.sse are sometimes not
10397 // initialized when rd_stats.skip = 1,
10398 // then instead rd_stats.dist and rd_stats.sse have the
10399 // combined luma and chroma dist and sse.
10400 // This can be seen inside motion_mode_rd(), which is called by
10401 // handle_inter_mode().
10402 if (bsize < BLOCK_8X8) av1_init_rd_stats(&rd_stats_y);
10403#endif
Angie Chiang76159122016-11-09 12:13:22 -080010404 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010405
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010406 // Point to variables that are maintained between loop iterations
10407 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010408#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010409 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010410 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010411#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010412 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10413 &rd_stats_uv, &disable_skip, frame_mv,
Zoe Liu85b66462017-04-20 14:28:19 -070010414#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10415 frame_comp_mv,
10416#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010417 mi_row, mi_col, &args, best_rd);
Angie Chiang76159122016-11-09 12:13:22 -080010418
10419 rate2 = rd_stats.rate;
10420 skippable = rd_stats.skip;
10421 distortion2 = rd_stats.dist;
10422 total_sse = rd_stats.sse;
10423 rate_y = rd_stats_y.rate;
10424 rate_uv = rd_stats_uv.rate;
Yushin Cho63927c42017-05-23 15:41:05 -070010425#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010426 if (bsize < BLOCK_8X8) {
10427 if (rd_stats_y.rate != INT_MAX) {
10428 assert(rd_stats_y.sse < INT64_MAX);
10429 assert(rd_stats_y.dist < INT64_MAX);
10430 }
10431 total_sse_y = rd_stats_y.sse;
10432 distortion2_y = rd_stats_y.dist;
10433 }
Yushin Cho63927c42017-05-23 15:41:05 -070010434#endif
Angie Chiang76159122016-11-09 12:13:22 -080010435 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010436
David Barker404b2e82017-03-27 13:07:47 +010010437// TODO(jingning): This needs some refactoring to improve code quality
10438// and reduce redundant steps.
10439#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070010440#if CONFIG_COMPOUND_SINGLEREF
10441 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
10442 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10443 ((mbmi->mode == NEWMV || mbmi->mode == SR_NEW_NEWMV ||
10444 mbmi->mode == NEW_NEWMV) &&
10445 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10446#else // !CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010010447 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +010010448 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10449 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10450 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Zoe Liu85b66462017-04-20 14:28:19 -070010451#endif // CONFIG_COMPOUND_SINGLEREF
10452#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010453 if ((mbmi->mode == NEARMV &&
10454 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10455 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Zoe Liu85b66462017-04-20 14:28:19 -070010456#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010457 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10458 MB_MODE_INFO backup_mbmi = *mbmi;
10459 int backup_skip = x->skip;
10460 int64_t tmp_ref_rd = this_rd;
10461 int ref_idx;
10462
Yue Chen6e601e92016-12-05 18:19:00 -080010463// TODO(jingning): This should be deprecated shortly.
10464#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010465 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010466#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010467 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010468#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010469 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010470 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010471
10472 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010473 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010474 // Dummy
10475 int_mv backup_fmv[2];
10476 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10477 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10478
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010479 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010480
10481 if (this_rd < INT64_MAX) {
Urvang Joshi70006e42017-06-14 16:08:55 -070010482 if (RDCOST(x->rdmult, rate_y + rate_uv, distortion2) <
10483 RDCOST(x->rdmult, 0, total_sse))
10484 tmp_ref_rd = RDCOST(
10485 x->rdmult, rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10486 distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010487 else
Urvang Joshi70006e42017-06-14 16:08:55 -070010488 tmp_ref_rd = RDCOST(
10489 x->rdmult, rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10490 rate_y - rate_uv,
10491 total_sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010492 }
10493#if CONFIG_VAR_TX
10494 for (i = 0; i < MAX_MB_PLANE; ++i)
10495 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10496 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010497#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010498
10499 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10500 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010501 int dummy_disable_skip = 0;
10502 int ref;
10503 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010504 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010505
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010506 av1_invalid_rd_stats(&tmp_rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010507
Jingning Han52617b22017-04-11 12:50:08 -070010508 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010509
Yaowu Xuc27fc142016-08-22 16:08:15 -070010510 mbmi->ref_mv_idx = 1 + ref_idx;
10511
David Barker3dfba992017-04-03 16:10:09 +010010512#if CONFIG_EXT_INTER
10513 if (comp_pred) {
10514 int ref_mv_idx = mbmi->ref_mv_idx;
10515 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10516 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10517 // mbmi->ref_mv_idx (like NEWMV)
10518 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10519 ref_mv_idx = 1 + mbmi->ref_mv_idx;
10520
10521 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10522 int_mv this_mv =
10523 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10524 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10525 xd->n8_h << MI_SIZE_LOG2, xd);
10526 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10527 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
10528 int_mv this_mv =
10529 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10530 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10531 xd->n8_h << MI_SIZE_LOG2, xd);
10532 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10533 }
10534
10535 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10536 int_mv this_mv =
10537 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
10538 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10539 xd->n8_h << MI_SIZE_LOG2, xd);
10540 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10541 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10542 int_mv this_mv =
10543 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10544 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10545 xd->n8_h << MI_SIZE_LOG2, xd);
10546 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10547 }
Zoe Liu85b66462017-04-20 14:28:19 -070010548#if CONFIG_COMPOUND_SINGLEREF
10549 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
10550 int ref_mv_idx = mbmi->ref_mv_idx;
10551 // Special case: SR_NEAR_NEWMV mode use
10552 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10553 // mbmi->ref_mv_idx (like NEWMV)
10554 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx = 1 + mbmi->ref_mv_idx;
10555
10556 // TODO(zoeliu): For the mode of SR_NEAREST_NEWMV, as it only runs
10557 // the "if", not the "else if",
10558 // mbmi_ext->ref_mvs[mbmi->ref_frame[0]] takes the
10559 // value for "NEWMV", instead of "NEARESTMV".
10560 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
10561 compound_ref1_mode(mbmi->mode) == NEWMV) {
10562 int_mv this_mv =
10563 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10564 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10565 xd->n8_h << MI_SIZE_LOG2, xd);
10566 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10567 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV ||
10568 compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10569 int_mv this_mv =
10570 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10571 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10572 xd->n8_h << MI_SIZE_LOG2, xd);
10573 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10574 }
10575#endif // CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010010576 } else {
10577#endif // CONFIG_EXT_INTER
10578 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10579 int_mv this_mv =
10580 (ref == 0)
10581 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10582 .this_mv
10583 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10584 .comp_mv;
10585 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10586 xd->n8_h << MI_SIZE_LOG2, xd);
10587 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10588 }
10589#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010590 }
David Barker3dfba992017-04-03 16:10:09 +010010591#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010592
10593 cur_mv =
10594 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10595 .this_mv;
10596 clamp_mv2(&cur_mv.as_mv, xd);
10597
Alex Converse0fa0f422017-04-24 12:51:14 -070010598 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010599 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010600#if CONFIG_EXT_INTER
10601 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -080010602#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010603
10604 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010605 av1_init_rd_stats(&tmp_rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010606#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10607 // With the same reason as 'rd_stats_y' passed to above
10608 // handle_inter_mode(), tmp_rd_stats_y.dist and
10609 // tmp_rd_stats_y.sse are sometimes not initialized, esp. when
10610 // tmp_rd_stats.skip = 1 and tmp_rd_stats.dist and .sse
10611 // represent combined luma and chroma .dist and .sse,
10612 // we should initialized tmp_rd_stats_y.
10613 if (bsize < BLOCK_8X8) av1_init_rd_stats(&tmp_rd_stats_y);
10614#endif
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010615 // Point to variables that are not maintained between iterations
10616 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010617#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010618 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010619 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010620#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070010621 tmp_alt_rd = handle_inter_mode(cpi, x, bsize, &tmp_rd_stats,
10622 &tmp_rd_stats_y, &tmp_rd_stats_uv,
10623 &dummy_disable_skip, frame_mv,
10624#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10625 frame_comp_mv,
10626#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10627 mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010628 // Prevent pointers from escaping local scope
10629 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010630#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010631 args.single_newmv_rate = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010632#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010633 }
10634
10635 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10636 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010637 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10638 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010639 tmp_rd_stats.rate +=
10640 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10641 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010642 }
10643
10644 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10645 mbmi->ref_mv_idx + idx_offset + 1 &&
10646 ref_idx < ref_set - 1) {
10647 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010648 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10649 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010650 tmp_rd_stats.rate +=
10651 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10652 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010653 }
10654
10655 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010656#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Urvang Joshi70006e42017-06-14 16:08:55 -070010657 tmp_alt_rd =
10658 RDCOST(x->rdmult, tmp_rd_stats.rate, tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010659#else
Urvang Joshi70006e42017-06-14 16:08:55 -070010660 if (RDCOST(x->rdmult, tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
Angie Chiang76159122016-11-09 12:13:22 -080010661 tmp_rd_stats.dist) <
Urvang Joshi70006e42017-06-14 16:08:55 -070010662 RDCOST(x->rdmult, 0, tmp_rd_stats.sse))
10663 tmp_alt_rd = RDCOST(
10664 x->rdmult, tmp_rd_stats.rate +
10665 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10666 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010667 else
Urvang Joshi70006e42017-06-14 16:08:55 -070010668 tmp_alt_rd = RDCOST(
10669 x->rdmult, tmp_rd_stats.rate +
10670 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10671 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10672 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010673#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010674 }
10675
10676 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010677 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010678 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010679 distortion2 = tmp_rd_stats.dist;
10680 skippable = tmp_rd_stats.skip;
10681 rate_y = tmp_rd_stats_y.rate;
10682 rate_uv = tmp_rd_stats_uv.rate;
10683 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010684 this_rd = tmp_alt_rd;
10685 tmp_ref_rd = tmp_alt_rd;
10686 backup_mbmi = *mbmi;
10687 backup_skip = x->skip;
Yushin Cho63927c42017-05-23 15:41:05 -070010688#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10689 if (bsize < BLOCK_8X8) {
Yushin Choc0f6bf22017-06-09 16:08:02 -070010690 if (tmp_rd_stats_y.rate != INT_MAX) {
10691 assert(tmp_rd_stats_y.sse < INT64_MAX);
10692 assert(tmp_rd_stats_y.dist < INT64_MAX);
10693 }
Yushin Cho63927c42017-05-23 15:41:05 -070010694 total_sse_y = tmp_rd_stats_y.sse;
10695 distortion2_y = tmp_rd_stats_y.dist;
10696 }
10697#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010698#if CONFIG_VAR_TX
10699 for (i = 0; i < MAX_MB_PLANE; ++i)
10700 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10701 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010702#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010703 } else {
10704 *mbmi = backup_mbmi;
10705 x->skip = backup_skip;
10706 }
10707 }
10708
10709 frame_mv[NEARMV][ref_frame] = backup_mv;
10710 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10711 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10712#if CONFIG_VAR_TX
10713 for (i = 0; i < MAX_MB_PLANE; ++i)
10714 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10715 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010716#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010717 }
10718 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10719 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010720
10721 if (this_rd == INT64_MAX) continue;
10722
Jingning Hanc41a5492017-02-24 11:18:52 -080010723#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010724 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010725#else
Jingning Han69d21012017-05-14 16:51:27 -070010726 if (mbmi->sb_type != BLOCK_4X4)
Jingning Hanc41a5492017-02-24 11:18:52 -080010727 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010728#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010729
10730 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10731 }
10732
Yaowu Xuc27fc142016-08-22 16:08:15 -070010733 // Estimate the reference frame signaling cost and add it
10734 // to the rolling cost variable.
10735 if (comp_pred) {
Zoe Liuc082bbc2017-05-17 13:31:37 -070010736#if CONFIG_EXT_COMP_REFS
10737 rate2 += ref_costs_comp[ref_frame][second_ref_frame];
10738#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -070010739 rate2 += ref_costs_comp[ref_frame];
10740#if CONFIG_EXT_REFS
10741 rate2 += ref_costs_comp[second_ref_frame];
10742#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -070010743#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -070010744 } else {
10745 rate2 += ref_costs_single[ref_frame];
10746 }
10747
Zoe Liu85b66462017-04-20 14:28:19 -070010748#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10749 // Add the cost to signal single/comp mode in single ref.
10750 if (!comp_pred && cm->reference_mode != COMPOUND_REFERENCE) {
10751 aom_prob singleref_comp_mode_p = av1_get_inter_mode_prob(cm, xd);
10752 rate2 += av1_cost_bit(singleref_comp_mode_p,
10753 is_inter_singleref_comp_mode(mbmi->mode));
10754 }
10755#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10756
Yue Chen69f18e12016-09-08 14:48:15 -070010757#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010758 if (ref_frame == INTRA_FRAME) {
10759#else
10760 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010761#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010762 if (skippable) {
10763 // Back out the coefficient coding costs
10764 rate2 -= (rate_y + rate_uv);
10765 rate_y = 0;
10766 rate_uv = 0;
10767 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010768 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010769 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Urvang Joshi70006e42017-06-14 16:08:55 -070010770 if (RDCOST(x->rdmult, rate_y + rate_uv + rate_skip0, distortion2) <
10771 RDCOST(x->rdmult, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010772 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010773 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010774 } else {
10775 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010776 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010777 distortion2 = total_sse;
10778 assert(total_sse >= 0);
10779 rate2 -= (rate_y + rate_uv);
10780 this_skip2 = 1;
10781 rate_y = 0;
10782 rate_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -070010783#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010784 if (bsize < BLOCK_8X8) {
10785 assert(total_sse_y < INT64_MAX);
10786 distortion2_y = total_sse_y;
10787 }
Yushin Cho63927c42017-05-23 15:41:05 -070010788#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010789 }
10790 } else {
10791 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010792 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010793 }
10794
10795 // Calculate the final RD estimate for this mode.
Urvang Joshi70006e42017-06-14 16:08:55 -070010796 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010797#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010798 } else {
10799 this_skip2 = mbmi->skip;
Urvang Joshi70006e42017-06-14 16:08:55 -070010800 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010801 if (this_skip2) {
10802 rate_y = 0;
10803 rate_uv = 0;
10804 }
Yue Chen69f18e12016-09-08 14:48:15 -070010805#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010806 }
10807
Yushin Choc0f6bf22017-06-09 16:08:02 -070010808#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10809 if ((bsize < BLOCK_8X8) && (rate2 != INT_MAX)) {
10810 assert(distortion2_y < INT64_MAX);
10811 }
10812#endif
10813
Yaowu Xuc27fc142016-08-22 16:08:15 -070010814 if (ref_frame == INTRA_FRAME) {
10815 // Keep record of best intra rd
10816 if (this_rd < best_intra_rd) {
10817 best_intra_rd = this_rd;
10818 best_intra_mode = mbmi->mode;
10819 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010820#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Emil Keyder01770b32017-01-20 18:03:11 -050010821 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010822 if (this_rd < best_single_inter_rd) {
10823 best_single_inter_rd = this_rd;
10824 best_single_inter_ref = mbmi->ref_frame[0];
10825 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010826#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010827 }
10828
10829 if (!disable_skip && ref_frame == INTRA_FRAME) {
10830 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010831 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010832 }
10833
10834 // Did this mode help.. i.e. is it the new best mode
10835 if (this_rd < best_rd || x->skip) {
10836 if (!mode_excluded) {
10837 // Note index of best mode so far
10838 best_mode_index = mode_index;
10839
10840 if (ref_frame == INTRA_FRAME) {
10841 /* required for left and above block mv */
10842 mbmi->mv[0].as_int = 0;
10843 } else {
10844 best_pred_sse = x->pred_sse[ref_frame];
10845 }
10846
10847 rd_cost->rate = rate2;
10848#if CONFIG_SUPERTX
10849 if (x->skip)
10850 *returnrate_nocoef = rate2;
10851 else
10852 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010853 *returnrate_nocoef -= av1_cost_bit(
10854 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10855 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10856 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010857#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -070010858#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10859 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -080010860 const MOTION_MODE motion_allowed = motion_mode_allowed(
10861#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10862 0, xd->global_motion,
10863#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10864 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -080010865 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -070010866 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -080010867 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010868 *returnrate_nocoef -=
10869 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -070010870#else
10871 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010872#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010873#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010874#endif // CONFIG_SUPERTX
10875 rd_cost->dist = distortion2;
10876 rd_cost->rdcost = this_rd;
10877 best_rd = this_rd;
10878 best_mbmode = *mbmi;
10879 best_skip2 = this_skip2;
10880 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010881 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10882 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010883 best_rate_uv = rate_uv;
Yushin Cho63927c42017-05-23 15:41:05 -070010884#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010885 if (bsize < BLOCK_8X8) {
10886 assert(distortion2_y < INT64_MAX);
10887 rd_cost->dist_y = distortion2_y;
10888 }
Yushin Cho63927c42017-05-23 15:41:05 -070010889#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010890#if CONFIG_VAR_TX
10891 for (i = 0; i < MAX_MB_PLANE; ++i)
10892 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10893 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010894#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010895 }
10896 }
Yushin Choc0f6bf22017-06-09 16:08:02 -070010897#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10898 if ((bsize < BLOCK_8X8) && (rd_cost->rate != INT_MAX)) {
10899 assert(rd_cost->dist_y < INT64_MAX);
10900 }
10901#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010902 /* keep record of best compound/single-only prediction */
10903 if (!disable_skip && ref_frame != INTRA_FRAME) {
10904 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10905
10906 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10907 single_rate = rate2 - compmode_cost;
10908 hybrid_rate = rate2;
10909 } else {
10910 single_rate = rate2;
10911 hybrid_rate = rate2 + compmode_cost;
10912 }
10913
Urvang Joshi70006e42017-06-14 16:08:55 -070010914 single_rd = RDCOST(x->rdmult, single_rate, distortion2);
10915 hybrid_rd = RDCOST(x->rdmult, hybrid_rate, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010916
10917 if (!comp_pred) {
10918 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10919 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10920 } else {
10921 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10922 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10923 }
10924 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10925 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10926 }
10927
Yaowu Xuc27fc142016-08-22 16:08:15 -070010928 if (x->skip && !comp_pred) break;
10929 }
10930
10931 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10932 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10933 is_inter_mode(best_mbmode.mode)) ||
10934 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10935 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010936 int skip_blk = 0;
10937 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010938
10939 x->use_default_inter_tx_type = 0;
10940 x->use_default_intra_tx_type = 0;
10941
10942 *mbmi = best_mbmode;
10943
10944 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10945
10946 // Select prediction reference frames.
10947 for (i = 0; i < MAX_MB_PLANE; i++) {
10948 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10949 if (has_second_ref(mbmi))
10950 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10951 }
10952
Zoe Liu85b66462017-04-20 14:28:19 -070010953#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10954 // Single ref compound mode
10955 if (!has_second_ref(mbmi) && is_inter_singleref_comp_mode(mbmi->mode)) {
10956 xd->block_refs[1] = xd->block_refs[0];
10957 for (i = 0; i < MAX_MB_PLANE; i++)
10958 xd->plane[i].pre[1] = xd->plane[i].pre[0];
10959 }
10960#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10961
Yaowu Xuc27fc142016-08-22 16:08:15 -070010962 if (is_inter_mode(mbmi->mode)) {
Jingning Hanc44009c2017-05-06 11:36:49 -070010963 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -070010964#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010965 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -080010966 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010967 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10968 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010969 }
Yue Chencb60b182016-10-13 15:18:22 -070010970#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010971 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010972#if CONFIG_VAR_TX
10973 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010974 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010975 } else {
10976 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010977 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010978 for (idy = 0; idy < xd->n8_h; ++idy)
10979 for (idx = 0; idx < xd->n8_w; ++idx)
10980 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010981 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010982 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10983 }
10984
Angie Chiangb5dda482016-11-02 16:19:58 -070010985 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010986#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010987 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010988 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010989#endif // CONFIG_VAR_TX
10990 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010991 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010992 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010993 }
10994
Urvang Joshi70006e42017-06-14 16:08:55 -070010995 if (RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate,
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010996 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070010997 RDCOST(x->rdmult, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010998 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010999 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
11000 rd_stats_uv.rate = 0;
11001 rd_stats_y.dist = rd_stats_y.sse;
11002 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011003 } else {
11004 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011005 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011006 }
11007
Urvang Joshi70006e42017-06-14 16:08:55 -070011008 if (RDCOST(x->rdmult, best_rate_y + best_rate_uv, rd_cost->dist) >
11009 RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate,
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011010 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011011#if CONFIG_VAR_TX
11012 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080011013#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011014 best_mbmode.tx_type = mbmi->tx_type;
11015 best_mbmode.tx_size = mbmi->tx_size;
11016#if CONFIG_VAR_TX
11017 for (idy = 0; idy < xd->n8_h; ++idy)
11018 for (idx = 0; idx < xd->n8_w; ++idx)
11019 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
11020
11021 for (i = 0; i < MAX_MB_PLANE; ++i)
11022 memcpy(ctx->blk_skip[i], x->blk_skip[i],
11023 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070011024
11025 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080011026#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011027 rd_cost->rate +=
11028 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
11029 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Urvang Joshi70006e42017-06-14 16:08:55 -070011030 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011031 best_skip2 = skip_blk;
Yushin Choc0f6bf22017-06-09 16:08:02 -070011032#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11033 if (bsize < BLOCK_8X8) {
11034 assert(rd_cost->rate != INT_MAX);
11035 assert(rd_cost->dist_y < INT64_MAX);
11036 rd_cost->dist_y = rd_stats_y.dist;
11037 }
11038#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011039 }
11040 }
11041
Yushin Choc0f6bf22017-06-09 16:08:02 -070011042#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11043 if ((bsize < BLOCK_8X8) && (rd_cost->rate != INT_MAX)) {
11044 assert(rd_cost->dist_y < INT64_MAX);
11045 }
11046#endif
11047
Urvang Joshib100db72016-10-12 16:28:56 -070011048#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011049 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -070011050 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011051 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011052#if CONFIG_SUPERTX
11053 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011054#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080011055 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
11056 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070011057 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011058 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080011059 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011060 uint8_t *const best_palette_color_map =
11061 x->palette_buffer->best_palette_color_map;
11062 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080011063 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011064
11065 mbmi->mode = DC_PRED;
11066 mbmi->uv_mode = DC_PRED;
11067 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011068 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070011069 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080011070 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
11071 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
11072 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080011073 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
11074 memcpy(color_map, best_palette_color_map,
11075 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011076 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
11077 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070011078 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
11079 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011080 if (rate_uv_intra[uv_tx] == INT_MAX) {
11081 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070011082 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
11083 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011084 pmi_uv[uv_tx] = *pmi;
11085#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011086 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
11087#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011088#if CONFIG_FILTER_INTRA
11089 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
11090#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011091 }
11092 mbmi->uv_mode = mode_uv[uv_tx];
11093 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080011094 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011095 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
11096 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
11097 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080011098 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011099#if CONFIG_EXT_INTRA
11100 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011101#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011102#if CONFIG_FILTER_INTRA
11103 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
11104 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
11105 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
11106 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
11107 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
11108 }
11109#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011110 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
11111 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
11112 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011113 rate2 += ref_costs_single[INTRA_FRAME];
11114
11115 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011116 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011117#if CONFIG_SUPERTX
11118 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080011119#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011120 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011121 } else {
11122#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011123 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080011124#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011125 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011126 }
Urvang Joshi70006e42017-06-14 16:08:55 -070011127 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011128 if (this_rd < best_rd) {
11129 best_mode_index = 3;
11130 mbmi->mv[0].as_int = 0;
11131 rd_cost->rate = rate2;
11132#if CONFIG_SUPERTX
11133 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011134#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011135 rd_cost->dist = distortion2;
11136 rd_cost->rdcost = this_rd;
11137 best_rd = this_rd;
11138 best_mbmode = *mbmi;
11139 best_skip2 = 0;
11140 best_mode_skippable = skippable;
11141 }
11142 }
11143PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070011144#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011145
hui su5db97432016-10-14 16:10:14 -070011146#if CONFIG_FILTER_INTRA
11147 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070011148 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070011149 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070011150#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080011151 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070011152#endif // CONFIG_PALETTE
11153 !dc_skipped && best_mode_index >= 0 &&
11154 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070011155 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080011156 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
11157 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070011158#if CONFIG_EXT_INTRA
11159 uv_angle_delta,
11160#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070011161#if CONFIG_PALETTE
11162 pmi_uv, palette_ctx,
11163#endif // CONFIG_PALETTE
11164 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011165 &best_mode_index, &best_skip2, &best_mode_skippable,
11166#if CONFIG_SUPERTX
11167 returnrate_nocoef,
11168#endif // CONFIG_SUPERTX
11169 best_pred_rd, &best_mbmode, rd_cost);
11170 }
hui su5db97432016-10-14 16:10:14 -070011171#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011172
Zoe Liu85b66462017-04-20 14:28:19 -070011173// The inter modes' rate costs are not calculated precisely in some cases.
11174// Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11175// ZEROMV. Here, checks are added for those cases, and the mode decisions
11176// are corrected.
11177#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
11178// NOTE: For SR_NEW_NEWMV, no need to check as the two mvs from the same ref
11179// are surely different from each other.
11180#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -070011181 if (best_mbmode.mode == NEWMV
11182#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070011183 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011184#endif // CONFIG_EXT_INTER
11185 ) {
11186 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11187 best_mbmode.ref_frame[1] };
11188 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011189 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070011190 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011191#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011192 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11193 cm->allow_high_precision_mv, bsize,
11194 mi_col, mi_row, 0)
11195 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011196 zeromv[1].as_int = comp_pred_mode
11197 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11198 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011199 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011200 .as_int
11201 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011202#else
11203 zeromv[0].as_int = 0;
11204 zeromv[1].as_int = 0;
11205#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011206 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011207 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011208 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011209 : INT_MAX;
11210
11211 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11212 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11213 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11214 best_mbmode.mode = NEARMV;
11215 best_mbmode.ref_mv_idx = i;
11216 }
11217 }
11218
11219 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11220 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011221 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011222 best_mbmode.mode = ZEROMV;
11223 } else {
11224 int_mv nearestmv[2];
11225 int_mv nearmv[2];
11226
11227#if CONFIG_EXT_INTER
11228 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11229 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11230 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11231 } else {
11232 nearmv[0] = frame_mv[NEARMV][refs[0]];
11233 nearmv[1] = frame_mv[NEARMV][refs[1]];
11234 }
11235#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011236 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011237 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011238 : INT_MAX;
11239
11240 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11241 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11242 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11243
11244 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11245 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11246 best_mbmode.mode = NEARMV;
11247 best_mbmode.ref_mv_idx = i;
11248 }
11249 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011250#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011251 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11252 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11253 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11254 } else {
11255 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11256 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11257 }
11258
11259 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011260 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011261#if CONFIG_EXT_INTER
11262 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011263 } else {
11264 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
11265 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
11266 : INT_MAX;
11267
11268 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11269 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11270 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11271
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -070011272 // Try switching to the NEAR_NEARMV mode
11273 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011274 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11275 best_mbmode.mode = NEAR_NEARMV;
11276 best_mbmode.ref_mv_idx = i;
11277 }
11278 }
11279
David Barker3dfba992017-04-03 16:10:09 +010011280 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010011281 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11282 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11283 best_mbmode.mode = ZERO_ZEROMV;
11284 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011285#else
11286 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011287 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11288 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011289 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010011290 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011291#endif // CONFIG_EXT_INTER
11292 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011293 }
11294
David Barker9620bcd2017-03-22 14:46:42 +000011295 // Make sure that the ref_mv_idx is only nonzero when we're
11296 // using a mode which can support ref_mv_idx
11297 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010011298#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070011299#if CONFIG_COMPOUND_SINGLEREF
11300 !(best_mbmode.mode == NEWMV || best_mbmode.mode == SR_NEW_NEWMV ||
11301 best_mbmode.mode == NEW_NEWMV ||
11302 have_nearmv_in_inter_mode(best_mbmode.mode))) {
11303#else // !CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010011304 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
11305 have_nearmv_in_inter_mode(best_mbmode.mode))) {
Zoe Liu85b66462017-04-20 14:28:19 -070011306#endif // CONFIG_COMPOUND_SINGLEREF
11307#else // !CONFIG_EXT_INTER
David Barker9620bcd2017-03-22 14:46:42 +000011308 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
Zoe Liu85b66462017-04-20 14:28:19 -070011309#endif // CONFIG_EXT_INTER
David Barker9620bcd2017-03-22 14:46:42 +000011310 best_mbmode.ref_mv_idx = 0;
11311 }
11312
David Barkercdcac6d2016-12-01 17:04:16 +000011313 {
Jingning Han731af492016-11-17 11:53:23 -080011314 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11315 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011316 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011317 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011318#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011319 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11320 best_mbmode.ref_frame[1] };
11321 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011322 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011323 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011324 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070011325 zeromv[1].as_int = (refs[1] != NONE_FRAME)
11326 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11327 cm->allow_high_precision_mv,
11328 bsize, mi_col, mi_row, 0)
11329 .as_int
11330 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000011331 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11332 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11333#else
11334 zeromv[0].as_int = zeromv[1].as_int = 0;
11335#endif // CONFIG_GLOBAL_MOTION
11336 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11337 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11338#if CONFIG_EXT_INTER
11339 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11340#else
Emil Keyder01770b32017-01-20 18:03:11 -050011341 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011342 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11343#endif // CONFIG_EXT_INTER
11344 ) {
11345 best_mbmode.mode = ZEROMV;
11346 }
David Barker68e6e862016-11-24 15:10:15 +000011347 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011348 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011349
11350 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11351 rd_cost->rate = INT_MAX;
11352 rd_cost->rdcost = INT64_MAX;
11353 return;
11354 }
11355
Yaowu Xuc27fc142016-08-22 16:08:15 -070011356#if CONFIG_DUAL_FILTER
11357 assert((cm->interp_filter == SWITCHABLE) ||
11358 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11359 !is_inter_block(&best_mbmode));
11360 assert((cm->interp_filter == SWITCHABLE) ||
11361 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11362 !is_inter_block(&best_mbmode));
11363 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11364 assert((cm->interp_filter == SWITCHABLE) ||
11365 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11366 !is_inter_block(&best_mbmode));
11367 assert((cm->interp_filter == SWITCHABLE) ||
11368 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11369 !is_inter_block(&best_mbmode));
11370 }
11371#else
11372 assert((cm->interp_filter == SWITCHABLE) ||
11373 (cm->interp_filter == best_mbmode.interp_filter) ||
11374 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011375#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011376
11377 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011378 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11379 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011380
11381 // macroblock modes
11382 *mbmi = best_mbmode;
11383 x->skip |= best_skip2;
11384
Yue Chen19e7aa82016-11-30 14:05:39 -080011385// Note: this section is needed since the mode may have been forced to
11386// ZEROMV by the all-zero mode handling of ref-mv.
11387#if CONFIG_GLOBAL_MOTION
11388 if (mbmi->mode == ZEROMV
11389#if CONFIG_EXT_INTER
11390 || mbmi->mode == ZERO_ZEROMV
11391#endif // CONFIG_EXT_INTER
11392 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011393#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11394 // Correct the motion mode for ZEROMV
11395 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11396#if SEPARATE_GLOBAL_MOTION
11397 0, xd->global_motion,
11398#endif // SEPARATE_GLOBAL_MOTION
11399 xd->mi[0]);
11400 if (mbmi->motion_mode > last_motion_mode_allowed)
11401 mbmi->motion_mode = last_motion_mode_allowed;
11402#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11403
11404 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011405 if (is_nontrans_global_motion(xd)) {
11406#if CONFIG_DUAL_FILTER
11407 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11408 ? EIGHTTAP_REGULAR
11409 : cm->interp_filter;
11410 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11411 ? EIGHTTAP_REGULAR
11412 : cm->interp_filter;
11413#else
11414 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11415 : cm->interp_filter;
11416#endif // CONFIG_DUAL_FILTER
11417 }
11418 }
11419#endif // CONFIG_GLOBAL_MOTION
11420
Yaowu Xuc27fc142016-08-22 16:08:15 -070011421 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11422 if (mbmi->mode != NEWMV)
11423 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11424 else
11425 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11426 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011427
11428 for (i = 0; i < REFERENCE_MODES; ++i) {
11429 if (best_pred_rd[i] == INT64_MAX)
11430 best_pred_diff[i] = INT_MIN;
11431 else
11432 best_pred_diff[i] = best_rd - best_pred_rd[i];
11433 }
11434
11435 x->skip |= best_mode_skippable;
11436
11437 assert(best_mode_index >= 0);
11438
11439 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11440 best_mode_skippable);
11441
Urvang Joshib100db72016-10-12 16:28:56 -070011442#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011443 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11444 restore_uv_color_map(cpi, x);
11445 }
Urvang Joshib100db72016-10-12 16:28:56 -070011446#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011447}
11448
Urvang Joshi52648442016-10-13 17:27:51 -070011449void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11450 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011451 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011452 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011453 PICK_MODE_CONTEXT *ctx,
11454 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011455 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011456 MACROBLOCKD *const xd = &x->e_mbd;
11457 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11458 unsigned char segment_id = mbmi->segment_id;
11459 const int comp_pred = 0;
11460 int i;
11461 int64_t best_pred_diff[REFERENCE_MODES];
11462 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -070011463#if CONFIG_EXT_COMP_REFS
11464 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME][TOTAL_REFS_PER_FRAME];
11465#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011466 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -070011467#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011468 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011469 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011470 int64_t this_rd = INT64_MAX;
11471 int rate2 = 0;
11472 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011473 (void)mi_row;
11474 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011475
11476 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11477 &comp_mode_p);
11478
11479 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11480 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11481 x->pred_mv_sad[i] = INT_MAX;
11482
11483 rd_cost->rate = INT_MAX;
11484
11485 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11486
Urvang Joshib100db72016-10-12 16:28:56 -070011487#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011488 mbmi->palette_mode_info.palette_size[0] = 0;
11489 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011490#endif // CONFIG_PALETTE
11491
hui su5db97432016-10-14 16:10:14 -070011492#if CONFIG_FILTER_INTRA
11493 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11494 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11495#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011496 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011497 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011498 mbmi->uv_mode = DC_PRED;
11499 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011500 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011501#if CONFIG_GLOBAL_MOTION
11502 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011503 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011504 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11505 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011506 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011507#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011508 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011509#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011510 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011511 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011512
Yaowu Xuc27fc142016-08-22 16:08:15 -070011513 mbmi->ref_mv_idx = 0;
11514 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011515
Yue Chendead17d2017-04-20 16:19:39 -070011516 mbmi->motion_mode = SIMPLE_TRANSLATION;
11517#if CONFIG_MOTION_VAR
11518 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
11519#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070011520#if CONFIG_WARPED_MOTION
11521 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
11522 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
11523 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
11524 }
11525#endif
Yue Chendead17d2017-04-20 16:19:39 -070011526
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011527 set_default_interp_filters(mbmi, cm->interp_filter);
11528
11529 if (cm->interp_filter != SWITCHABLE) {
11530 best_filter = cm->interp_filter;
11531 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011532 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011533 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011534 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11535 int rs;
11536 int best_rs = INT_MAX;
11537 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11538#if CONFIG_DUAL_FILTER
11539 int k;
11540 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11541#else
11542 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011543#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011544 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011545 if (rs < best_rs) {
11546 best_rs = rs;
11547#if CONFIG_DUAL_FILTER
11548 best_filter = mbmi->interp_filter[0];
11549#else
11550 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011551#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011552 }
11553 }
11554 }
11555 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011556// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070011557#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011558 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011559#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011560 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011561#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011562 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011563
11564 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011565 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011566
11567 // Estimate the reference frame signaling cost and add it
11568 // to the rolling cost variable.
11569 rate2 += ref_costs_single[LAST_FRAME];
Urvang Joshi70006e42017-06-14 16:08:55 -070011570 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011571
11572 rd_cost->rate = rate2;
11573 rd_cost->dist = distortion2;
11574 rd_cost->rdcost = this_rd;
Yushin Cho63927c42017-05-23 15:41:05 -070011575#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11576 if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2;
11577#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011578 if (this_rd >= best_rd_so_far) {
11579 rd_cost->rate = INT_MAX;
11580 rd_cost->rdcost = INT64_MAX;
11581 return;
11582 }
11583
11584#if CONFIG_DUAL_FILTER
11585 assert((cm->interp_filter == SWITCHABLE) ||
11586 (cm->interp_filter == mbmi->interp_filter[0]));
11587#else
11588 assert((cm->interp_filter == SWITCHABLE) ||
11589 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011590#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011591
Yaowu Xuf883b422016-08-30 14:01:10 -070011592 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11593 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011594
Yaowu Xuf883b422016-08-30 14:01:10 -070011595 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011596
11597 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11598}
11599
Yue Chencb60b182016-10-13 15:18:22 -070011600#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070011601// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070011602//
11603// The OBMC predictor is computed as:
11604//
11605// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011606// AOM_BLEND_A64(Mh(x),
11607// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011608// PLeft(x, y))
11609//
Yaowu Xuf883b422016-08-30 14:01:10 -070011610// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070011611// rounding, this can be written as:
11612//
Yaowu Xuf883b422016-08-30 14:01:10 -070011613// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011614// Mh(x) * Mv(y) * P(x,y) +
11615// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011616// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011617//
11618// Where :
11619//
Yaowu Xuf883b422016-08-30 14:01:10 -070011620// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
11621// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011622//
11623// This function computes 'wsrc' and 'mask' as:
11624//
11625// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011626// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070011627// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011628// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011629//
11630// mask(x, y) = Mh(x) * Mv(y)
11631//
11632// These can then be used to efficiently approximate the error for any
11633// predictor P in the context of the provided neighbouring predictors by
11634// computing:
11635//
11636// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011637// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011638//
Yaowu Xuf883b422016-08-30 14:01:10 -070011639static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011640 const MACROBLOCKD *xd, int mi_row,
11641 int mi_col, const uint8_t *above,
11642 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070011643 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011644 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
11645 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080011646 const int bw = xd->n8_w << MI_SIZE_LOG2;
11647 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070011648 int32_t *mask_buf = x->mask_buf;
11649 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011650 const int wsrc_stride = bw;
11651 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070011652 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011653#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011654 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
11655#else
11656 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011657#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011658
11659 // plane 0 should not be subsampled
11660 assert(xd->plane[0].subsampling_x == 0);
11661 assert(xd->plane[0].subsampling_y == 0);
11662
Yaowu Xuf883b422016-08-30 14:01:10 -070011663 av1_zero_array(wsrc_buf, bw * bh);
11664 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011665
11666 // handle above row
11667 if (xd->up_available) {
11668 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011669 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011670 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011671 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070011672 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
11673 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011674
11675 assert(miw > 0);
11676
11677 i = 0;
11678 do { // for each mi in the above row
11679 const int mi_col_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070011680 const MB_MODE_INFO *above_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011681 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070011682#if CONFIG_CHROMA_SUB8X8
11683 if (above_mbmi->sb_type < BLOCK_8X8)
11684 above_mbmi =
11685 &xd->mi[mi_col_offset + 1 + mi_row_offset * xd->mi_stride]->mbmi;
11686#endif
Jingning Han680b09e2017-05-22 16:42:36 -070011687 const BLOCK_SIZE a_bsize = AOMMAX(above_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070011688 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011689 const int neighbor_bw = mi_step * MI_SIZE;
11690
11691 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070011692 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
11693 neighbor_count += 2;
11694 else
11695 neighbor_count++;
11696 if (neighbor_count > neighbor_limit) break;
11697
Yaowu Xuc27fc142016-08-22 16:08:15 -070011698 const int tmp_stride = above_stride;
11699 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
11700 int32_t *mask = mask_buf + (i * MI_SIZE);
11701
11702 if (!is_hbd) {
11703 const uint8_t *tmp = above;
11704
11705 for (row = 0; row < overlap; ++row) {
11706 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011707 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011708 for (col = 0; col < neighbor_bw; ++col) {
11709 wsrc[col] = m1 * tmp[col];
11710 mask[col] = m0;
11711 }
11712 wsrc += wsrc_stride;
11713 mask += mask_stride;
11714 tmp += tmp_stride;
11715 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011716#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011717 } else {
11718 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11719
11720 for (row = 0; row < overlap; ++row) {
11721 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011722 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011723 for (col = 0; col < neighbor_bw; ++col) {
11724 wsrc[col] = m1 * tmp[col];
11725 mask[col] = m0;
11726 }
11727 wsrc += wsrc_stride;
11728 mask += mask_stride;
11729 tmp += tmp_stride;
11730 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011731#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011732 }
11733 }
11734
11735 above += neighbor_bw;
11736 i += mi_step;
11737 } while (i < miw);
11738 }
11739
11740 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011741 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11742 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011743 }
11744
11745 // handle left column
11746 if (xd->left_available) {
11747 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011748 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011749 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011750 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070011751 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
11752 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011753
11754 assert(mih > 0);
11755
11756 i = 0;
11757 do { // for each mi in the left column
11758 const int mi_row_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070011759 MB_MODE_INFO *left_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011760 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070011761
11762#if CONFIG_CHROMA_SUB8X8
11763 if (left_mbmi->sb_type < BLOCK_8X8)
11764 left_mbmi =
11765 &xd->mi[mi_col_offset + (mi_row_offset + 1) * xd->mi_stride]->mbmi;
11766#endif
Jingning Han680b09e2017-05-22 16:42:36 -070011767 const BLOCK_SIZE l_bsize = AOMMAX(left_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070011768 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011769 const int neighbor_bh = mi_step * MI_SIZE;
11770
11771 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070011772 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
11773 neighbor_count += 2;
11774 else
11775 neighbor_count++;
11776 if (neighbor_count > neighbor_limit) break;
11777
Yaowu Xuc27fc142016-08-22 16:08:15 -070011778 const int tmp_stride = left_stride;
11779 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11780 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11781
11782 if (!is_hbd) {
11783 const uint8_t *tmp = left;
11784
11785 for (row = 0; row < neighbor_bh; ++row) {
11786 for (col = 0; col < overlap; ++col) {
11787 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011788 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11789 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11790 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11791 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011792 }
11793 wsrc += wsrc_stride;
11794 mask += mask_stride;
11795 tmp += tmp_stride;
11796 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011797#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011798 } else {
11799 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
11800
11801 for (row = 0; row < neighbor_bh; ++row) {
11802 for (col = 0; col < overlap; ++col) {
11803 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011804 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11805 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11806 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11807 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011808 }
11809 wsrc += wsrc_stride;
11810 mask += mask_stride;
11811 tmp += tmp_stride;
11812 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011813#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011814 }
11815 }
11816
11817 left += neighbor_bh * left_stride;
11818 i += mi_step;
11819 } while (i < mih);
11820 }
11821
11822 if (!is_hbd) {
11823 const uint8_t *src = x->plane[0].src.buf;
11824
11825 for (row = 0; row < bh; ++row) {
11826 for (col = 0; col < bw; ++col) {
11827 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11828 }
11829 wsrc_buf += wsrc_stride;
11830 src += x->plane[0].src.stride;
11831 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011832#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011833 } else {
11834 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11835
11836 for (row = 0; row < bh; ++row) {
11837 for (col = 0; col < bw; ++col) {
11838 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11839 }
11840 wsrc_buf += wsrc_stride;
11841 src += x->plane[0].src.stride;
11842 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011843#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011844 }
11845}
Yue Chenf27b1602017-01-13 11:11:43 -080011846
11847#if CONFIG_NCOBMC
11848void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
11849 int mi_row, int mi_col) {
11850 const AV1_COMMON *const cm = &cpi->common;
11851 MACROBLOCKD *const xd = &x->e_mbd;
11852 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11853 MB_MODE_INFO backup_mbmi;
11854 BLOCK_SIZE bsize = mbmi->sb_type;
11855 int ref, skip_blk, backup_skip = x->skip;
11856 int64_t rd_causal;
11857 RD_STATS rd_stats_y, rd_stats_uv;
11858 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
11859 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
11860
11861 // Recompute the best causal predictor and rd
11862 mbmi->motion_mode = SIMPLE_TRANSLATION;
11863 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
11864 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
11865 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
11866 assert(cfg != NULL);
11867 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
11868 &xd->block_refs[ref]->sf);
11869 }
Jingning Han91d9a792017-04-18 12:01:52 -070011870 av1_setup_dst_planes(x->e_mbd.plane, bsize,
11871 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080011872
Jingning Hanc44009c2017-05-06 11:36:49 -070011873 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chenf27b1602017-01-13 11:11:43 -080011874
11875 av1_subtract_plane(x, bsize, 0);
11876 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
11877 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
11878 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
11879 if (rd_stats_y.skip && rd_stats_uv.skip) {
11880 rd_stats_y.rate = rate_skip1;
11881 rd_stats_uv.rate = 0;
11882 rd_stats_y.dist = rd_stats_y.sse;
11883 rd_stats_uv.dist = rd_stats_uv.sse;
11884 skip_blk = 0;
Urvang Joshi70006e42017-06-14 16:08:55 -070011885 } else if (RDCOST(x->rdmult,
Yue Chenf27b1602017-01-13 11:11:43 -080011886 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
11887 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070011888 RDCOST(x->rdmult, rate_skip1,
Yue Chenf27b1602017-01-13 11:11:43 -080011889 (rd_stats_y.sse + rd_stats_uv.sse))) {
11890 rd_stats_y.rate = rate_skip1;
11891 rd_stats_uv.rate = 0;
11892 rd_stats_y.dist = rd_stats_y.sse;
11893 rd_stats_uv.dist = rd_stats_uv.sse;
11894 skip_blk = 1;
11895 } else {
11896 rd_stats_y.rate += rate_skip0;
11897 skip_blk = 0;
11898 }
11899 backup_skip = skip_blk;
11900 backup_mbmi = *mbmi;
Urvang Joshi70006e42017-06-14 16:08:55 -070011901 rd_causal = RDCOST(x->rdmult, (rd_stats_y.rate + rd_stats_uv.rate),
Yue Chenf27b1602017-01-13 11:11:43 -080011902 (rd_stats_y.dist + rd_stats_uv.dist));
Urvang Joshi70006e42017-06-14 16:08:55 -070011903 rd_causal +=
11904 RDCOST(x->rdmult, av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
Yue Chenf27b1602017-01-13 11:11:43 -080011905
11906 // Check non-causal mode
11907 mbmi->motion_mode = OBMC_CAUSAL;
11908 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
11909
11910 av1_subtract_plane(x, bsize, 0);
11911 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
11912 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
11913 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
11914 if (rd_stats_y.skip && rd_stats_uv.skip) {
11915 rd_stats_y.rate = rate_skip1;
11916 rd_stats_uv.rate = 0;
11917 rd_stats_y.dist = rd_stats_y.sse;
11918 rd_stats_uv.dist = rd_stats_uv.sse;
11919 skip_blk = 0;
Urvang Joshi70006e42017-06-14 16:08:55 -070011920 } else if (RDCOST(x->rdmult,
Yue Chenf27b1602017-01-13 11:11:43 -080011921 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
11922 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070011923 RDCOST(x->rdmult, rate_skip1,
Yue Chenf27b1602017-01-13 11:11:43 -080011924 (rd_stats_y.sse + rd_stats_uv.sse))) {
11925 rd_stats_y.rate = rate_skip1;
11926 rd_stats_uv.rate = 0;
11927 rd_stats_y.dist = rd_stats_y.sse;
11928 rd_stats_uv.dist = rd_stats_uv.sse;
11929 skip_blk = 1;
11930 } else {
11931 rd_stats_y.rate += rate_skip0;
11932 skip_blk = 0;
11933 }
11934
11935 if (rd_causal >
Urvang Joshi70006e42017-06-14 16:08:55 -070011936 RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate +
11937 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
Yue Chenf27b1602017-01-13 11:11:43 -080011938 (rd_stats_y.dist + rd_stats_uv.dist))) {
11939 x->skip = skip_blk;
11940 } else {
11941 *mbmi = backup_mbmi;
11942 x->skip = backup_skip;
11943 }
11944}
Fergus Simpson4063a682017-02-28 16:52:22 -080011945#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070011946#endif // CONFIG_MOTION_VAR