blob: 79fe13eb3487b767d4cce97ccfbc13f43f286dbe [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
1758 av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
1759 blk_row, tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04001760#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001761 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001762#endif
hui sub8a6fd62017-05-10 10:57:57 -07001763#if CONFIG_DPCM_INTRA
1764 const int block_raster_idx =
1765 av1_block_index_to_raster_order(tx_size, block);
1766 const PREDICTION_MODE mode =
1767 (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
1768 TX_TYPE tx_type = get_tx_type((plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV,
1769 xd, block, tx_size);
1770 if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
1771 int8_t skip;
1772 av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
1773 plane_bsize, tx_size, tx_type, a, l, &skip);
1774 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1775 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1776 OUTPUT_HAS_DECODED_PIXELS);
1777 goto CALCULATE_RD;
1778 }
1779#endif // CONFIG_DPCM_INTRA
Angie Chiang62e54cd2017-04-06 10:45:56 -07001780 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
1781 }
1782
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001783#if !CONFIG_TXK_SEL
Angie Chiang62e54cd2017-04-06 10:45:56 -07001784 // full forward transform and quantization
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001785 const int coeff_ctx = combine_entropy_contexts(*a, *l);
Sarah Parker345366a2017-06-15 12:13:01 -07001786#if DISABLE_TRELLISQ_SEARCH
1787 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1788 coeff_ctx, AV1_XFORM_QUANT_B);
1789#else
Angie Chiang62e54cd2017-04-06 10:45:56 -07001790 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1791 coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07001792 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Sarah Parker345366a2017-06-15 12:13:01 -07001793#endif // DISABLE_TRELLISQ_SEARCH
Angie Chiang62e54cd2017-04-06 10:45:56 -07001794
1795 if (!is_inter_block(mbmi)) {
1796 struct macroblock_plane *const p = &x->plane[plane];
Angie Chiangbc2288c2017-04-09 15:41:17 -07001797 av1_inverse_transform_block_facade(xd, plane, block, blk_row, blk_col,
1798 p->eobs[block]);
Angie Chiang808d8592017-04-06 18:36:55 -07001799 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1800 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1801 OUTPUT_HAS_DECODED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001802 } else {
Angie Chiang808d8592017-04-06 18:36:55 -07001803 av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
1804 tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
1805 OUTPUT_HAS_PREDICTED_PIXELS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806 }
Luc Trudeauaa94baa2017-04-27 10:52:21 -04001807#if CONFIG_CFL
1808 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1809 struct macroblockd_plane *const pd = &xd->plane[plane];
1810 const int dst_stride = pd->dst.stride;
1811 uint8_t *dst =
1812 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1813 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
1814 }
1815#endif
hui sub8a6fd62017-05-10 10:57:57 -07001816#if CONFIG_DPCM_INTRA
1817CALCULATE_RD : {}
1818#endif // CONFIG_DPCM_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07001819 rd = RDCOST(x->rdmult, 0, this_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820 if (args->this_rd + rd > args->best_rd) {
1821 args->exit_early = 1;
1822 return;
1823 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001824#if !CONFIG_PVQ
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07001825 const PLANE_TYPE plane_type = get_plane_type(plane);
1826 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07001827 const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
Angie Chiang05917872017-04-15 12:28:56 -07001828 this_rd_stats.rate =
1829 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l,
1830 args->use_fast_coef_costing);
Angie Chiang65a39bb2017-04-11 16:50:04 -07001831#else // !CONFIG_PVQ
1832 this_rd_stats.rate = x->rate;
1833#endif // !CONFIG_PVQ
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001834#else // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001835 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
1836 tx_size, a, l, args->use_fast_coef_costing,
1837 &this_rd_stats);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07001838#endif // !CONFIG_TXK_SEL
Angie Chiang65a39bb2017-04-11 16:50:04 -07001839
1840#if !CONFIG_PVQ
Angie Chiang3963d632016-11-10 18:41:40 -08001841#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08001842 av1_update_txb_coeff_cost(&this_rd_stats, plane, tx_size, blk_row, blk_col,
1843 this_rd_stats.rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08001844#endif // CONFIG_RD_DEBUG
Yushin Cho6341f5c2017-03-24 14:36:28 -07001845 av1_set_txb_context(x, plane, block, tx_size, a, l);
Fergus Simpson4063a682017-02-28 16:52:22 -08001846#endif // !CONFIG_PVQ
Angie Chiangb3a12b52017-03-23 14:53:10 -07001847
Urvang Joshi70006e42017-06-14 16:08:55 -07001848 rd1 = RDCOST(x->rdmult, this_rd_stats.rate, this_rd_stats.dist);
1849 rd2 = RDCOST(x->rdmult, 0, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001850
1851 // TODO(jingning): temporarily enabled only for luma component
Yaowu Xuf883b422016-08-30 14:01:10 -07001852 rd = AOMMIN(rd1, rd2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001853
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001854#if !CONFIG_PVQ
1855 this_rd_stats.skip &= !x->plane[plane].eobs[block];
1856#else
1857 this_rd_stats.skip &= x->pvq_skip[plane];
Fergus Simpson4063a682017-02-28 16:52:22 -08001858#endif // !CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001859 av1_merge_rd_stats(&args->rd_stats, &this_rd_stats);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001860
Yaowu Xuc27fc142016-08-22 16:08:15 -07001861 args->this_rd += rd;
1862
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001863#if CONFIG_DAALA_DIST
1864 if (!(plane == 0 && plane_bsize >= BLOCK_8X8 &&
1865 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))) {
1866#endif
1867 if (args->this_rd > args->best_rd) {
1868 args->exit_early = 1;
1869 return;
1870 }
1871#if CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07001872 }
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001873#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001874}
1875
Yushin Cho7a428ba2017-01-12 16:28:49 -08001876#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001877static void daala_dist_sub8x8_txfm_rd(MACROBLOCK *x, BLOCK_SIZE bsize,
1878 struct rdcost_block_args *args) {
Yushin Cho7a428ba2017-01-12 16:28:49 -08001879 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001880 const struct macroblockd_plane *const pd = &xd->plane[0];
1881 const struct macroblock_plane *const p = &x->plane[0];
Yushin Cho4483e3d2017-04-18 19:41:20 -07001882 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001883 const int src_stride = p->src.stride;
1884 const int dst_stride = pd->dst.stride;
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001885 const uint8_t *src = &p->src.buf[0];
1886 const uint8_t *dst = &pd->dst.buf[0];
1887 const int16_t *pred = &pd->pred[0];
1888 const int bw = block_size_wide[bsize];
1889 const int bh = block_size_high[bsize];
Yushin Cho7a428ba2017-01-12 16:28:49 -08001890
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001891 int i, j;
1892 int64_t rd, rd1, rd2;
1893 int qm = OD_HVS_QM;
1894 int use_activity_masking = 0;
1895 unsigned int tmp1, tmp2;
1896 int qindex = x->qindex;
Yushin Cho04749122017-05-25 14:19:07 -07001897#if CONFIG_PVQ
1898 use_activity_masking = x->daala_enc.use_activity_masking;
1899#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -08001900
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001901 assert((bw & 0x07) == 0);
1902 assert((bh & 0x07) == 0);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001903
Yushin Cho8ab875d2017-06-23 14:47:21 -07001904#if CONFIG_HIGHBITDEPTH
1905 uint8_t *pred8;
1906 DECLARE_ALIGNED(16, uint16_t, pred16[MAX_TX_SQUARE]);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001907
Yushin Cho8ab875d2017-06-23 14:47:21 -07001908 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
1909 pred8 = CONVERT_TO_BYTEPTR(pred16);
1910 else
1911 pred8 = (uint8_t *)pred16;
1912#else
1913 DECLARE_ALIGNED(16, uint8_t, pred8[MAX_TX_SQUARE]);
1914#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -08001915
Yushin Cho8ab875d2017-06-23 14:47:21 -07001916#if CONFIG_HIGHBITDEPTH
1917 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1918 for (j = 0; j < bh; j++)
1919 for (i = 0; i < bw; i++)
1920 CONVERT_TO_SHORTPTR(pred8)[j * bw + i] = pred[j * bw + i];
1921 } else {
1922#endif
1923 for (j = 0; j < bh; j++)
1924 for (i = 0; i < bw; i++) pred8[j * bw + i] = pred[j * bw + i];
1925#if CONFIG_HIGHBITDEPTH
1926 }
1927#endif // CONFIG_HIGHBITDEPTH
1928
1929 tmp1 = av1_daala_dist(xd, src, src_stride, pred8, bw, bw, bh, bw, bh, qm,
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001930 use_activity_masking, qindex);
Yushin Cho8ab875d2017-06-23 14:47:21 -07001931 tmp2 = av1_daala_dist(xd, src, src_stride, dst, dst_stride, bw, bh, bw, bh,
1932 qm, use_activity_masking, qindex);
Yushin Cho4483e3d2017-04-18 19:41:20 -07001933
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001934 if (!is_inter_block(mbmi)) {
1935 args->rd_stats.sse = (int64_t)tmp1 * 16;
1936 args->rd_stats.dist = (int64_t)tmp2 * 16;
1937 } else {
1938 // For inter mode, the decoded pixels are provided in pd->pred,
1939 // while the predicted pixels are in dst.
1940 args->rd_stats.sse = (int64_t)tmp2 * 16;
1941 args->rd_stats.dist = (int64_t)tmp1 * 16;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001942 }
1943
Urvang Joshi70006e42017-06-14 16:08:55 -07001944 rd1 = RDCOST(x->rdmult, args->rd_stats.rate, args->rd_stats.dist);
1945 rd2 = RDCOST(x->rdmult, 0, args->rd_stats.sse);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001946 rd = AOMMIN(rd1, rd2);
1947
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001948 args->rd_stats.rdcost = rd;
1949 args->this_rd = rd;
Yushin Cho04eb9592017-06-21 17:35:06 -07001950
1951 if (args->this_rd > args->best_rd) args->exit_early = 1;
Yushin Cho7a428ba2017-01-12 16:28:49 -08001952}
Fergus Simpson4063a682017-02-28 16:52:22 -08001953#endif // CONFIG_DAALA_DIST
Yushin Cho7a428ba2017-01-12 16:28:49 -08001954
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001955static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
1956 RD_STATS *rd_stats, int64_t ref_best_rd, int plane,
1957 BLOCK_SIZE bsize, TX_SIZE tx_size,
1958 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001959 MACROBLOCKD *const xd = &x->e_mbd;
1960 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001962 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001963 args.x = x;
1964 args.cpi = cpi;
1965 args.best_rd = ref_best_rd;
1966 args.use_fast_coef_costing = use_fast_coef_casting;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001967 av1_init_rd_stats(&args.rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001968
1969 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
1970
Yaowu Xuf883b422016-08-30 14:01:10 -07001971 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001972
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001973 av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
1974 &args);
Yushin Cho7a428ba2017-01-12 16:28:49 -08001975#if CONFIG_DAALA_DIST
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001976 if (!args.exit_early && plane == 0 && bsize >= BLOCK_8X8 &&
Yushin Cho7a428ba2017-01-12 16:28:49 -08001977 (tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
Yushin Cho30a2c5f2017-06-07 14:18:54 -07001978 daala_dist_sub8x8_txfm_rd(x, bsize, &args);
1979#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -08001980
Yaowu Xuc27fc142016-08-22 16:08:15 -07001981 if (args.exit_early) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001982 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001983 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08001984 *rd_stats = args.rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985 }
1986}
1987
1988#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001989void av1_txfm_rd_in_plane_supertx(MACROBLOCK *x, const AV1_COMP *cpi, int *rate,
1990 int64_t *distortion, int *skippable,
1991 int64_t *sse, int64_t ref_best_rd, int plane,
1992 BLOCK_SIZE bsize, TX_SIZE tx_size,
1993 int use_fast_coef_casting) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001994 MACROBLOCKD *const xd = &x->e_mbd;
1995 const struct macroblockd_plane *const pd = &xd->plane[plane];
1996 struct rdcost_block_args args;
Yaowu Xuf883b422016-08-30 14:01:10 -07001997 av1_zero(args);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001998 args.cpi = cpi;
1999 args.x = x;
2000 args.best_rd = ref_best_rd;
2001 args.use_fast_coef_costing = use_fast_coef_casting;
2002
2003#if CONFIG_EXT_TX
2004 assert(tx_size < TX_SIZES);
2005#endif // CONFIG_EXT_TX
2006
2007 if (plane == 0) xd->mi[0]->mbmi.tx_size = tx_size;
2008
Yaowu Xuf883b422016-08-30 14:01:10 -07002009 av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002010
Yaowu Xuc27fc142016-08-22 16:08:15 -07002011 block_rd_txfm(plane, 0, 0, 0, get_plane_block_size(bsize, pd), tx_size,
2012 &args);
2013
2014 if (args.exit_early) {
2015 *rate = INT_MAX;
2016 *distortion = INT64_MAX;
2017 *sse = INT64_MAX;
2018 *skippable = 0;
2019 } else {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002020 *distortion = args.rd_stats.dist;
2021 *rate = args.rd_stats.rate;
2022 *sse = args.rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002023 *skippable = !x->plane[plane].eobs[0];
2024 }
2025}
2026#endif // CONFIG_SUPERTX
2027
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002028static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002029 BLOCK_SIZE bsize, TX_SIZE tx_size) {
2030 const AV1_COMMON *const cm = &cpi->common;
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002031 const MACROBLOCKD *const xd = &x->e_mbd;
2032 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002033
2034 const int tx_select =
2035 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
2036
2037 if (tx_select) {
2038 const int is_inter = is_inter_block(mbmi);
2039 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
2040 : intra_tx_size_cat_lookup[bsize];
2041 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
2042 const int depth = tx_size_to_depth(coded_tx_size);
2043 const int tx_size_ctx = get_tx_size_context(xd);
Yue Chen56e226e2017-05-02 16:21:40 -07002044 int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
2045#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
2046 if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size)
2047 r_tx_size += av1_cost_bit(cm->fc->quarter_tx_size_prob,
2048 tx_size == quarter_txsize_lookup[bsize]);
2049#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
Urvang Joshifeb925f2016-12-05 10:37:29 -08002050 return r_tx_size;
2051 } else {
2052 return 0;
2053 }
2054}
2055
Angie Chiang65201562017-04-10 15:23:28 -07002056// #TODO(angiebird): use this function whenever it's possible
Angie Chiang05917872017-04-15 12:28:56 -07002057int av1_tx_type_cost(const AV1_COMP *cpi, const MACROBLOCKD *xd,
2058 BLOCK_SIZE bsize, int plane, TX_SIZE tx_size,
2059 TX_TYPE tx_type) {
2060 if (plane > 0) return 0;
2061
Jingning Han243b66b2017-06-23 12:11:47 -07002062#if CONFIG_VAR_TX
2063 tx_size = get_min_tx_size(tx_size);
2064#endif
2065
Angie Chiang65201562017-04-10 15:23:28 -07002066 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
2067 const int is_inter = is_inter_block(mbmi);
2068#if CONFIG_EXT_TX
2069 const AV1_COMMON *cm = &cpi->common;
2070 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
2071 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
2072 const int ext_tx_set =
2073 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
2074 if (is_inter) {
2075 if (ext_tx_set > 0)
2076 return cpi
2077 ->inter_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]][tx_type];
2078 } else {
2079 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
2080 return cpi->intra_tx_type_costs[ext_tx_set][txsize_sqr_map[tx_size]]
2081 [mbmi->mode][tx_type];
2082 }
2083 }
2084#else
2085 (void)bsize;
2086 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2087 !FIXED_TX_TYPE) {
2088 if (is_inter) {
2089 return cpi->inter_tx_type_costs[tx_size][tx_type];
2090 } else {
2091 return cpi->intra_tx_type_costs[tx_size]
2092 [intra_mode_to_tx_type_context[mbmi->mode]]
2093 [tx_type];
2094 }
2095 }
2096#endif // CONFIG_EXT_TX
2097 return 0;
2098}
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002099static int64_t txfm_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2100 RD_STATS *rd_stats, int64_t ref_best_rd, BLOCK_SIZE bs,
2101 TX_TYPE tx_type, int tx_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07002102 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002103 MACROBLOCKD *const xd = &x->e_mbd;
2104 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2105 int64_t rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002106 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002107 int s0, s1;
2108 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002109 const int tx_select =
2110 cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8;
Urvang Joshifeb925f2016-12-05 10:37:29 -08002111
2112 const int r_tx_size = tx_size_cost(cpi, x, bs, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002113
2114 assert(skip_prob > 0);
2115#if CONFIG_EXT_TX && CONFIG_RECT_TX
2116 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed_bsize(bs)));
2117#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2118
Yaowu Xuf883b422016-08-30 14:01:10 -07002119 s0 = av1_cost_bit(skip_prob, 0);
2120 s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002121
2122 mbmi->tx_type = tx_type;
2123 mbmi->tx_size = tx_size;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002124 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, tx_size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002125 cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002126 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002127#if !CONFIG_TXK_SEL
Angie Chiang05917872017-04-15 12:28:56 -07002128 int plane = 0;
2129 rd_stats->rate += av1_tx_type_cost(cpi, xd, bs, plane, tx_size, tx_type);
2130#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002131
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002132 if (rd_stats->skip) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133 if (is_inter) {
Urvang Joshi70006e42017-06-14 16:08:55 -07002134 rd = RDCOST(x->rdmult, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002135 } else {
Urvang Joshi70006e42017-06-14 16:08:55 -07002136 rd = RDCOST(x->rdmult, s1 + r_tx_size * tx_select, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002137 }
2138 } else {
Urvang Joshi70006e42017-06-14 16:08:55 -07002139 rd = RDCOST(x->rdmult, rd_stats->rate + s0 + r_tx_size * tx_select,
2140 rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002141 }
2142
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002143 if (tx_select) rd_stats->rate += r_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002144
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002145 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
2146 !(rd_stats->skip))
Urvang Joshi70006e42017-06-14 16:08:55 -07002147 rd = AOMMIN(rd, RDCOST(x->rdmult, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002148
2149 return rd;
2150}
2151
Angie Chiang2d147c12017-04-05 11:23:59 -07002152static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
2153 TX_TYPE tx_type, TX_SIZE tx_size) {
Urvang Joshi0d1e4ff2017-04-27 16:17:25 -07002154 const MACROBLOCKD *const xd = &x->e_mbd;
2155 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Angie Chiang2d147c12017-04-05 11:23:59 -07002156 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2157 const int is_inter = is_inter_block(mbmi);
2158 int prune = 0;
2159 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2160 // passing -1 in for tx_type indicates that all 1D
2161 // transforms should be considered for pruning
2162 prune = prune_tx_types(cpi, bs, x, xd, -1);
2163
Angie Chianga4fa1902017-04-05 15:26:09 -07002164 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
Angie Chiang2d147c12017-04-05 11:23:59 -07002165 if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
2166 return 1;
2167 if (!is_inter && x->use_default_intra_tx_type &&
2168 tx_type != get_default_tx_type(0, xd, 0, tx_size))
2169 return 1;
2170 if (is_inter && x->use_default_inter_tx_type &&
2171 tx_type != get_default_tx_type(0, xd, 0, tx_size))
2172 return 1;
2173 if (max_tx_size >= TX_32X32 && tx_size == TX_4X4) return 1;
2174#if CONFIG_EXT_TX
2175 const AV1_COMMON *const cm = &cpi->common;
2176 int ext_tx_set =
2177 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
2178 if (is_inter) {
2179 if (!ext_tx_used_inter[ext_tx_set][tx_type]) return 1;
2180 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2181 if (!do_tx_type_search(tx_type, prune)) return 1;
2182 }
2183 } else {
2184 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2185 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) return 1;
2186 }
2187 if (!ext_tx_used_intra[ext_tx_set][tx_type]) return 1;
2188 }
2189#else // CONFIG_EXT_TX
2190 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) return 1;
2191 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2192 !do_tx_type_search(tx_type, prune))
2193 return 1;
2194#endif // CONFIG_EXT_TX
2195 return 0;
2196}
2197
Yue Chen5e606542017-05-24 17:03:17 -07002198#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Urvang Joshi52648442016-10-13 17:27:51 -07002199static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
2200 MACROBLOCK *x, int *r, int64_t *d, int *s,
2201 int64_t *sse, int64_t ref_best_rd) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002202 RD_STATS rd_stats;
2203 int64_t rd = txfm_yrd(cpi, x, &rd_stats, ref_best_rd, bs, DCT_DCT,
2204 max_txsize_lookup[bs]);
2205 *r = rd_stats.rate;
2206 *d = rd_stats.dist;
2207 *s = rd_stats.skip;
2208 *sse = rd_stats.sse;
2209 return rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002210}
Yue Chen5e606542017-05-24 17:03:17 -07002211#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002212
Urvang Joshi52648442016-10-13 17:27:51 -07002213static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002214 RD_STATS *rd_stats, int64_t ref_best_rd,
Urvang Joshi52648442016-10-13 17:27:51 -07002215 BLOCK_SIZE bs) {
2216 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217 MACROBLOCKD *const xd = &x->e_mbd;
2218 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2219 TX_TYPE tx_type, best_tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002220 int64_t this_rd, best_rd = INT64_MAX;
Yaowu Xuf883b422016-08-30 14:01:10 -07002221 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
2222 int s0 = av1_cost_bit(skip_prob, 0);
2223 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002224 const int is_inter = is_inter_block(mbmi);
2225 int prune = 0;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002226 const int plane = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002227#if CONFIG_EXT_TX
2228 int ext_tx_set;
2229#endif // CONFIG_EXT_TX
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002230 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002231
2232 mbmi->tx_size = tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
Jingning Hane67b38a2016-11-04 10:30:00 -07002233#if CONFIG_VAR_TX
2234 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002235#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002236#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002237 ext_tx_set =
2238 get_ext_tx_set(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002239#endif // CONFIG_EXT_TX
2240
2241 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
2242#if CONFIG_EXT_TX
2243 prune = prune_tx_types(cpi, bs, x, xd, ext_tx_set);
2244#else
2245 prune = prune_tx_types(cpi, bs, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08002246#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002247#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002248 if (get_ext_tx_types(mbmi->tx_size, bs, is_inter, cm->reduced_tx_set_used) >
2249 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002250 !xd->lossless[mbmi->segment_id]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07002251#if CONFIG_PVQ
2252 od_rollback_buffer pre_buf, post_buf;
2253
2254 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2255 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002256#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002257
2258 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002259 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002260 if (is_inter) {
2261 if (x->use_default_inter_tx_type &&
2262 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2263 continue;
2264 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
2265 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
2266 if (!do_tx_type_search(tx_type, prune)) continue;
2267 }
2268 } else {
2269 if (x->use_default_intra_tx_type &&
2270 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2271 continue;
2272 if (!ALLOW_INTRA_EXT_TX && bs >= BLOCK_8X8) {
2273 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
2274 }
2275 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
2276 }
2277
2278 mbmi->tx_type = tx_type;
2279
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002280 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002281 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002282#if CONFIG_PVQ
2283 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002284#endif // CONFIG_PVQ
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002285 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002286 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002287
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002288 if (this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002289 this_rd = RDCOST(x->rdmult, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002290 else
Urvang Joshi70006e42017-06-14 16:08:55 -07002291 this_rd =
2292 RDCOST(x->rdmult, this_rd_stats.rate + s0, this_rd_stats.dist);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002293 if (is_inter_block(mbmi) && !xd->lossless[mbmi->segment_id] &&
2294 !this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002295 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002296
2297 if (this_rd < best_rd) {
2298 best_rd = this_rd;
2299 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002300 *rd_stats = this_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002301#if CONFIG_PVQ
2302 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002303#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304 }
2305 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07002306#if CONFIG_PVQ
2307 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002308#endif // CONFIG_PVQ
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002309 } else {
2310 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002311 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2312 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002313 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002314#else // CONFIG_EXT_TX
2315 if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id]) {
2316 for (tx_type = 0; tx_type < TX_TYPES; ++tx_type) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002317 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002318 if (!is_inter && x->use_default_intra_tx_type &&
2319 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2320 continue;
2321 if (is_inter && x->use_default_inter_tx_type &&
2322 tx_type != get_default_tx_type(0, xd, 0, mbmi->tx_size))
2323 continue;
2324 mbmi->tx_type = tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002325 txfm_rd_in_plane(x, cpi, &this_rd_stats, ref_best_rd, 0, bs,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002326 mbmi->tx_size, cpi->sf.use_fast_coef_costing);
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002327 if (this_rd_stats.rate == INT_MAX) continue;
Angie Chiangaa0c34b2017-04-25 12:25:38 -07002328
2329 av1_tx_type_cost(cpi, xd, bs, plane, mbmi->tx_size, tx_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002330 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
2332 !do_tx_type_search(tx_type, prune))
2333 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002334 }
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002335 if (this_rd_stats.skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07002336 this_rd = RDCOST(x->rdmult, s1, this_rd_stats.sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002337 else
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002338 this_rd =
Urvang Joshi70006e42017-06-14 16:08:55 -07002339 RDCOST(x->rdmult, this_rd_stats.rate + s0, this_rd_stats.dist);
2340 if (is_inter && !xd->lossless[mbmi->segment_id] && !this_rd_stats.skip)
2341 this_rd = AOMMIN(this_rd, RDCOST(x->rdmult, s1, this_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002342
2343 if (this_rd < best_rd) {
2344 best_rd = this_rd;
2345 best_tx_type = mbmi->tx_type;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002346 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002347 }
2348 }
Guillaume Martres4e4d3a02016-08-21 19:02:33 -07002349 } else {
2350 mbmi->tx_type = DCT_DCT;
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002351 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2352 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002353 }
2354#endif // CONFIG_EXT_TX
2355 mbmi->tx_type = best_tx_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002356}
2357
Urvang Joshi52648442016-10-13 17:27:51 -07002358static void choose_smallest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002359 RD_STATS *rd_stats, int64_t ref_best_rd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002360 BLOCK_SIZE bs) {
2361 MACROBLOCKD *const xd = &x->e_mbd;
2362 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2363
2364 mbmi->tx_size = TX_4X4;
2365 mbmi->tx_type = DCT_DCT;
Jingning Hane67b38a2016-11-04 10:30:00 -07002366#if CONFIG_VAR_TX
2367 mbmi->min_tx_size = get_min_tx_size(TX_4X4);
Fergus Simpson4063a682017-02-28 16:52:22 -08002368#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002369
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002370 txfm_rd_in_plane(x, cpi, rd_stats, ref_best_rd, 0, bs, mbmi->tx_size,
2371 cpi->sf.use_fast_coef_costing);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002372}
2373
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002374#if CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002375static INLINE int bsize_to_num_blk(BLOCK_SIZE bsize) {
2376 int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * tx_size_wide_log2[0]);
2377 return num_blk;
2378}
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002379#endif // CONFIG_TXK_SEL || CONFIG_VAR_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002380
Urvang Joshi52648442016-10-13 17:27:51 -07002381static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
Angie Chiang7c2b7f22016-11-07 16:00:00 -08002382 MACROBLOCK *x, RD_STATS *rd_stats,
2383 int64_t ref_best_rd, BLOCK_SIZE bs) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002384 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002385 MACROBLOCKD *const xd = &x->e_mbd;
2386 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002387 int64_t rd = INT64_MAX;
Angie Chianga4fa1902017-04-05 15:26:09 -07002388 int n;
2389 int start_tx, end_tx;
2390 int64_t best_rd = INT64_MAX, last_rd = INT64_MAX;
2391 const TX_SIZE max_tx_size = max_txsize_lookup[bs];
2392 TX_SIZE best_tx_size = max_tx_size;
2393 TX_TYPE best_tx_type = DCT_DCT;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002394#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002395 TX_TYPE best_txk_type[MAX_SB_SQUARE / (TX_SIZE_W_MIN * TX_SIZE_H_MIN)];
2396 const int num_blk = bsize_to_num_blk(bs);
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002397#endif // CONFIG_TXK_SEL
Angie Chianga4fa1902017-04-05 15:26:09 -07002398 const int tx_select = cm->tx_mode == TX_MODE_SELECT;
2399 const int is_inter = is_inter_block(mbmi);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002400#if CONFIG_PVQ
2401 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07002402 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002403#endif // CONFIG_PVQ
Angie Chianga4fa1902017-04-05 15:26:09 -07002404
2405 av1_invalid_rd_stats(rd_stats);
2406
2407#if CONFIG_EXT_TX && CONFIG_RECT_TX
2408 int evaluate_rect_tx = 0;
2409 if (tx_select) {
2410 evaluate_rect_tx = is_rect_tx_allowed(xd, mbmi);
2411 } else {
2412 const TX_SIZE chosen_tx_size =
2413 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2414 evaluate_rect_tx = is_rect_tx(chosen_tx_size);
2415 assert(IMPLIES(evaluate_rect_tx, is_rect_tx_allowed(xd, mbmi)));
2416 }
2417 if (evaluate_rect_tx) {
Angie Chiangf1cb0752017-04-10 16:01:20 -07002418 TX_TYPE tx_start = DCT_DCT;
2419 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002420#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002421 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2422 // performed in av1_search_txk_type()
2423 tx_end = DCT_DCT + 1;
2424#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002425 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002426 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002427 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
Angie Chianga4fa1902017-04-05 15:26:09 -07002428 const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
2429 RD_STATS this_rd_stats;
2430 int ext_tx_set =
2431 get_ext_tx_set(rect_tx_size, bs, is_inter, cm->reduced_tx_set_used);
2432 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2433 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2434 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type,
2435 rect_tx_size);
2436 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002437#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002438 memcpy(best_txk_type, mbmi->txk_type,
2439 sizeof(best_txk_type[0]) * num_blk);
2440#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002441 best_tx_type = tx_type;
2442 best_tx_size = rect_tx_size;
2443 best_rd = rd;
2444 *rd_stats = this_rd_stats;
2445 }
2446 }
Debargha Mukherjee094c9432017-02-22 10:31:25 -08002447#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002448 const int is_inter = is_inter_block(mbmi);
2449 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
Fergus Simpson4063a682017-02-28 16:52:22 -08002450#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
Angie Chianga4fa1902017-04-05 15:26:09 -07002451 }
2452 }
Yue Chen56e226e2017-05-02 16:21:40 -07002453
2454#if CONFIG_RECT_TX_EXT
2455 // test 1:4/4:1 tx
2456 int evaluate_quarter_tx = 0;
2457 if (is_quarter_tx_allowed(xd, mbmi, is_inter)) {
2458 if (tx_select) {
2459 evaluate_quarter_tx = 1;
2460 } else {
2461 const TX_SIZE chosen_tx_size =
2462 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2463 evaluate_quarter_tx = chosen_tx_size == quarter_txsize_lookup[bs];
2464 }
2465 }
2466 if (evaluate_quarter_tx) {
2467 TX_TYPE tx_start = DCT_DCT;
2468 TX_TYPE tx_end = TX_TYPES;
2469#if CONFIG_TXK_SEL
2470 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2471 // performed in av1_search_txk_type()
2472 tx_end = DCT_DCT + 1;
2473#endif
2474 TX_TYPE tx_type;
2475 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
2476 if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
2477 const TX_SIZE tx_size = quarter_txsize_lookup[bs];
2478 RD_STATS this_rd_stats;
2479 int ext_tx_set =
2480 get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
2481 if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
2482 (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
2483 rd =
2484 txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, tx_size);
2485 if (rd < best_rd) {
2486#if CONFIG_TXK_SEL
2487 memcpy(best_txk_type, mbmi->txk_type,
2488 sizeof(best_txk_type[0]) * num_blk);
2489#endif
2490 best_tx_type = tx_type;
2491 best_tx_size = tx_size;
2492 best_rd = rd;
2493 *rd_stats = this_rd_stats;
2494 }
2495 }
2496#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2497 const int is_inter = is_inter_block(mbmi);
2498 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2499#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2500 }
2501 }
2502#endif // CONFIG_RECT_TX_EXT
Angie Chianga4fa1902017-04-05 15:26:09 -07002503#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2504
2505 if (tx_select) {
2506 start_tx = max_tx_size;
2507 end_tx = (max_tx_size >= TX_32X32) ? TX_8X8 : TX_4X4;
2508 } else {
2509 const TX_SIZE chosen_tx_size =
2510 tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
2511 start_tx = chosen_tx_size;
2512 end_tx = chosen_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002513 }
2514
Angie Chianga4fa1902017-04-05 15:26:09 -07002515 last_rd = INT64_MAX;
2516 for (n = start_tx; n >= end_tx; --n) {
Sarah Parker36661922017-04-13 14:26:49 -07002517#if CONFIG_EXT_TX && CONFIG_RECT_TX
2518 if (is_rect_tx(n)) break;
2519#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Angie Chiangf1cb0752017-04-10 16:01:20 -07002520 TX_TYPE tx_start = DCT_DCT;
2521 TX_TYPE tx_end = TX_TYPES;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002522#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002523 // The tx_type becomes dummy when lv_map is on. The tx_type search will be
2524 // performed in av1_search_txk_type()
2525 tx_end = DCT_DCT + 1;
2526#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002527 TX_TYPE tx_type;
Angie Chiangf1cb0752017-04-10 16:01:20 -07002528 for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002529 RD_STATS this_rd_stats;
2530 if (skip_txfm_search(cpi, x, bs, tx_type, n)) continue;
2531 rd = txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, n);
2532#if CONFIG_PVQ
2533 od_encode_rollback(&x->daala_enc, &buf);
2534#endif // CONFIG_PVQ
2535 // Early termination in transform size search.
2536 if (cpi->sf.tx_size_search_breakout &&
2537 (rd == INT64_MAX ||
2538 (this_rd_stats.skip == 1 && tx_type != DCT_DCT && n < start_tx) ||
2539 (n < (int)max_tx_size && rd > last_rd)))
2540 break;
2541
2542 last_rd = rd;
2543 if (rd < best_rd) {
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002544#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002545 memcpy(best_txk_type, mbmi->txk_type,
2546 sizeof(best_txk_type[0]) * num_blk);
2547#endif
Angie Chianga4fa1902017-04-05 15:26:09 -07002548 best_tx_type = tx_type;
2549 best_tx_size = n;
2550 best_rd = rd;
2551 *rd_stats = this_rd_stats;
2552 }
2553#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2554 const int is_inter = is_inter_block(mbmi);
2555 if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
2556#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
2557 }
2558 }
2559 mbmi->tx_size = best_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002560 mbmi->tx_type = best_tx_type;
Angie Chiangcd9b03f2017-04-16 13:37:13 -07002561#if CONFIG_TXK_SEL
Angie Chiangf1cb0752017-04-10 16:01:20 -07002562 memcpy(mbmi->txk_type, best_txk_type, sizeof(best_txk_type[0]) * num_blk);
2563#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002564
Jingning Hane67b38a2016-11-04 10:30:00 -07002565#if CONFIG_VAR_TX
2566 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08002567#endif // CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07002568
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569#if !CONFIG_EXT_TX
2570 if (mbmi->tx_size >= TX_32X32) assert(mbmi->tx_type == DCT_DCT);
Fergus Simpson4063a682017-02-28 16:52:22 -08002571#endif // !CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07002572#if CONFIG_PVQ
Yushin Cho403618e2016-11-09 10:45:32 -08002573 if (best_rd != INT64_MAX) {
Angie Chianga4fa1902017-04-05 15:26:09 -07002574 txfm_yrd(cpi, x, rd_stats, ref_best_rd, bs, best_tx_type, best_tx_size);
Yushin Cho05f540a2016-11-08 22:12:51 -08002575 }
Fergus Simpson4063a682017-02-28 16:52:22 -08002576#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002577}
2578
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002579static void super_block_yrd(const AV1_COMP *const cpi, MACROBLOCK *x,
2580 RD_STATS *rd_stats, BLOCK_SIZE bs,
2581 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002582 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002583 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002584
2585 assert(bs == xd->mi[0]->mbmi.sb_type);
2586
Yaowu Xu1e2aae12017-02-27 16:33:14 -08002587 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002588 choose_smallest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002589 } else if (cpi->sf.tx_size_search_method == USE_LARGESTALL) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002590 choose_largest_tx_size(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002591 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002592 choose_tx_size_type_from_rd(cpi, x, rd_stats, ref_best_rd, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002593 }
2594}
2595
2596static int conditional_skipintra(PREDICTION_MODE mode,
2597 PREDICTION_MODE best_intra_mode) {
2598 if (mode == D117_PRED && best_intra_mode != V_PRED &&
2599 best_intra_mode != D135_PRED)
2600 return 1;
2601 if (mode == D63_PRED && best_intra_mode != V_PRED &&
2602 best_intra_mode != D45_PRED)
2603 return 1;
2604 if (mode == D207_PRED && best_intra_mode != H_PRED &&
2605 best_intra_mode != D45_PRED)
2606 return 1;
2607 if (mode == D153_PRED && best_intra_mode != H_PRED &&
2608 best_intra_mode != D135_PRED)
2609 return 1;
2610 return 0;
2611}
2612
hui su308a6392017-01-12 14:49:57 -08002613// Model based RD estimation for luma intra blocks.
2614static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
hui su9a416f52017-01-13 11:37:53 -08002615 BLOCK_SIZE bsize, int mode_cost) {
hui su308a6392017-01-12 14:49:57 -08002616 MACROBLOCKD *const xd = &x->e_mbd;
2617 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002618 assert(!is_inter_block(mbmi));
hui su308a6392017-01-12 14:49:57 -08002619 RD_STATS this_rd_stats;
2620 int row, col;
2621 int64_t temp_sse, this_rd;
2622 const TX_SIZE tx_size = tx_size_from_tx_mode(bsize, cpi->common.tx_mode, 0);
2623 const int stepr = tx_size_high_unit[tx_size];
2624 const int stepc = tx_size_wide_unit[tx_size];
2625 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
2626 const int max_blocks_high = max_block_high(xd, bsize, 0);
2627 mbmi->tx_size = tx_size;
2628 // Prediction.
Angie Chiang3d005e42017-04-02 16:31:35 -07002629 const int step = stepr * stepc;
2630 int block = 0;
hui su308a6392017-01-12 14:49:57 -08002631 for (row = 0; row < max_blocks_high; row += stepr) {
2632 for (col = 0; col < max_blocks_wide; col += stepc) {
Luc Trudeauf5334002017-04-25 12:21:26 -04002633#if CONFIG_CFL
David Michael Barrd3b01b82017-04-27 19:58:52 +09002634 const struct macroblockd_plane *const pd = &xd->plane[0];
2635 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002636
2637#if CONFIG_EC_ADAPT
2638 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
2639#else
Luc Trudeau64ed2ce2017-05-12 12:01:24 -04002640 FRAME_CONTEXT *const ec_ctx = cpi->common.fc;
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04002641#endif // CONFIG_EC_ADAPT
2642
2643 av1_predict_intra_block_encoder_facade(x, ec_ctx, 0, block, col, row,
2644 tx_size, plane_bsize);
Luc Trudeauf5334002017-04-25 12:21:26 -04002645#else
Angie Chiang752ccce2017-04-09 13:41:13 -07002646 av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04002647#endif
Angie Chiang3d005e42017-04-02 16:31:35 -07002648 block += step;
hui su308a6392017-01-12 14:49:57 -08002649 }
2650 }
2651 // RD estimation.
2652 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
2653 &this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
hui su9a416f52017-01-13 11:37:53 -08002654#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07002655 if (av1_is_directional_mode(mbmi->mode, bsize) &&
2656 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07002657 mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
2658 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
hui su9a416f52017-01-13 11:37:53 -08002659 }
2660#endif // CONFIG_EXT_INTRA
hui su8f4cc0a2017-01-13 15:14:49 -08002661#if CONFIG_FILTER_INTRA
2662 if (mbmi->mode == DC_PRED) {
2663 const aom_prob prob = cpi->common.fc->filter_intra_probs[0];
2664 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
2665 const int mode = mbmi->filter_intra_mode_info.filter_intra_mode[0];
2666 mode_cost += (av1_cost_bit(prob, 1) +
2667 write_uniform_cost(FILTER_INTRA_MODES, mode));
2668 } else {
2669 mode_cost += av1_cost_bit(prob, 0);
2670 }
2671 }
2672#endif // CONFIG_FILTER_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07002673 this_rd =
2674 RDCOST(x->rdmult, this_rd_stats.rate + mode_cost, this_rd_stats.dist);
hui su308a6392017-01-12 14:49:57 -08002675 return this_rd;
2676}
2677
Urvang Joshib100db72016-10-12 16:28:56 -07002678#if CONFIG_PALETTE
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002679// Extends 'color_map' array from 'orig_width x orig_height' to 'new_width x
2680// new_height'. Extra rows and columns are filled in by copying last valid
2681// row/column.
2682static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
2683 int orig_height, int new_width,
2684 int new_height) {
2685 int j;
2686 assert(new_width >= orig_width);
2687 assert(new_height >= orig_height);
2688 if (new_width == orig_width && new_height == orig_height) return;
2689
2690 for (j = orig_height - 1; j >= 0; --j) {
2691 memmove(color_map + j * new_width, color_map + j * orig_width, orig_width);
2692 // Copy last column to extra columns.
2693 memset(color_map + j * new_width + orig_width,
2694 color_map[j * new_width + orig_width - 1], new_width - orig_width);
2695 }
2696 // Copy last row to extra rows.
2697 for (j = orig_height; j < new_height; ++j) {
2698 memcpy(color_map + j * new_width, color_map + (orig_height - 1) * new_width,
2699 new_width);
2700 }
2701}
2702
hui su33567b22017-04-30 16:40:19 -07002703#if CONFIG_PALETTE_DELTA_ENCODING
2704// Bias toward using colors in the cache.
2705// TODO(huisu): Try other schemes to improve compression.
2706static void optimize_palette_colors(uint16_t *color_cache, int n_cache,
2707 int n_colors, int stride,
2708 float *centroids) {
2709 if (n_cache <= 0) return;
2710 for (int i = 0; i < n_colors * stride; i += stride) {
2711 float min_diff = fabsf(centroids[i] - color_cache[0]);
2712 int idx = 0;
2713 for (int j = 1; j < n_cache; ++j) {
2714 float this_diff = fabsf(centroids[i] - color_cache[j]);
2715 if (this_diff < min_diff) {
2716 min_diff = this_diff;
2717 idx = j;
2718 }
2719 }
2720 if (min_diff < 1.5) centroids[i] = color_cache[idx];
2721 }
2722}
2723#endif // CONFIG_PALETTE_DELTA_ENCODING
2724
hui sude0c70a2017-01-09 17:12:17 -08002725static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
2726 BLOCK_SIZE bsize, int palette_ctx,
2727 int dc_mode_cost, MB_MODE_INFO *best_mbmi,
2728 uint8_t *best_palette_color_map,
hui su78c611a2017-01-13 17:06:04 -08002729 int64_t *best_rd, int64_t *best_model_rd,
2730 int *rate, int *rate_tokenonly,
2731 int64_t *distortion, int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002732 int rate_overhead = 0;
2733 MACROBLOCKD *const xd = &x->e_mbd;
2734 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08002735 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07002736 assert(!is_inter_block(mbmi));
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002737 int this_rate, colors, n;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002738 const int src_stride = x->plane[0].src.stride;
2739 const uint8_t *const src = x->plane[0].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08002740 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002741 int block_width, block_height, rows, cols;
2742 av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
2743 &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002744
2745 assert(cpi->common.allow_screen_content_tools);
2746
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002747#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002748 if (cpi->common.use_highbitdepth)
Yaowu Xuf883b422016-08-30 14:01:10 -07002749 colors = av1_count_colors_highbd(src, src_stride, rows, cols,
2750 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002751 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002752#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07002753 colors = av1_count_colors(src, src_stride, rows, cols);
hui su5db97432016-10-14 16:10:14 -07002754#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08002755 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07002756#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757
2758 if (colors > 1 && colors <= 64) {
hui su78c611a2017-01-13 17:06:04 -08002759 int r, c, i, j, k, palette_mode_cost;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07002761 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 float *const data = x->palette_buffer->kmeans_data_buf;
2763 float centroids[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002764 float lb, ub, val;
hui su78c611a2017-01-13 17:06:04 -08002765 RD_STATS tokenonly_rd_stats;
2766 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002767 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002768#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002769 uint16_t *src16 = CONVERT_TO_SHORTPTR(src);
2770 if (cpi->common.use_highbitdepth)
2771 lb = ub = src16[0];
2772 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002773#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002774 lb = ub = src[0];
2775
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002776#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002777 if (cpi->common.use_highbitdepth) {
2778 for (r = 0; r < rows; ++r) {
2779 for (c = 0; c < cols; ++c) {
2780 val = src16[r * src_stride + c];
2781 data[r * cols + c] = val;
2782 if (val < lb)
2783 lb = val;
2784 else if (val > ub)
2785 ub = val;
2786 }
2787 }
2788 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002789#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 for (r = 0; r < rows; ++r) {
2791 for (c = 0; c < cols; ++c) {
2792 val = src[r * src_stride + c];
2793 data[r * cols + c] = val;
2794 if (val < lb)
2795 lb = val;
2796 else if (val > ub)
2797 ub = val;
2798 }
2799 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002800#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002801 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002802#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002803
2804 mbmi->mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07002805#if CONFIG_FILTER_INTRA
2806 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
2807#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002808
2809 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
2810
hui su33567b22017-04-30 16:40:19 -07002811#if CONFIG_PALETTE_DELTA_ENCODING
2812 const MODE_INFO *above_mi = xd->above_mi;
2813 const MODE_INFO *left_mi = xd->left_mi;
2814 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
2815 const int n_cache =
2816 av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
2817#endif // CONFIG_PALETTE_DELTA_ENCODING
2818
Yaowu Xuc27fc142016-08-22 16:08:15 -07002819 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
2820 --n) {
Urvang Joshi773e3542017-05-05 18:09:42 -07002821 if (colors == PALETTE_MIN_SIZE) {
2822 // Special case: These colors automatically become the centroids.
2823 assert(colors == n);
2824 assert(colors == 2);
2825 centroids[0] = lb;
2826 centroids[1] = ub;
2827 k = 2;
2828 } else {
2829 for (i = 0; i < n; ++i) {
2830 centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
2831 }
2832 av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
hui su33567b22017-04-30 16:40:19 -07002833#if CONFIG_PALETTE_DELTA_ENCODING
2834 optimize_palette_colors(color_cache, n_cache, n, 1, centroids);
2835#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi773e3542017-05-05 18:09:42 -07002836 k = av1_remove_duplicates(centroids, n);
2837 if (k < PALETTE_MIN_SIZE) {
2838 // Too few unique colors to create a palette. And DC_PRED will work
2839 // well for that case anyway. So skip.
2840 continue;
2841 }
Urvang Joshi5fb95f72017-05-05 17:36:16 -07002842 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002843
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002844#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845 if (cpi->common.use_highbitdepth)
2846 for (i = 0; i < k; ++i)
2847 pmi->palette_colors[i] =
2848 clip_pixel_highbd((int)centroids[i], cpi->common.bit_depth);
2849 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002850#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002851 for (i = 0; i < k; ++i)
2852 pmi->palette_colors[i] = clip_pixel((int)centroids[i]);
2853 pmi->palette_size[0] = k;
2854
Yaowu Xuf883b422016-08-30 14:01:10 -07002855 av1_calc_indices(data, centroids, color_map, rows * cols, k, 1);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002856 extend_palette_color_map(color_map, cols, rows, block_width,
2857 block_height);
hui su78c611a2017-01-13 17:06:04 -08002858 palette_mode_cost =
hui sud13c24a2017-04-07 16:13:07 -07002859 dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08002860 cpi->palette_y_size_cost[bsize - BLOCK_8X8][k - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861 write_uniform_cost(k, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07002862 av1_cost_bit(
2863 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002864 1);
hui su33567b22017-04-30 16:40:19 -07002865 palette_mode_cost += av1_palette_color_cost_y(pmi,
2866#if CONFIG_PALETTE_DELTA_ENCODING
2867 color_cache, n_cache,
2868#endif // CONFIG_PALETTE_DELTA_ENCODING
2869 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002870 for (i = 0; i < rows; ++i) {
2871 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07002872 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08002873 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08002874 color_map, block_width, i, j, k, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002875 assert(color_idx >= 0 && color_idx < k);
Alex Converse92109812017-02-22 10:21:40 -08002876 palette_mode_cost += cpi->palette_y_color_cost[k - PALETTE_MIN_SIZE]
2877 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002878 }
2879 }
hui su78c611a2017-01-13 17:06:04 -08002880 this_model_rd = intra_model_yrd(cpi, x, bsize, palette_mode_cost);
2881 if (*best_model_rd != INT64_MAX &&
2882 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
2883 continue;
2884 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
2885 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
2886 if (tokenonly_rd_stats.rate == INT_MAX) continue;
2887 this_rate = tokenonly_rd_stats.rate + palette_mode_cost;
Urvang Joshi70006e42017-06-14 16:08:55 -07002888 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
hui su8a630492017-01-10 18:22:41 -08002889 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08002890 tokenonly_rd_stats.rate -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
hui su8a630492017-01-10 18:22:41 -08002891 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002892 if (this_rd < *best_rd) {
2893 *best_rd = this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002894 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08002895 block_width * block_height * sizeof(color_map[0]));
hui sude0c70a2017-01-09 17:12:17 -08002896 *best_mbmi = *mbmi;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08002897 rate_overhead = this_rate - tokenonly_rd_stats.rate;
hui su8a630492017-01-10 18:22:41 -08002898 if (rate) *rate = this_rate;
2899 if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
2900 if (distortion) *distortion = tokenonly_rd_stats.dist;
2901 if (skippable) *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002902 }
2903 }
2904 }
hui sude0c70a2017-01-09 17:12:17 -08002905
2906 if (best_mbmi->palette_mode_info.palette_size[0] > 0) {
2907 memcpy(color_map, best_palette_color_map,
2908 rows * cols * sizeof(best_palette_color_map[0]));
2909 }
2910 *mbmi = *best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002911 return rate_overhead;
2912}
Urvang Joshib100db72016-10-12 16:28:56 -07002913#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002914
Urvang Joshifeb925f2016-12-05 10:37:29 -08002915static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
Urvang Joshi52648442016-10-13 17:27:51 -07002916 const AV1_COMP *const cpi, MACROBLOCK *x, int row, int col,
2917 PREDICTION_MODE *best_mode, const int *bmode_costs, ENTROPY_CONTEXT *a,
2918 ENTROPY_CONTEXT *l, int *bestrate, int *bestratey, int64_t *bestdistortion,
Urvang Joshifeb925f2016-12-05 10:37:29 -08002919 BLOCK_SIZE bsize, TX_SIZE tx_size, int *y_skip, int64_t rd_thresh) {
Angie Chiang22ba7512016-10-20 17:10:33 -07002920 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002921 PREDICTION_MODE mode;
2922 MACROBLOCKD *const xd = &x->e_mbd;
Urvang Joshi330aec82017-05-08 15:37:42 -07002923 assert(!is_inter_block(&xd->mi[0]->mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002924 int64_t best_rd = rd_thresh;
2925 struct macroblock_plane *p = &x->plane[0];
2926 struct macroblockd_plane *pd = &xd->plane[0];
2927 const int src_stride = p->src.stride;
2928 const int dst_stride = pd->dst.stride;
2929 const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
Yushin Cho1a2df5e2017-01-09 13:36:13 -08002930 uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002931#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08002932 // TODO(jingning): This is a temporal change. The whole function should be
2933 // out when cb4x4 is enabled.
2934 ENTROPY_CONTEXT ta[4], tempa[4];
2935 ENTROPY_CONTEXT tl[4], templ[4];
2936#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002937 ENTROPY_CONTEXT ta[2], tempa[2];
2938 ENTROPY_CONTEXT tl[2], templ[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07002939#endif // CONFIG_CHROMA_2X2
Urvang Joshifeb925f2016-12-05 10:37:29 -08002940
2941 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
2942 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
2943 const int tx_width_unit = tx_size_wide_unit[tx_size];
2944 const int tx_height_unit = tx_size_high_unit[tx_size];
2945 const int pred_block_width = block_size_wide[bsize];
2946 const int pred_block_height = block_size_high[bsize];
2947 const int tx_width = tx_size_wide[tx_size];
2948 const int tx_height = tx_size_high[tx_size];
2949 const int pred_width_in_transform_blocks = pred_block_width / tx_width;
2950 const int pred_height_in_transform_blocks = pred_block_height / tx_height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002951 int idx, idy;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07002952 int best_can_skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953 uint8_t best_dst[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002954#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002955 uint16_t best_dst16[8 * 8];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002956#endif // CONFIG_HIGHBITDEPTH
Urvang Joshifeb925f2016-12-05 10:37:29 -08002957 const int is_lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
2958#if CONFIG_EXT_TX && CONFIG_RECT_TX
2959 const int sub_bsize = bsize;
2960#else
2961 const int sub_bsize = BLOCK_4X4;
2962#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07002963
Yushin Cho77bba8d2016-11-04 16:36:56 -07002964#if CONFIG_PVQ
2965 od_rollback_buffer pre_buf, post_buf;
2966 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2967 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08002968#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07002969
Urvang Joshifeb925f2016-12-05 10:37:29 -08002970 assert(bsize < BLOCK_8X8);
2971 assert(tx_width < 8 || tx_height < 8);
2972#if CONFIG_EXT_TX && CONFIG_RECT_TX
hui suff5e2092017-03-27 10:07:59 -07002973 if (is_lossless)
2974 assert(tx_width == 4 && tx_height == 4);
2975 else
2976 assert(tx_width == pred_block_width && tx_height == pred_block_height);
Urvang Joshifeb925f2016-12-05 10:37:29 -08002977#else
2978 assert(tx_width == 4 && tx_height == 4);
2979#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
2980
2981 memcpy(ta, a, pred_width_in_transform_blocks * sizeof(a[0]));
2982 memcpy(tl, l, pred_height_in_transform_blocks * sizeof(l[0]));
2983
2984 xd->mi[0]->mbmi.tx_size = tx_size;
2985
Urvang Joshib100db72016-10-12 16:28:56 -07002986#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987 xd->mi[0]->mbmi.palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07002988#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002989
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002990#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002991 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08002992#if CONFIG_PVQ
2993 od_encode_checkpoint(&x->daala_enc, &pre_buf);
2994#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002995 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
2996 int64_t this_rd;
2997 int ratey = 0;
2998 int64_t distortion = 0;
2999 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003000 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001
Urvang Joshifeb925f2016-12-05 10:37:29 -08003002 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
3003 (1 << mode)))
3004 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003005
3006 // Only do the oblique modes if the best so far is
3007 // one of the neighboring directional modes
3008 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3009 if (conditional_skipintra(mode, *best_mode)) continue;
3010 }
3011
Urvang Joshifeb925f2016-12-05 10:37:29 -08003012 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
3013 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003014
Urvang Joshifeb925f2016-12-05 10:37:29 -08003015 for (idy = 0; idy < pred_height_in_transform_blocks; ++idy) {
3016 for (idx = 0; idx < pred_width_in_transform_blocks; ++idx) {
3017 const int block_raster_idx = (row + idy) * 2 + (col + idx);
3018 const int block =
3019 av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003020 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
3021 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Thomas Daede6ff6af62017-02-03 16:29:24 -08003022#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003023 int16_t *const src_diff = av1_raster_block_offset_int16(
3024 BLOCK_8X8, block_raster_idx, p->src_diff);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003025#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003026 int skip;
3027 assert(block < 4);
3028 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3029 idx == 0 && idy == 0));
3030 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3031 block == 0 || block == 2));
3032 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00003033 av1_predict_intra_block(
3034 xd, pd->width, pd->height, txsize_to_bsize[tx_size], mode, dst,
3035 dst_stride, dst, dst_stride, col + idx, row + idy, 0);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003036#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003037 aom_highbd_subtract_block(tx_height, tx_width, src_diff, 8, src,
3038 src_stride, dst, dst_stride, xd->bd);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003039#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003040 if (is_lossless) {
Angie Chiang752ccce2017-04-09 13:41:13 -07003041 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003042 const SCAN_ORDER *scan_order =
3043 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003044 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003045 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003046#if !CONFIG_PVQ
Angie Chiangff6d8902016-10-21 11:02:09 -07003047 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003048 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang05917872017-04-15 12:28:56 -07003049 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07003050 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003051 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003052 skip = (p->eobs[block] == 0);
3053 can_skip &= skip;
3054 tempa[idx] = !skip;
3055 templ[idy] = !skip;
3056#if CONFIG_EXT_TX
3057 if (tx_size == TX_8X4) {
3058 tempa[idx + 1] = tempa[idx];
3059 } else if (tx_size == TX_4X8) {
3060 templ[idy + 1] = templ[idy];
3061 }
3062#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08003063#else
3064 (void)scan_order;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003065
Thomas Daede6ff6af62017-02-03 16:29:24 -08003066 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3067 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3068
3069 ratey += x->rate;
3070 skip = x->pvq_skip[0];
3071 tempa[idx] = !skip;
3072 templ[idy] = !skip;
3073 can_skip &= skip;
3074#endif
Urvang Joshi70006e42017-06-14 16:08:55 -07003075 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003076 goto next_highbd;
Thomas Daede6ff6af62017-02-03 16:29:24 -08003077#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003078 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08003079#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07003080 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3081 DCT_DCT, tx_size, dst, dst_stride,
3082 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003083 } else {
3084 int64_t dist;
3085 unsigned int tmp;
Angie Chiang752ccce2017-04-09 13:41:13 -07003086 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003087 const SCAN_ORDER *scan_order =
3088 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003089 const int coeff_ctx =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003090 combine_entropy_contexts(tempa[idx], templ[idy]);
Thomas Daede6ff6af62017-02-03 16:29:24 -08003091#if !CONFIG_PVQ
Sarah Parker345366a2017-06-15 12:13:01 -07003092#if DISABLE_TRELLISQ_SEARCH
3093 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3094 tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3095#else
Angie Chiangff6d8902016-10-21 11:02:09 -07003096 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003097 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07003098 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
3099 templ + idy);
Sarah Parker345366a2017-06-15 12:13:01 -07003100#endif // DISABLE_TRELLISQ_SEARCH
Angie Chiang05917872017-04-15 12:28:56 -07003101 ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
Angie Chiang77368af2017-03-23 16:22:07 -07003102 tempa + idx, templ + idy,
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07003103 cpi->sf.use_fast_coef_costing);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003104 skip = (p->eobs[block] == 0);
3105 can_skip &= skip;
3106 tempa[idx] = !skip;
3107 templ[idy] = !skip;
3108#if CONFIG_EXT_TX
3109 if (tx_size == TX_8X4) {
3110 tempa[idx + 1] = tempa[idx];
3111 } else if (tx_size == TX_4X8) {
3112 templ[idy + 1] = templ[idy];
3113 }
3114#endif // CONFIG_EXT_TX
Thomas Daede6ff6af62017-02-03 16:29:24 -08003115#else
3116 (void)scan_order;
3117
3118 av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
3119 tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
3120 ratey += x->rate;
3121 skip = x->pvq_skip[0];
3122 tempa[idx] = !skip;
3123 templ[idy] = !skip;
3124 can_skip &= skip;
3125#endif
3126#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003127 if (!skip)
Thomas Daede6ff6af62017-02-03 16:29:24 -08003128#endif
Yushin Cho08195cc2017-04-05 16:37:01 -07003129 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3130 tx_type, tx_size, dst, dst_stride,
3131 p->eobs[block]);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003132 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003133 dist = (int64_t)tmp << 4;
3134 distortion += dist;
Urvang Joshi70006e42017-06-14 16:08:55 -07003135 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003136 goto next_highbd;
3137 }
3138 }
3139 }
3140
3141 rate += ratey;
Urvang Joshi70006e42017-06-14 16:08:55 -07003142 this_rd = RDCOST(x->rdmult, rate, distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143
3144 if (this_rd < best_rd) {
3145 *bestrate = rate;
3146 *bestratey = ratey;
3147 *bestdistortion = distortion;
3148 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003149 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003150 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003151 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3152 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Thomas Daede6ff6af62017-02-03 16:29:24 -08003153#if CONFIG_PVQ
3154 od_encode_checkpoint(&x->daala_enc, &post_buf);
3155#endif
Urvang Joshifeb925f2016-12-05 10:37:29 -08003156 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 memcpy(best_dst16 + idy * 8,
3158 CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08003159 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003160 }
3161 }
3162 next_highbd : {}
Thomas Daede6ff6af62017-02-03 16:29:24 -08003163#if CONFIG_PVQ
3164 od_encode_rollback(&x->daala_enc, &pre_buf);
3165#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166 }
3167
3168 if (best_rd >= rd_thresh) return best_rd;
3169
Thomas Daede6ff6af62017-02-03 16:29:24 -08003170#if CONFIG_PVQ
3171 od_encode_rollback(&x->daala_enc, &post_buf);
3172#endif
3173
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003174 if (y_skip) *y_skip &= best_can_skip;
3175
Urvang Joshifeb925f2016-12-05 10:37:29 -08003176 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 memcpy(CONVERT_TO_SHORTPTR(dst_init + idy * dst_stride),
Urvang Joshifeb925f2016-12-05 10:37:29 -08003178 best_dst16 + idy * 8,
3179 pred_width_in_transform_blocks * 4 * sizeof(uint16_t));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 }
3181
3182 return best_rd;
3183 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003184#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003185
Yushin Cho77bba8d2016-11-04 16:36:56 -07003186#if CONFIG_PVQ
3187 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003188#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003189
Yaowu Xuc27fc142016-08-22 16:08:15 -07003190 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
3191 int64_t this_rd;
3192 int ratey = 0;
3193 int64_t distortion = 0;
3194 int rate = bmode_costs[mode];
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003195 int can_skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003196
Urvang Joshifeb925f2016-12-05 10:37:29 -08003197 if (!(cpi->sf.intra_y_mode_mask[txsize_sqr_up_map[tx_size]] &
3198 (1 << mode))) {
3199 continue;
3200 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003201
3202 // Only do the oblique modes if the best so far is
3203 // one of the neighboring directional modes
3204 if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
3205 if (conditional_skipintra(mode, *best_mode)) continue;
3206 }
3207
Urvang Joshifeb925f2016-12-05 10:37:29 -08003208 memcpy(tempa, ta, pred_width_in_transform_blocks * sizeof(ta[0]));
3209 memcpy(templ, tl, pred_height_in_transform_blocks * sizeof(tl[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003210
Urvang Joshifeb925f2016-12-05 10:37:29 -08003211 for (idy = 0; idy < pred_height_in_4x4_blocks; idy += tx_height_unit) {
3212 for (idx = 0; idx < pred_width_in_4x4_blocks; idx += tx_width_unit) {
3213 const int block_raster_idx = (row + idy) * 2 + (col + idx);
3214 int block = av1_raster_order_to_block_index(tx_size, block_raster_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003215 const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride];
3216 uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride];
Yushin Cho77bba8d2016-11-04 16:36:56 -07003217#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003218 int16_t *const src_diff = av1_raster_block_offset_int16(
3219 BLOCK_8X8, block_raster_idx, p->src_diff);
Fergus Simpson4063a682017-02-28 16:52:22 -08003220#endif // !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003221 int skip;
3222 assert(block < 4);
3223 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3224 idx == 0 && idy == 0));
3225 assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
3226 block == 0 || block == 2));
3227 xd->mi[0]->bmi[block_raster_idx].as_mode = mode;
David Barker839467f2017-01-19 11:06:15 +00003228 av1_predict_intra_block(xd, pd->width, pd->height,
3229 txsize_to_bsize[tx_size], mode, dst, dst_stride,
3230 dst, dst_stride,
Jingning Hand1097fc2016-12-06 10:55:34 -08003231#if CONFIG_CB4X4
3232 2 * (col + idx), 2 * (row + idy),
3233#else
3234 col + idx, row + idy,
Fergus Simpson4063a682017-02-28 16:52:22 -08003235#endif // CONFIG_CB4X4
Jingning Hand1097fc2016-12-06 10:55:34 -08003236 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003237#if !CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003238 aom_subtract_block(tx_height, tx_width, src_diff, 8, src, src_stride,
3239 dst, dst_stride);
Fergus Simpson4063a682017-02-28 16:52:22 -08003240#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003241
Urvang Joshi14731732017-04-27 18:40:49 -07003242 TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -07003243 const SCAN_ORDER *scan_order =
3244 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Urvang Joshi14731732017-04-27 18:40:49 -07003245 const int coeff_ctx = combine_entropy_contexts(tempa[idx], templ[idy]);
Jingning Hand1097fc2016-12-06 10:55:34 -08003246#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003247 block = 4 * block;
Fergus Simpson4063a682017-02-28 16:52:22 -08003248#endif // CONFIG_CB4X4
Yushin Cho900243b2017-01-03 11:02:38 -08003249#if !CONFIG_PVQ
Sarah Parker345366a2017-06-15 12:13:01 -07003250#if DISABLE_TRELLISQ_SEARCH
3251 av1_xform_quant(cm, x, 0, block,
3252#if CONFIG_CB4X4
3253 2 * (row + idy), 2 * (col + idx),
3254#else
3255 row + idy, col + idx,
3256#endif // CONFIG_CB4X4
3257 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_B);
3258#else
Urvang Joshi14731732017-04-27 18:40:49 -07003259 const AV1_XFORM_QUANT xform_quant =
3260 is_lossless ? AV1_XFORM_QUANT_B : AV1_XFORM_QUANT_FP;
3261 av1_xform_quant(cm, x, 0, block,
Jingning Hand1097fc2016-12-06 10:55:34 -08003262#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003263 2 * (row + idy), 2 * (col + idx),
Jingning Hand1097fc2016-12-06 10:55:34 -08003264#else
Urvang Joshi14731732017-04-27 18:40:49 -07003265 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003266#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003267 BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
Yushin Cho900243b2017-01-03 11:02:38 -08003268
Angie Chiang3511c372017-05-31 12:47:07 -07003269 av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
3270 templ + idy);
Sarah Parker345366a2017-06-15 12:13:01 -07003271#endif // DISABLE_TRELLISQ_SEARCH
Urvang Joshi14731732017-04-27 18:40:49 -07003272 ratey +=
3273 av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
3274 templ + idy, cpi->sf.use_fast_coef_costing);
3275 skip = (p->eobs[block] == 0);
3276 can_skip &= skip;
3277 tempa[idx] = !skip;
3278 templ[idy] = !skip;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003279#if CONFIG_EXT_TX
Urvang Joshi14731732017-04-27 18:40:49 -07003280 if (tx_size == TX_8X4) {
3281 tempa[idx + 1] = tempa[idx];
3282 } else if (tx_size == TX_4X8) {
3283 templ[idy + 1] = templ[idy];
3284 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003285#endif // CONFIG_EXT_TX
Yushin Cho77bba8d2016-11-04 16:36:56 -07003286#else
Urvang Joshi14731732017-04-27 18:40:49 -07003287 (void)scan_order;
Yushin Cho900243b2017-01-03 11:02:38 -08003288
Urvang Joshi14731732017-04-27 18:40:49 -07003289 av1_xform_quant(cm, x, 0, block,
Yushin Cho900243b2017-01-03 11:02:38 -08003290#if CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003291 2 * (row + idy), 2 * (col + idx),
Yushin Cho900243b2017-01-03 11:02:38 -08003292#else
Urvang Joshi14731732017-04-27 18:40:49 -07003293 row + idy, col + idx,
Fergus Simpson4063a682017-02-28 16:52:22 -08003294#endif // CONFIG_CB4X4
Urvang Joshi14731732017-04-27 18:40:49 -07003295 BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
3296
3297 ratey += x->rate;
3298 skip = x->pvq_skip[0];
3299 tempa[idx] = !skip;
3300 templ[idy] = !skip;
3301 can_skip &= skip;
Fergus Simpson4063a682017-02-28 16:52:22 -08003302#endif // !CONFIG_PVQ
Urvang Joshi14731732017-04-27 18:40:49 -07003303
3304 if (!is_lossless) { // To use the pixel domain distortion, we need to
3305 // calculate inverse txfm *before* calculating RD
3306 // cost. Compared to calculating the distortion in
3307 // the frequency domain, the overhead of encoding
3308 // effort is low.
Yushin Chob27a17f2016-12-23 14:33:02 -08003309#if CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003310 if (!skip)
Fergus Simpson4063a682017-02-28 16:52:22 -08003311#endif // CONFIG_PVQ
Yushin Cho08195cc2017-04-05 16:37:01 -07003312 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3313 tx_type, tx_size, dst, dst_stride,
3314 p->eobs[block]);
Urvang Joshi14731732017-04-27 18:40:49 -07003315 unsigned int tmp;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003316 cpi->fn_ptr[sub_bsize].vf(src, src_stride, dst, dst_stride, &tmp);
Urvang Joshi14731732017-04-27 18:40:49 -07003317 const int64_t dist = (int64_t)tmp << 4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318 distortion += dist;
Urvang Joshi14731732017-04-27 18:40:49 -07003319 }
3320
Urvang Joshi70006e42017-06-14 16:08:55 -07003321 if (RDCOST(x->rdmult, ratey, distortion) >= best_rd) goto next;
Urvang Joshi14731732017-04-27 18:40:49 -07003322
3323 if (is_lossless) { // Calculate inverse txfm *after* RD cost.
3324#if CONFIG_PVQ
3325 if (!skip)
3326#endif // CONFIG_PVQ
3327 av1_inverse_transform_block(xd, BLOCK_OFFSET(pd->dqcoeff, block),
3328 DCT_DCT, tx_size, dst, dst_stride,
3329 p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003330 }
3331 }
3332 }
3333
3334 rate += ratey;
Urvang Joshi70006e42017-06-14 16:08:55 -07003335 this_rd = RDCOST(x->rdmult, rate, distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003336
3337 if (this_rd < best_rd) {
3338 *bestrate = rate;
3339 *bestratey = ratey;
3340 *bestdistortion = distortion;
3341 best_rd = this_rd;
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003342 best_can_skip = can_skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003343 *best_mode = mode;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003344 memcpy(a, tempa, pred_width_in_transform_blocks * sizeof(tempa[0]));
3345 memcpy(l, templ, pred_height_in_transform_blocks * sizeof(templ[0]));
Yushin Cho77bba8d2016-11-04 16:36:56 -07003346#if CONFIG_PVQ
3347 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003348#endif // CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -08003349 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003350 memcpy(best_dst + idy * 8, dst_init + idy * dst_stride,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003351 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003352 }
3353 next : {}
Yushin Cho77bba8d2016-11-04 16:36:56 -07003354#if CONFIG_PVQ
3355 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003356#endif // CONFIG_PVQ
3357 } // mode decision loop
Yaowu Xuc27fc142016-08-22 16:08:15 -07003358
3359 if (best_rd >= rd_thresh) return best_rd;
3360
Yushin Cho77bba8d2016-11-04 16:36:56 -07003361#if CONFIG_PVQ
3362 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003363#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07003364
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003365 if (y_skip) *y_skip &= best_can_skip;
3366
Urvang Joshifeb925f2016-12-05 10:37:29 -08003367 for (idy = 0; idy < pred_height_in_transform_blocks * 4; ++idy)
Yaowu Xuc27fc142016-08-22 16:08:15 -07003368 memcpy(dst_init + idy * dst_stride, best_dst + idy * 8,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003369 pred_width_in_transform_blocks * 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003370
3371 return best_rd;
3372}
3373
Urvang Joshi52648442016-10-13 17:27:51 -07003374static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
3375 MACROBLOCK *mb, int *rate,
3376 int *rate_y, int64_t *distortion,
3377 int *y_skip, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003378 const MACROBLOCKD *const xd = &mb->e_mbd;
3379 MODE_INFO *const mic = xd->mi[0];
3380 const MODE_INFO *above_mi = xd->above_mi;
3381 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003382 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003383 assert(!is_inter_block(mbmi));
Urvang Joshifeb925f2016-12-05 10:37:29 -08003384 const BLOCK_SIZE bsize = mbmi->sb_type;
3385 const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
3386 const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003387 int idx, idy;
3388 int cost = 0;
3389 int64_t total_distortion = 0;
3390 int tot_rate_y = 0;
3391 int64_t total_rd = 0;
3392 const int *bmode_costs = cpi->mbmode_cost[0];
Urvang Joshifeb925f2016-12-05 10:37:29 -08003393 const int is_lossless = xd->lossless[mbmi->segment_id];
3394#if CONFIG_EXT_TX && CONFIG_RECT_TX
3395 const TX_SIZE tx_size = is_lossless ? TX_4X4 : max_txsize_rect_lookup[bsize];
3396#else
3397 const TX_SIZE tx_size = TX_4X4;
3398#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399
3400#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08003401#if CONFIG_INTRA_INTERP
Urvang Joshifeb925f2016-12-05 10:37:29 -08003402 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003403#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003404#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003405#if CONFIG_FILTER_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08003406 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003407#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003408
3409 // TODO(any): Add search of the tx_type to improve rd performance at the
3410 // expense of speed.
Urvang Joshifeb925f2016-12-05 10:37:29 -08003411 mbmi->tx_type = DCT_DCT;
3412 mbmi->tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003413
Debargha Mukherjee096ae4c2016-09-07 10:08:13 -07003414 if (y_skip) *y_skip = 1;
3415
Urvang Joshifeb925f2016-12-05 10:37:29 -08003416 // Pick modes for each prediction sub-block (of size 4x4, 4x8, or 8x4) in this
3417 // 8x8 coding block.
3418 for (idy = 0; idy < 2; idy += pred_height_in_4x4_blocks) {
3419 for (idx = 0; idx < 2; idx += pred_width_in_4x4_blocks) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003420 PREDICTION_MODE best_mode = DC_PRED;
3421 int r = INT_MAX, ry = INT_MAX;
3422 int64_t d = INT64_MAX, this_rd = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08003423 int j;
3424 const int pred_block_idx = idy * 2 + idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003425 if (cpi->common.frame_type == KEY_FRAME) {
Urvang Joshifeb925f2016-12-05 10:37:29 -08003426 const PREDICTION_MODE A =
3427 av1_above_block_mode(mic, above_mi, pred_block_idx);
3428 const PREDICTION_MODE L =
3429 av1_left_block_mode(mic, left_mi, pred_block_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003430
3431 bmode_costs = cpi->y_mode_costs[A][L];
3432 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003433 this_rd = rd_pick_intra_sub_8x8_y_subblock_mode(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003434 cpi, mb, idy, idx, &best_mode, bmode_costs,
3435 xd->plane[0].above_context + idx, xd->plane[0].left_context + idy, &r,
Urvang Joshifeb925f2016-12-05 10:37:29 -08003436 &ry, &d, bsize, tx_size, y_skip, best_rd - total_rd);
Yushin Cho7a428ba2017-01-12 16:28:49 -08003437#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003438 if (this_rd >= best_rd - total_rd) return INT64_MAX;
Fergus Simpson4063a682017-02-28 16:52:22 -08003439#endif // !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003440 total_rd += this_rd;
3441 cost += r;
3442 total_distortion += d;
3443 tot_rate_y += ry;
3444
Urvang Joshifeb925f2016-12-05 10:37:29 -08003445 mic->bmi[pred_block_idx].as_mode = best_mode;
3446 for (j = 1; j < pred_height_in_4x4_blocks; ++j)
3447 mic->bmi[pred_block_idx + j * 2].as_mode = best_mode;
3448 for (j = 1; j < pred_width_in_4x4_blocks; ++j)
3449 mic->bmi[pred_block_idx + j].as_mode = best_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003450
3451 if (total_rd >= best_rd) return INT64_MAX;
3452 }
3453 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08003454 mbmi->mode = mic->bmi[3].as_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003455
Yushin Cho7a428ba2017-01-12 16:28:49 -08003456#if CONFIG_DAALA_DIST
3457 {
3458 const struct macroblock_plane *p = &mb->plane[0];
3459 const struct macroblockd_plane *pd = &xd->plane[0];
3460 const int src_stride = p->src.stride;
3461 const int dst_stride = pd->dst.stride;
3462 uint8_t *src = p->src.buf;
3463 uint8_t *dst = pd->dst.buf;
3464 int use_activity_masking = 0;
3465 int qm = OD_HVS_QM;
3466
3467#if CONFIG_PVQ
3468 use_activity_masking = mb->daala_enc.use_activity_masking;
Fergus Simpson4063a682017-02-28 16:52:22 -08003469#endif // CONFIG_PVQ
Yushin Cho7a428ba2017-01-12 16:28:49 -08003470 // Daala-defined distortion computed for the block of 8x8 pixels
Yushin Cho8ab875d2017-06-23 14:47:21 -07003471 total_distortion =
3472 av1_daala_dist(xd, src, src_stride, dst, dst_stride, 8, 8, 8, 8, qm,
3473 use_activity_masking, mb->qindex)
3474 << 4;
Yushin Cho7a428ba2017-01-12 16:28:49 -08003475 }
Fergus Simpson4063a682017-02-28 16:52:22 -08003476#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07003477 // Add in the cost of the transform type
Urvang Joshifeb925f2016-12-05 10:37:29 -08003478 if (!is_lossless) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003479 int rate_tx_type = 0;
3480#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08003481 if (get_ext_tx_types(tx_size, bsize, 0, cpi->common.reduced_tx_set_used) >
3482 1) {
3483 const int eset =
3484 get_ext_tx_set(tx_size, bsize, 0, cpi->common.reduced_tx_set_used);
Urvang Joshifeb925f2016-12-05 10:37:29 -08003485 rate_tx_type = cpi->intra_tx_type_costs[eset][txsize_sqr_map[tx_size]]
3486 [mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003487 }
3488#else
clang-format67948d32016-09-07 22:40:40 -07003489 rate_tx_type =
Urvang Joshifeb925f2016-12-05 10:37:29 -08003490 cpi->intra_tx_type_costs[txsize_sqr_map[tx_size]]
3491 [intra_mode_to_tx_type_context[mbmi->mode]]
3492 [mbmi->tx_type];
Fergus Simpson4063a682017-02-28 16:52:22 -08003493#endif // CONFIG_EXT_TX
Urvang Joshifeb925f2016-12-05 10:37:29 -08003494 assert(mbmi->tx_size == tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003495 cost += rate_tx_type;
3496 tot_rate_y += rate_tx_type;
3497 }
3498
3499 *rate = cost;
3500 *rate_y = tot_rate_y;
3501 *distortion = total_distortion;
3502
Urvang Joshi70006e42017-06-14 16:08:55 -07003503 return RDCOST(mb->rdmult, cost, total_distortion);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003504}
3505
hui su5db97432016-10-14 16:10:14 -07003506#if CONFIG_FILTER_INTRA
3507// Return 1 if an filter intra mode is selected; return 0 otherwise.
3508static int rd_pick_filter_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
3509 int *rate, int *rate_tokenonly,
3510 int64_t *distortion, int *skippable,
3511 BLOCK_SIZE bsize, int mode_cost,
hui su8f4cc0a2017-01-13 15:14:49 -08003512 int64_t *best_rd, int64_t *best_model_rd,
3513 uint16_t skip_mask) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003514 MACROBLOCKD *const xd = &x->e_mbd;
3515 MODE_INFO *const mic = xd->mi[0];
3516 MB_MODE_INFO *mbmi = &mic->mbmi;
hui su5db97432016-10-14 16:10:14 -07003517 int filter_intra_selected_flag = 0;
hui su5db97432016-10-14 16:10:14 -07003518 FILTER_INTRA_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003519 TX_SIZE best_tx_size = TX_4X4;
hui su5db97432016-10-14 16:10:14 -07003520 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003521 TX_TYPE best_tx_type;
3522
hui su5db97432016-10-14 16:10:14 -07003523 av1_zero(filter_intra_mode_info);
3524 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003525 mbmi->mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07003526#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003527 mbmi->palette_mode_info.palette_size[0] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07003528#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003529
3530 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su8f4cc0a2017-01-13 15:14:49 -08003531 int this_rate;
3532 int64_t this_rd, this_model_rd;
3533 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003534 if (skip_mask & (1 << mode)) continue;
hui su5db97432016-10-14 16:10:14 -07003535 mbmi->filter_intra_mode_info.filter_intra_mode[0] = mode;
hui su8f4cc0a2017-01-13 15:14:49 -08003536 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3537 if (*best_model_rd != INT64_MAX &&
3538 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3539 continue;
3540 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003541 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
3542 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003543 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07003544 av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
Urvang Joshi70006e42017-06-14 16:08:55 -07003546 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003547
3548 if (this_rd < *best_rd) {
3549 *best_rd = this_rd;
3550 best_tx_size = mic->mbmi.tx_size;
hui su5db97432016-10-14 16:10:14 -07003551 filter_intra_mode_info = mbmi->filter_intra_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003552 best_tx_type = mic->mbmi.tx_type;
3553 *rate = this_rate;
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003554 *rate_tokenonly = tokenonly_rd_stats.rate;
3555 *distortion = tokenonly_rd_stats.dist;
3556 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07003557 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003558 }
3559 }
3560
hui su5db97432016-10-14 16:10:14 -07003561 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003562 mbmi->mode = DC_PRED;
3563 mbmi->tx_size = best_tx_size;
hui su5db97432016-10-14 16:10:14 -07003564 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] =
3565 filter_intra_mode_info.use_filter_intra_mode[0];
3566 mbmi->filter_intra_mode_info.filter_intra_mode[0] =
3567 filter_intra_mode_info.filter_intra_mode[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003568 mbmi->tx_type = best_tx_type;
3569 return 1;
3570 } else {
3571 return 0;
3572 }
3573}
hui su5db97432016-10-14 16:10:14 -07003574#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003575
hui su5db97432016-10-14 16:10:14 -07003576#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08003577// Run RD calculation with given luma intra prediction angle., and return
3578// the RD cost. Update the best mode info. if the RD cost is the best so far.
3579static int64_t calc_rd_given_intra_angle(
3580 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mode_cost,
3581 int64_t best_rd_in, int8_t angle_delta, int max_angle_delta, int *rate,
3582 RD_STATS *rd_stats, int *best_angle_delta, TX_SIZE *best_tx_size,
3583 TX_TYPE *best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003584#if CONFIG_INTRA_INTERP
3585 INTRA_FILTER *best_filter,
3586#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003587 int64_t *best_rd, int64_t *best_model_rd) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003588 int this_rate;
3589 RD_STATS tokenonly_rd_stats;
hui su9a416f52017-01-13 11:37:53 -08003590 int64_t this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003591 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003592 assert(!is_inter_block(mbmi));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003593
hui su45dc5972016-12-08 17:42:50 -08003594 mbmi->angle_delta[0] = angle_delta;
hui su9a416f52017-01-13 11:37:53 -08003595 this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
3596 if (*best_model_rd != INT64_MAX &&
3597 this_model_rd > *best_model_rd + (*best_model_rd >> 1))
3598 return INT64_MAX;
3599 if (this_model_rd < *best_model_rd) *best_model_rd = this_model_rd;
hui su45dc5972016-12-08 17:42:50 -08003600 super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in);
3601 if (tokenonly_rd_stats.rate == INT_MAX) return INT64_MAX;
3602
3603 this_rate = tokenonly_rd_stats.rate + mode_cost +
3604 write_uniform_cost(2 * max_angle_delta + 1,
3605 mbmi->angle_delta[0] + max_angle_delta);
Urvang Joshi70006e42017-06-14 16:08:55 -07003606 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003607
3608 if (this_rd < *best_rd) {
3609 *best_rd = this_rd;
3610 *best_angle_delta = mbmi->angle_delta[0];
3611 *best_tx_size = mbmi->tx_size;
hui sueda3d762016-12-06 16:58:23 -08003612#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003613 *best_filter = mbmi->intra_filter;
hui sueda3d762016-12-06 16:58:23 -08003614#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003615 *best_tx_type = mbmi->tx_type;
3616 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08003617 rd_stats->rate = tokenonly_rd_stats.rate;
3618 rd_stats->dist = tokenonly_rd_stats.dist;
3619 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 }
hui su45dc5972016-12-08 17:42:50 -08003621 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003622}
3623
hui su45dc5972016-12-08 17:42:50 -08003624// With given luma directional intra prediction mode, pick the best angle delta
3625// Return the RD cost corresponding to the best angle delta.
Urvang Joshi52648442016-10-13 17:27:51 -07003626static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
hui su45dc5972016-12-08 17:42:50 -08003627 int *rate, RD_STATS *rd_stats,
3628 BLOCK_SIZE bsize, int mode_cost,
hui su9a416f52017-01-13 11:37:53 -08003629 int64_t best_rd,
3630 int64_t *best_model_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003631 MACROBLOCKD *const xd = &x->e_mbd;
3632 MODE_INFO *const mic = xd->mi[0];
3633 MB_MODE_INFO *mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003634 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08003635 int i, angle_delta, best_angle_delta = 0;
hui su45dc5972016-12-08 17:42:50 -08003636 int first_try = 1;
hui sueda3d762016-12-06 16:58:23 -08003637#if CONFIG_INTRA_INTERP
3638 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07003639 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003640 INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -08003641#endif // CONFIG_INTRA_INTERP
Debargha Mukherjeedf0e0d72017-04-27 15:16:53 -07003642 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003643 TX_SIZE best_tx_size = mic->mbmi.tx_size;
3644 TX_TYPE best_tx_type = mbmi->tx_type;
3645
hui su0a6731f2017-04-26 15:23:47 -07003646 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003647
hui su0a6731f2017-04-26 15:23:47 -07003648 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui sueda3d762016-12-06 16:58:23 -08003649#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003650 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3651 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3652 mic->mbmi.intra_filter = filter;
hui sueda3d762016-12-06 16:58:23 -08003653#endif // CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003654 for (i = 0; i < 2; ++i) {
3655 best_rd_in = (best_rd == INT64_MAX)
3656 ? INT64_MAX
3657 : (best_rd + (best_rd >> (first_try ? 3 : 5)));
3658 this_rd = calc_rd_given_intra_angle(
3659 cpi, x, bsize,
hui sueda3d762016-12-06 16:58:23 -08003660#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003661 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui sueda3d762016-12-06 16:58:23 -08003662#else
hui su45dc5972016-12-08 17:42:50 -08003663 mode_cost,
hui sueda3d762016-12-06 16:58:23 -08003664#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003665 best_rd_in, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003666 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
hui sueda3d762016-12-06 16:58:23 -08003667#if CONFIG_INTRA_INTERP
3668 &best_filter,
3669#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003670 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003671 rd_cost[2 * angle_delta + i] = this_rd;
3672 if (first_try && this_rd == INT64_MAX) return best_rd;
3673 first_try = 0;
3674 if (angle_delta == 0) {
3675 rd_cost[1] = this_rd;
3676 break;
3677 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003678 }
hui su45dc5972016-12-08 17:42:50 -08003679#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003680 }
hui su45dc5972016-12-08 17:42:50 -08003681#endif // CONFIG_INTRA_INTERP
3682 }
3683
3684 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07003685 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08003686 int64_t rd_thresh;
3687#if CONFIG_INTRA_INTERP
3688 for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) {
3689 if (FILTER_FAST_SEARCH && filter != INTRA_FILTER_LINEAR) continue;
3690 mic->mbmi.intra_filter = filter;
3691#endif // CONFIG_INTRA_INTERP
3692 for (i = 0; i < 2; ++i) {
3693 int skip_search = 0;
3694 rd_thresh = best_rd + (best_rd >> 5);
3695 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
3696 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
3697 skip_search = 1;
3698 if (!skip_search) {
Yue Chenb0f808b2017-04-26 11:55:14 -07003699 calc_rd_given_intra_angle(
hui su45dc5972016-12-08 17:42:50 -08003700 cpi, x, bsize,
3701#if CONFIG_INTRA_INTERP
3702 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
3703#else
3704 mode_cost,
3705#endif // CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07003706 best_rd, (1 - 2 * i) * angle_delta, MAX_ANGLE_DELTA, rate,
hui su45dc5972016-12-08 17:42:50 -08003707 rd_stats, &best_angle_delta, &best_tx_size, &best_tx_type,
3708#if CONFIG_INTRA_INTERP
3709 &best_filter,
3710#endif // CONFIG_INTRA_INTERP
hui su9a416f52017-01-13 11:37:53 -08003711 &best_rd, best_model_rd);
hui su45dc5972016-12-08 17:42:50 -08003712 }
3713 }
3714#if CONFIG_INTRA_INTERP
3715 }
3716#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003717 }
3718
hui sueda3d762016-12-06 16:58:23 -08003719#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08003720 if (FILTER_FAST_SEARCH && rd_stats->rate < INT_MAX) {
hui su0a6731f2017-04-26 15:23:47 -07003721 p_angle = mode_to_angle_map[mbmi->mode] + best_angle_delta * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07003722 if (av1_is_intra_filter_switchable(p_angle)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 for (filter = INTRA_FILTER_LINEAR + 1; filter < INTRA_FILTERS; ++filter) {
3724 mic->mbmi.intra_filter = filter;
hui su45dc5972016-12-08 17:42:50 -08003725 this_rd = calc_rd_given_intra_angle(
3726 cpi, x, bsize,
3727 mode_cost + cpi->intra_filter_cost[intra_filter_ctx][filter],
hui su0a6731f2017-04-26 15:23:47 -07003728 best_rd, best_angle_delta, MAX_ANGLE_DELTA, rate, rd_stats,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003729 &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter,
hui su9a416f52017-01-13 11:37:53 -08003730 &best_rd, best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003731 }
3732 }
3733 }
hui sueda3d762016-12-06 16:58:23 -08003734#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003735
3736 mbmi->tx_size = best_tx_size;
3737 mbmi->angle_delta[0] = best_angle_delta;
hui sueda3d762016-12-06 16:58:23 -08003738#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003739 mic->mbmi.intra_filter = best_filter;
hui sueda3d762016-12-06 16:58:23 -08003740#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07003741 mbmi->tx_type = best_tx_type;
3742 return best_rd;
3743}
3744
3745// Indices are sign, integer, and fractional part of the gradient value
3746static const uint8_t gradient_to_angle_bin[2][7][16] = {
3747 {
3748 { 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0 },
3749 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
3750 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3751 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3752 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
3753 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3754 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3755 },
3756 {
3757 { 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4 },
3758 { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3 },
3759 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3760 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3761 { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
3762 { 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3763 { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
3764 },
3765};
3766
Yue Chen56e226e2017-05-02 16:21:40 -07003767/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003768static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
3769 0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
hui su9cc10652017-04-27 17:22:07 -07003770#if CONFIG_ALT_INTRA
3771 0,
3772#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07003773};
Yue Chen56e226e2017-05-02 16:21:40 -07003774/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07003775
3776static void angle_estimation(const uint8_t *src, int src_stride, int rows,
hui su9cc10652017-04-27 17:22:07 -07003777 int cols, BLOCK_SIZE bsize,
3778 uint8_t *directional_mode_skip_mask) {
3779 memset(directional_mode_skip_mask, 0,
3780 INTRA_MODES * sizeof(*directional_mode_skip_mask));
Joe Young830d4ce2017-05-30 17:48:13 -07003781 // Check if angle_delta is used
3782 if (!av1_use_angle_delta(bsize)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003783 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003784 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3785 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003786 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003787 for (r = 1; r < rows; ++r) {
3788 for (c = 1; c < cols; ++c) {
3789 dx = src[c] - src[c - 1];
3790 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003791 int index;
3792 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003793 if (dy == 0) {
3794 index = 2;
3795 } else {
hui su9cc10652017-04-27 17:22:07 -07003796 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003797 dx = abs(dx);
3798 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003799 const int remd = (dx % dy) * 16 / dy;
3800 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003801 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003802 }
3803 hist[index] += temp;
3804 }
3805 src += src_stride;
3806 }
3807
hui su9cc10652017-04-27 17:22:07 -07003808 int i;
3809 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003810 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3811 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003812 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003813 const uint8_t angle_bin = mode_to_angle_bin[i];
3814 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003815 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003816 if (angle_bin > 0) {
3817 score += hist[angle_bin - 1];
3818 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003820 if (angle_bin < DIRECTIONAL_MODES - 1) {
3821 score += hist[angle_bin + 1];
3822 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003823 }
3824 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3825 directional_mode_skip_mask[i] = 1;
3826 }
3827 }
3828}
3829
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003830#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003831static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
hui su9cc10652017-04-27 17:22:07 -07003832 int rows, int cols, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003833 uint8_t *directional_mode_skip_mask) {
hui su9cc10652017-04-27 17:22:07 -07003834 memset(directional_mode_skip_mask, 0,
3835 INTRA_MODES * sizeof(*directional_mode_skip_mask));
Joe Young830d4ce2017-05-30 17:48:13 -07003836 // Check if angle_delta is used
3837 if (!av1_use_angle_delta(bsize)) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003838 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
hui su9cc10652017-04-27 17:22:07 -07003839 uint64_t hist[DIRECTIONAL_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840 memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
3841 src += src_stride;
hui su9cc10652017-04-27 17:22:07 -07003842 int r, c, dx, dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003843 for (r = 1; r < rows; ++r) {
3844 for (c = 1; c < cols; ++c) {
3845 dx = src[c] - src[c - 1];
3846 dy = src[c] - src[c - src_stride];
hui su9cc10652017-04-27 17:22:07 -07003847 int index;
3848 const int temp = dx * dx + dy * dy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003849 if (dy == 0) {
3850 index = 2;
3851 } else {
hui su9cc10652017-04-27 17:22:07 -07003852 const int sn = (dx > 0) ^ (dy > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003853 dx = abs(dx);
3854 dy = abs(dy);
hui su9cc10652017-04-27 17:22:07 -07003855 const int remd = (dx % dy) * 16 / dy;
3856 const int quot = dx / dy;
Yaowu Xuf883b422016-08-30 14:01:10 -07003857 index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003858 }
3859 hist[index] += temp;
3860 }
3861 src += src_stride;
3862 }
3863
hui su9cc10652017-04-27 17:22:07 -07003864 int i;
3865 uint64_t hist_sum = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003866 for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
3867 for (i = 0; i < INTRA_MODES; ++i) {
hui su9cc10652017-04-27 17:22:07 -07003868 if (av1_is_directional_mode(i, bsize)) {
Urvang Joshida70e7b2016-10-19 11:48:54 -07003869 const uint8_t angle_bin = mode_to_angle_bin[i];
3870 uint64_t score = 2 * hist[angle_bin];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003871 int weight = 2;
Urvang Joshida70e7b2016-10-19 11:48:54 -07003872 if (angle_bin > 0) {
3873 score += hist[angle_bin - 1];
3874 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003875 }
Urvang Joshida70e7b2016-10-19 11:48:54 -07003876 if (angle_bin < DIRECTIONAL_MODES - 1) {
3877 score += hist[angle_bin + 1];
3878 ++weight;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879 }
3880 if (score * ANGLE_SKIP_THRESH < hist_sum * weight)
3881 directional_mode_skip_mask[i] = 1;
3882 }
3883 }
3884}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003885#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003886#endif // CONFIG_EXT_INTRA
3887
3888// This function is used only for intra_only frames
Urvang Joshi52648442016-10-13 17:27:51 -07003889static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
3890 int *rate, int *rate_tokenonly,
3891 int64_t *distortion, int *skippable,
3892 BLOCK_SIZE bsize, int64_t best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003893 uint8_t mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 MACROBLOCKD *const xd = &x->e_mbd;
3895 MODE_INFO *const mic = xd->mi[0];
hui sude0c70a2017-01-09 17:12:17 -08003896 MB_MODE_INFO *const mbmi = &mic->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07003897 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08003898 MB_MODE_INFO best_mbmi = *mbmi;
hui su308a6392017-01-12 14:49:57 -08003899 int64_t best_model_rd = INT64_MAX;
hui sude0c70a2017-01-09 17:12:17 -08003900#if CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08003901 const int rows = block_size_high[bsize];
3902 const int cols = block_size_wide[bsize];
hui sueda3d762016-12-06 16:58:23 -08003903#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07003904 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui sueda3d762016-12-06 16:58:23 -08003905#endif // CONFIG_INTRA_INTERP
hui sude0c70a2017-01-09 17:12:17 -08003906 int is_directional_mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003907 uint8_t directional_mode_skip_mask[INTRA_MODES];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003908 const int src_stride = x->plane[0].src.stride;
3909 const uint8_t *src = x->plane[0].src.buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003911#if CONFIG_FILTER_INTRA
3912 int beat_best_rd = 0;
hui su5db97432016-10-14 16:10:14 -07003913 uint16_t filter_intra_mode_skip_mask = (1 << FILTER_INTRA_MODES) - 1;
3914#endif // CONFIG_FILTER_INTRA
Urvang Joshi52648442016-10-13 17:27:51 -07003915 const int *bmode_costs;
Urvang Joshib100db72016-10-12 16:28:56 -07003916#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08003917 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918 uint8_t *best_palette_color_map =
3919 cpi->common.allow_screen_content_tools
3920 ? x->palette_buffer->best_palette_color_map
3921 : NULL;
Urvang Joshi23a61112017-01-30 14:59:27 -08003922 int palette_y_mode_ctx = 0;
hui su9bc1d8d2017-03-24 12:36:03 -07003923 const int try_palette =
3924 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Urvang Joshib100db72016-10-12 16:28:56 -07003925#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003926 const MODE_INFO *above_mi = xd->above_mi;
3927 const MODE_INFO *left_mi = xd->left_mi;
Yaowu Xuf883b422016-08-30 14:01:10 -07003928 const PREDICTION_MODE A = av1_above_block_mode(mic, above_mi, 0);
3929 const PREDICTION_MODE L = av1_left_block_mode(mic, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003930 const PREDICTION_MODE FINAL_MODE_SEARCH = TM_PRED + 1;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003931#if CONFIG_PVQ
3932 od_rollback_buffer pre_buf, post_buf;
3933
3934 od_encode_checkpoint(&x->daala_enc, &pre_buf);
3935 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003936#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937 bmode_costs = cpi->y_mode_costs[A][L];
3938
3939#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003940 mbmi->angle_delta[0] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003941#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -07003943 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003944 directional_mode_skip_mask);
3945 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003946#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -07003947 angle_estimation(src, src_stride, rows, cols, bsize,
3948 directional_mode_skip_mask);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003949#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07003950#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003951 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
hui su5db97432016-10-14 16:10:14 -07003952#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07003953#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954 pmi->palette_size[0] = 0;
3955 if (above_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003956 palette_y_mode_ctx +=
3957 (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003958 if (left_mi)
Urvang Joshi23a61112017-01-30 14:59:27 -08003959 palette_y_mode_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Urvang Joshib100db72016-10-12 16:28:56 -07003960#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07003961
3962 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
3963 x->use_default_intra_tx_type = 1;
3964 else
3965 x->use_default_intra_tx_type = 0;
3966
3967 /* Y Search for intra prediction mode */
3968 for (mode_idx = DC_PRED; mode_idx <= FINAL_MODE_SEARCH; ++mode_idx) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003969 RD_STATS this_rd_stats;
hui su308a6392017-01-12 14:49:57 -08003970 int this_rate, this_rate_tokenonly, s;
3971 int64_t this_distortion, this_rd, this_model_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003972 if (mode_idx == FINAL_MODE_SEARCH) {
3973 if (x->use_default_intra_tx_type == 0) break;
hui sude0c70a2017-01-09 17:12:17 -08003974 mbmi->mode = best_mbmi.mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 x->use_default_intra_tx_type = 0;
3976 } else {
hui sude0c70a2017-01-09 17:12:17 -08003977 mbmi->mode = mode_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003979#if CONFIG_PVQ
3980 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08003981#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003982#if CONFIG_EXT_INTRA
hui su308a6392017-01-12 14:49:57 -08003983 mbmi->angle_delta[0] = 0;
3984#endif // CONFIG_EXT_INTRA
hui su9a416f52017-01-13 11:37:53 -08003985 this_model_rd = intra_model_yrd(cpi, x, bsize, bmode_costs[mbmi->mode]);
hui su308a6392017-01-12 14:49:57 -08003986 if (best_model_rd != INT64_MAX &&
3987 this_model_rd > best_model_rd + (best_model_rd >> 1))
3988 continue;
3989 if (this_model_rd < best_model_rd) best_model_rd = this_model_rd;
3990#if CONFIG_EXT_INTRA
hui sude0c70a2017-01-09 17:12:17 -08003991 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
3992 if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
Joe Young830d4ce2017-05-30 17:48:13 -07003993 if (is_directional_mode && av1_use_angle_delta(bsize)) {
hui su45dc5972016-12-08 17:42:50 -08003994 this_rd_stats.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -07003995 rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
3996 bmode_costs[mbmi->mode], best_rd, &best_model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003997 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -08003998 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999 }
4000#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -08004001 super_block_yrd(cpi, x, &this_rd_stats, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -08004002#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -08004003 this_rate_tokenonly = this_rd_stats.rate;
4004 this_distortion = this_rd_stats.dist;
4005 s = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004006
4007 if (this_rate_tokenonly == INT_MAX) continue;
4008
hui sude0c70a2017-01-09 17:12:17 -08004009 this_rate = this_rate_tokenonly + bmode_costs[mbmi->mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004010
hui sude0c70a2017-01-09 17:12:17 -08004011 if (!xd->lossless[mbmi->segment_id] && mbmi->sb_type >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004012 // super_block_yrd above includes the cost of the tx_size in the
4013 // tokenonly rate, but for intra blocks, tx_size is always coded
4014 // (prediction granularity), so we account for it in the full rate,
4015 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08004016 this_rate_tokenonly -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004017 }
Urvang Joshib100db72016-10-12 16:28:56 -07004018#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07004019 if (try_palette && mbmi->mode == DC_PRED) {
Urvang Joshi23a61112017-01-30 14:59:27 -08004020 this_rate +=
4021 av1_cost_bit(av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
4022 [palette_y_mode_ctx],
4023 0);
hui su9bc1d8d2017-03-24 12:36:03 -07004024 }
Urvang Joshib100db72016-10-12 16:28:56 -07004025#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07004026#if CONFIG_FILTER_INTRA
hui sude0c70a2017-01-09 17:12:17 -08004027 if (mbmi->mode == DC_PRED)
hui su5db97432016-10-14 16:10:14 -07004028 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[0], 0);
4029#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004030#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004031 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -08004032#if CONFIG_INTRA_INTERP
hui su0a6731f2017-04-26 15:23:47 -07004033 const int p_angle =
4034 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07004035 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004036 this_rate +=
hui sude0c70a2017-01-09 17:12:17 -08004037 cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -08004038#endif // CONFIG_INTRA_INTERP
Joe Young830d4ce2017-05-30 17:48:13 -07004039 if (av1_use_angle_delta(bsize)) {
4040 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
4041 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
4042 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004043 }
4044#endif // CONFIG_EXT_INTRA
Urvang Joshi70006e42017-06-14 16:08:55 -07004045 this_rd = RDCOST(x->rdmult, this_rate, this_distortion);
hui su5db97432016-10-14 16:10:14 -07004046#if CONFIG_FILTER_INTRA
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -07004047 if (best_rd == INT64_MAX || this_rd - best_rd < (best_rd >> 4)) {
hui sude0c70a2017-01-09 17:12:17 -08004048 filter_intra_mode_skip_mask ^= (1 << mbmi->mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004049 }
hui su5db97432016-10-14 16:10:14 -07004050#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004051
4052 if (this_rd < best_rd) {
hui sude0c70a2017-01-09 17:12:17 -08004053 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 best_rd = this_rd;
hui su5db97432016-10-14 16:10:14 -07004055#if CONFIG_FILTER_INTRA
4056 beat_best_rd = 1;
4057#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004058 *rate = this_rate;
4059 *rate_tokenonly = this_rate_tokenonly;
4060 *distortion = this_distortion;
4061 *skippable = s;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004062#if CONFIG_PVQ
4063 od_encode_checkpoint(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004064#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004065 }
4066 }
4067
Yushin Cho77bba8d2016-11-04 16:36:56 -07004068#if CONFIG_PVQ
4069 od_encode_rollback(&x->daala_enc, &post_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08004070#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004071
Urvang Joshib100db72016-10-12 16:28:56 -07004072#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07004073 if (try_palette) {
Urvang Joshi23a61112017-01-30 14:59:27 -08004074 rd_pick_palette_intra_sby(cpi, x, bsize, palette_y_mode_ctx,
4075 bmode_costs[DC_PRED], &best_mbmi,
4076 best_palette_color_map, &best_rd, &best_model_rd,
4077 rate, rate_tokenonly, distortion, skippable);
hui sude0c70a2017-01-09 17:12:17 -08004078 }
Urvang Joshib100db72016-10-12 16:28:56 -07004079#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004080
hui su5db97432016-10-14 16:10:14 -07004081#if CONFIG_FILTER_INTRA
4082 if (beat_best_rd) {
4083 if (rd_pick_filter_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
4084 skippable, bsize, bmode_costs[DC_PRED],
hui su8f4cc0a2017-01-13 15:14:49 -08004085 &best_rd, &best_model_rd,
4086 filter_intra_mode_skip_mask)) {
hui sude0c70a2017-01-09 17:12:17 -08004087 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004088 }
4089 }
hui su5db97432016-10-14 16:10:14 -07004090#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004091
hui sude0c70a2017-01-09 17:12:17 -08004092 *mbmi = best_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004093 return best_rd;
4094}
4095
Yue Chena1e48dc2016-08-29 17:29:33 -07004096// Return value 0: early termination triggered, no valid rd cost available;
4097// 1: rd cost values are valid.
Angie Chiang284d7772016-11-08 11:06:45 -08004098static int super_block_uvrd(const AV1_COMP *const cpi, MACROBLOCK *x,
4099 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4100 int64_t ref_best_rd) {
Yue Chena1e48dc2016-08-29 17:29:33 -07004101 MACROBLOCKD *const xd = &x->e_mbd;
4102 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4103 const TX_SIZE uv_tx_size = get_uv_tx_size(mbmi, &xd->plane[1]);
4104 int plane;
Yue Chena1e48dc2016-08-29 17:29:33 -07004105 int is_cost_valid = 1;
Angie Chiang284d7772016-11-08 11:06:45 -08004106 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004107
4108 if (ref_best_rd < 0) is_cost_valid = 0;
Jingning Han9ce464c2017-02-20 15:36:30 -08004109
Jingning Han31b6a4f2017-02-23 11:05:53 -08004110#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004111 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han2d2dac22017-04-11 09:41:10 -07004112
4113 bsize = scale_chroma_bsize(bsize, xd->plane[1].subsampling_x,
4114 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08004115#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004116
Yushin Cho77bba8d2016-11-04 16:36:56 -07004117#if !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07004118 if (is_inter_block(mbmi) && is_cost_valid) {
Yue Chena1e48dc2016-08-29 17:29:33 -07004119 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
4120 av1_subtract_plane(x, bsize, plane);
4121 }
Fergus Simpson4063a682017-02-28 16:52:22 -08004122#endif // !CONFIG_PVQ
Yue Chena1e48dc2016-08-29 17:29:33 -07004123
Yushin Cho09de28b2016-06-21 14:51:23 -07004124 if (is_cost_valid) {
4125 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
Angie Chiang7c2b7f22016-11-07 16:00:00 -08004126 RD_STATS pn_rd_stats;
4127 txfm_rd_in_plane(x, cpi, &pn_rd_stats, ref_best_rd, plane, bsize,
4128 uv_tx_size, cpi->sf.use_fast_coef_costing);
4129 if (pn_rd_stats.rate == INT_MAX) {
Yushin Cho09de28b2016-06-21 14:51:23 -07004130 is_cost_valid = 0;
4131 break;
4132 }
Angie Chiang284d7772016-11-08 11:06:45 -08004133 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Urvang Joshi70006e42017-06-14 16:08:55 -07004134 if (RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist) > ref_best_rd &&
4135 RDCOST(x->rdmult, 0, rd_stats->sse) > ref_best_rd) {
Yushin Cho09de28b2016-06-21 14:51:23 -07004136 is_cost_valid = 0;
4137 break;
4138 }
Yue Chena1e48dc2016-08-29 17:29:33 -07004139 }
4140 }
4141
4142 if (!is_cost_valid) {
4143 // reset cost value
Angie Chiang284d7772016-11-08 11:06:45 -08004144 av1_invalid_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004145 }
4146
4147 return is_cost_valid;
4148}
4149
Yaowu Xuc27fc142016-08-22 16:08:15 -07004150#if CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004151void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
4152 int blk_row, int blk_col, int plane, int block,
Angie Chiang77368af2017-03-23 16:22:07 -07004153 int plane_bsize, const ENTROPY_CONTEXT *a,
4154 const ENTROPY_CONTEXT *l, RD_STATS *rd_stats) {
Angie Chiang22ba7512016-10-20 17:10:33 -07004155 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 MACROBLOCKD *xd = &x->e_mbd;
4157 const struct macroblock_plane *const p = &x->plane[plane];
4158 struct macroblockd_plane *const pd = &xd->plane[plane];
Jingning Han243b66b2017-06-23 12:11:47 -07004159
4160#if CONFIG_TXK_SEL
4161 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
4162 tx_size, a, l, 0, rd_stats);
4163 return;
4164#endif
4165
Yaowu Xuc27fc142016-08-22 16:08:15 -07004166 int64_t tmp;
4167 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05004168 PLANE_TYPE plane_type = get_plane_type(plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004169 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -07004170 const SCAN_ORDER *const scan_order =
Angie Chiangbd99b382017-06-20 15:11:16 -07004171 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004172 BLOCK_SIZE txm_bsize = txsize_to_bsize[tx_size];
Jingning Han9fdc4222016-10-27 21:32:19 -07004173 int bh = block_size_high[txm_bsize];
4174 int bw = block_size_wide[txm_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004175 int src_stride = p->src.stride;
Jingning Han9ca05b72017-01-03 14:41:36 -08004176 uint8_t *src =
4177 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
4178 uint8_t *dst =
4179 &pd->dst
4180 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004181#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004182 DECLARE_ALIGNED(16, uint16_t, rec_buffer16[MAX_TX_SQUARE]);
4183 uint8_t *rec_buffer;
4184#else
4185 DECLARE_ALIGNED(16, uint8_t, rec_buffer[MAX_TX_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004186#endif // CONFIG_HIGHBITDEPTH
Timothy B. Terriberryd62e2a32017-06-10 16:04:21 -07004187 const int diff_stride = block_size_wide[plane_bsize];
Jingning Han9ca05b72017-01-03 14:41:36 -08004188 const int16_t *diff =
4189 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiangd81fdb42016-11-03 12:20:58 -07004190 int txb_coeff_cost;
Jingning Hand3fada82016-11-22 10:46:55 -08004191
4192 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004193
Angie Chiang77368af2017-03-23 16:22:07 -07004194 int coeff_ctx = get_entropy_context(tx_size, a, l);
4195
Jingning Hane3b81bc2017-06-23 11:43:52 -07004196#if CONFIG_TXK_SEL
4197 av1_search_txk_type(cpi, x, plane, block, blk_row, blk_col, plane_bsize,
4198 tx_size, a, l, 0, rd_stats);
4199 return;
4200#endif
4201
Sarah Parker5680a012017-06-21 09:41:25 -07004202#if DISABLE_TRELLISQ_SEARCH
4203 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
4204 coeff_ctx, AV1_XFORM_QUANT_B);
4205
4206#else
Angie Chiangff6d8902016-10-21 11:02:09 -07004207 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08004208 coeff_ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209
Angie Chiang3511c372017-05-31 12:47:07 -07004210 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Sarah Parker5680a012017-06-21 09:41:25 -07004211#endif // DISABLE_TRELLISQ_SEARCH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004212
Angie Chiang808d8592017-04-06 18:36:55 -07004213// TODO(any): Use av1_dist_block to compute distortion
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004214#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4216 rec_buffer = CONVERT_TO_BYTEPTR(rec_buffer16);
Yaowu Xuf883b422016-08-30 14:01:10 -07004217 aom_highbd_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07004218 0, NULL, 0, bw, bh, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004219 } else {
4220 rec_buffer = (uint8_t *)rec_buffer16;
Yaowu Xuf883b422016-08-30 14:01:10 -07004221 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0,
Jingning Han9fdc4222016-10-27 21:32:19 -07004222 NULL, 0, bw, bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004223 }
4224#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004225 aom_convolve_copy(dst, pd->dst.stride, rec_buffer, MAX_TX_SIZE, NULL, 0, NULL,
Jingning Han9fdc4222016-10-27 21:32:19 -07004226 0, bw, bh);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004227#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228
Yushin Cho75b01002017-06-21 13:43:57 -07004229 tmp = pixel_diff_dist(x, plane, diff, diff_stride, blk_row, blk_col,
4230 plane_bsize, txm_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004232#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004233 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
4234 tmp = ROUND_POWER_OF_TWO(tmp, (xd->bd - 8) * 2);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004235#endif // CONFIG_HIGHBITDEPTH
Angie Chiangb5dda482016-11-02 16:19:58 -07004236 rd_stats->sse += tmp * 16;
Angie Chiang41fffae2017-04-03 10:33:18 -07004237 const int eob = p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238
Angie Chiang41fffae2017-04-03 10:33:18 -07004239 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, rec_buffer,
4240 MAX_TX_SIZE, eob);
4241 if (eob > 0) {
Yushin Cho04749122017-05-25 14:19:07 -07004242#if CONFIG_DAALA_DIST
4243 if (plane == 0 && (bw < 8 && bh < 8)) {
4244 // Save sub8x8 luma decoded pixels
4245 // since 8x8 luma decoded pixels are not available for daala-dist
4246 // after recursive split of BLOCK_8x8 is done.
4247 const int pred_stride = block_size_wide[plane_bsize];
4248 const int pred_idx = (blk_row * pred_stride + blk_col)
4249 << tx_size_wide_log2[0];
4250 int16_t *decoded = &pd->pred[pred_idx];
4251 int i, j;
4252
Yushin Cho8ab875d2017-06-23 14:47:21 -07004253#if CONFIG_HIGHBITDEPTH
4254 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4255 for (j = 0; j < bh; j++)
4256 for (i = 0; i < bw; i++)
4257 decoded[j * pred_stride + i] =
4258 CONVERT_TO_SHORTPTR(rec_buffer)[j * MAX_TX_SIZE + i];
4259 } else {
4260#endif
4261 for (j = 0; j < bh; j++)
4262 for (i = 0; i < bw; i++)
4263 decoded[j * pred_stride + i] = rec_buffer[j * MAX_TX_SIZE + i];
4264#if CONFIG_HIGHBITDEPTH
4265 }
4266#endif // CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004267 }
4268#endif // CONFIG_DAALA_DIST
Yushin Cho75b01002017-06-21 13:43:57 -07004269 tmp = pixel_dist(cpi, x, plane, src, src_stride, rec_buffer, MAX_TX_SIZE,
4270 blk_row, blk_col, plane_bsize, txm_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004271 }
Angie Chiangb5dda482016-11-02 16:19:58 -07004272 rd_stats->dist += tmp * 16;
Angie Chiang77368af2017-03-23 16:22:07 -07004273 txb_coeff_cost =
Angie Chiang05917872017-04-15 12:28:56 -07004274 av1_cost_coeffs(cpi, x, plane, block, tx_size, scan_order, a, l, 0);
Angie Chiangd81fdb42016-11-03 12:20:58 -07004275 rd_stats->rate += txb_coeff_cost;
Angie Chiang41fffae2017-04-03 10:33:18 -07004276 rd_stats->skip &= (eob == 0);
Jingning Han63cbf342016-11-09 15:37:48 -08004277
Angie Chiangd81fdb42016-11-03 12:20:58 -07004278#if CONFIG_RD_DEBUG
Angie Chiange94556b2016-11-09 10:59:30 -08004279 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4280 txb_coeff_cost);
Fergus Simpson4063a682017-02-28 16:52:22 -08004281#endif // CONFIG_RD_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282}
4283
Yaowu Xuf883b422016-08-30 14:01:10 -07004284static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Jingning Han63cbf342016-11-09 15:37:48 -08004285 int blk_col, int plane, int block, int block32,
4286 TX_SIZE tx_size, int depth, BLOCK_SIZE plane_bsize,
Jingning Han94d5bfc2016-10-21 10:14:36 -07004287 ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
4288 TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
Angie Chiangb5dda482016-11-02 16:19:58 -07004289 RD_STATS *rd_stats, int64_t ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004290 int *is_cost_valid, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004291 MACROBLOCKD *const xd = &x->e_mbd;
4292 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4293 struct macroblock_plane *const p = &x->plane[plane];
4294 struct macroblockd_plane *const pd = &xd->plane[plane];
4295 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4296 const int tx_col = blk_col >> (1 - pd->subsampling_x);
clang-format67948d32016-09-07 22:40:40 -07004297 TX_SIZE(*const inter_tx_size)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004298 [MAX_MIB_SIZE] =
4299 (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
Jingning Hanf65b8702016-10-31 12:13:20 -07004300 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4301 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Han58224042016-10-27 16:35:32 -07004302 const int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004303 int64_t this_rd = INT64_MAX;
4304 ENTROPY_CONTEXT *pta = ta + blk_col;
4305 ENTROPY_CONTEXT *ptl = tl + blk_row;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306 int coeff_ctx, i;
Jingning Han331662e2017-05-30 17:03:32 -07004307 int ctx = txfm_partition_context(tx_above + blk_col, tx_left + blk_row,
4308 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004309 int64_t sum_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004310 int tmp_eob = 0;
4311 int zero_blk_rate;
Angie Chiangd7246172016-11-03 11:49:15 -07004312 RD_STATS sum_rd_stats;
Jingning Han1c019f92016-11-21 12:53:32 -08004313 const int tx_size_ctx = txsize_sqr_map[tx_size];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004314#if CONFIG_TXK_SEL
4315 TX_TYPE best_tx_type = TX_TYPES;
4316 int txk_idx = block;
4317#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004318
Jingning Han63cbf342016-11-09 15:37:48 -08004319 av1_init_rd_stats(&sum_rd_stats);
Jingning Hanfe45b212016-11-22 10:30:23 -08004320
Jingning Hand3fada82016-11-22 10:46:55 -08004321 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004322
4323 if (ref_best_rd < 0) {
4324 *is_cost_valid = 0;
4325 return;
4326 }
4327
Jingning Hance059e82016-10-31 16:27:28 -07004328 coeff_ctx = get_entropy_context(tx_size, pta, ptl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004329
Angie Chiangc0feea82016-11-03 15:36:18 -07004330 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004331
4332 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4333
Jingning Han1c019f92016-11-21 12:53:32 -08004334 zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
4335 [coeff_ctx][EOB_TOKEN];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004336
4337 if (cpi->common.tx_mode == TX_MODE_SELECT || tx_size == TX_4X4) {
4338 inter_tx_size[0][0] = tx_size;
Jingning Han63cbf342016-11-09 15:37:48 -08004339
4340 if (tx_size == TX_32X32 && mbmi->tx_type != DCT_DCT &&
4341 rd_stats_stack[block32].rate != INT_MAX) {
4342 *rd_stats = rd_stats_stack[block32];
4343 p->eobs[block] = !rd_stats->skip;
4344 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
4345 } else {
4346 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004347 plane_bsize, pta, ptl, rd_stats);
Jingning Han63cbf342016-11-09 15:37:48 -08004348 if (tx_size == TX_32X32) {
4349 rd_stats_stack[block32] = *rd_stats;
4350 }
4351 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004352
Urvang Joshi70006e42017-06-14 16:08:55 -07004353 if ((RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist) >=
4354 RDCOST(x->rdmult, zero_blk_rate, rd_stats->sse) ||
Angie Chiangb5dda482016-11-02 16:19:58 -07004355 rd_stats->skip == 1) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004356 !xd->lossless[mbmi->segment_id]) {
Jingning Hanc7ea7612017-01-11 15:01:30 -08004357#if CONFIG_RD_DEBUG
4358 av1_update_txb_coeff_cost(rd_stats, plane, tx_size, blk_row, blk_col,
4359 zero_blk_rate - rd_stats->rate);
Fergus Simpson4063a682017-02-28 16:52:22 -08004360#endif // CONFIG_RD_DEBUG
Angie Chiangb5dda482016-11-02 16:19:58 -07004361 rd_stats->rate = zero_blk_rate;
4362 rd_stats->dist = rd_stats->sse;
4363 rd_stats->skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364 x->blk_skip[plane][blk_row * bw + blk_col] = 1;
4365 p->eobs[block] = 0;
4366 } else {
4367 x->blk_skip[plane][blk_row * bw + blk_col] = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004368 rd_stats->skip = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004369 }
4370
Jingning Han571189c2016-10-24 10:38:43 -07004371 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
Angie Chiangb5dda482016-11-02 16:19:58 -07004372 rd_stats->rate +=
4373 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
Urvang Joshi70006e42017-06-14 16:08:55 -07004374 this_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004375 tmp_eob = p->eobs[block];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004376#if CONFIG_TXK_SEL
4377 best_tx_type = mbmi->txk_type[txk_idx];
4378#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 }
4380
Jingning Han571189c2016-10-24 10:38:43 -07004381 if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH) {
Jingning Han18482fe2016-11-02 17:01:58 -07004382 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4383 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004384 int sub_step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Angie Chiangb5dda482016-11-02 16:19:58 -07004385 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004386 int this_cost_valid = 1;
4387 int64_t tmp_rd = 0;
Yushin Cho04749122017-05-25 14:19:07 -07004388#if CONFIG_DAALA_DIST
4389 int sub8x8_eob[4];
4390#endif
Angie Chiangd7246172016-11-03 11:49:15 -07004391 sum_rd_stats.rate =
4392 av1_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
Jingning Hand3fada82016-11-22 10:46:55 -08004393
4394 assert(tx_size < TX_SIZES_ALL);
4395
Yaowu Xuc27fc142016-08-22 16:08:15 -07004396 for (i = 0; i < 4 && this_cost_valid; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004397 int offsetr = blk_row + (i >> 1) * bsl;
4398 int offsetc = blk_col + (i & 0x01) * bsl;
4399
4400 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4401
Jingning Han63cbf342016-11-09 15:37:48 -08004402 select_tx_block(cpi, x, offsetr, offsetc, plane, block, block32, sub_txs,
Jingning Han98d6a1f2016-11-03 12:47:47 -07004403 depth + 1, plane_bsize, ta, tl, tx_above, tx_left,
Jingning Han63cbf342016-11-09 15:37:48 -08004404 &this_rd_stats, ref_best_rd - tmp_rd, &this_cost_valid,
4405 rd_stats_stack);
Yushin Cho04749122017-05-25 14:19:07 -07004406#if CONFIG_DAALA_DIST
4407 if (plane == 0 && tx_size == TX_8X8) {
4408 sub8x8_eob[i] = p->eobs[block];
4409 }
4410#endif // CONFIG_DAALA_DIST
Angie Chiangc0feea82016-11-03 15:36:18 -07004411 av1_merge_rd_stats(&sum_rd_stats, &this_rd_stats);
Jingning Han98d6a1f2016-11-03 12:47:47 -07004412
Urvang Joshi70006e42017-06-14 16:08:55 -07004413 tmp_rd = RDCOST(x->rdmult, sum_rd_stats.rate, sum_rd_stats.dist);
Yushin Cho04749122017-05-25 14:19:07 -07004414#if !CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07004415 if (this_rd < tmp_rd) break;
Yushin Cho04749122017-05-25 14:19:07 -07004416#endif
Jingning Han98d6a1f2016-11-03 12:47:47 -07004417 block += sub_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004418 }
Yushin Cho04749122017-05-25 14:19:07 -07004419#if CONFIG_DAALA_DIST
4420 if (this_cost_valid && plane == 0 && tx_size == TX_8X8) {
4421 const int src_stride = p->src.stride;
4422 const int dst_stride = pd->dst.stride;
4423
4424 const uint8_t *src =
4425 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
4426 const uint8_t *dst =
4427 &pd->dst
4428 .buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
4429
4430 int64_t daala_dist;
4431 int qindex = x->qindex;
4432 const int pred_stride = block_size_wide[plane_bsize];
4433 const int pred_idx = (blk_row * pred_stride + blk_col)
4434 << tx_size_wide_log2[0];
4435 int16_t *pred = &pd->pred[pred_idx];
4436 int j;
4437 int qm = OD_HVS_QM;
4438 int use_activity_masking = 0;
4439 int row, col;
4440
Yushin Cho8ab875d2017-06-23 14:47:21 -07004441#if CONFIG_HIGHBITDEPTH
4442 uint8_t *pred8;
4443 DECLARE_ALIGNED(16, uint16_t, pred8_16[8 * 8]);
4444#else
Yushin Cho04749122017-05-25 14:19:07 -07004445 DECLARE_ALIGNED(16, uint8_t, pred8[8 * 8]);
Yushin Cho8ab875d2017-06-23 14:47:21 -07004446#endif // CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004447
4448#if CONFIG_PVQ
4449 use_activity_masking = x->daala_enc.use_activity_masking;
4450#endif
Yushin Cho8ab875d2017-06-23 14:47:21 -07004451 daala_dist = av1_daala_dist(xd, src, src_stride, dst, dst_stride, 8, 8, 8,
4452 8, qm, use_activity_masking, qindex) *
Yushin Cho04749122017-05-25 14:19:07 -07004453 16;
4454 sum_rd_stats.sse = daala_dist;
4455
Yushin Cho8ab875d2017-06-23 14:47:21 -07004456#if CONFIG_HIGHBITDEPTH
4457 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
4458 pred8 = CONVERT_TO_BYTEPTR(pred8_16);
4459 else
4460 pred8 = (uint8_t *)pred8_16;
4461#endif
Yushin Cho04749122017-05-25 14:19:07 -07004462
Yushin Cho8ab875d2017-06-23 14:47:21 -07004463#if CONFIG_HIGHBITDEPTH
4464 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
4465 for (row = 0; row < 2; ++row) {
4466 for (col = 0; col < 2; ++col) {
4467 int idx = row * 2 + col;
4468 int eob = sub8x8_eob[idx];
4469
4470 if (eob > 0) {
4471 for (j = 0; j < 4; j++)
4472 for (i = 0; i < 4; i++)
4473 CONVERT_TO_SHORTPTR(pred8)
4474 [(row * 4 + j) * 8 + 4 * col + i] =
4475 pred[(row * 4 + j) * pred_stride + 4 * col + i];
4476 } else {
4477 for (j = 0; j < 4; j++)
4478 for (i = 0; i < 4; i++)
4479 CONVERT_TO_SHORTPTR(pred8)
4480 [(row * 4 + j) * 8 + 4 * col + i] = CONVERT_TO_SHORTPTR(
4481 dst)[(row * 4 + j) * dst_stride + 4 * col + i];
4482 }
Yushin Cho04749122017-05-25 14:19:07 -07004483 }
4484 }
Yushin Cho8ab875d2017-06-23 14:47:21 -07004485 } else {
4486#endif
4487 for (row = 0; row < 2; ++row) {
4488 for (col = 0; col < 2; ++col) {
4489 int idx = row * 2 + col;
4490 int eob = sub8x8_eob[idx];
4491
4492 if (eob > 0) {
4493 for (j = 0; j < 4; j++)
4494 for (i = 0; i < 4; i++)
4495 pred8[(row * 4 + j) * 8 + 4 * col + i] =
4496 pred[(row * 4 + j) * pred_stride + 4 * col + i];
4497 } else {
4498 for (j = 0; j < 4; j++)
4499 for (i = 0; i < 4; i++)
4500 pred8[(row * 4 + j) * 8 + 4 * col + i] =
4501 dst[(row * 4 + j) * dst_stride + 4 * col + i];
4502 }
4503 }
4504 }
4505#if CONFIG_HIGHBITDEPTH
Yushin Cho04749122017-05-25 14:19:07 -07004506 }
Yushin Cho8ab875d2017-06-23 14:47:21 -07004507#endif // CONFIG_HIGHBITDEPTH
4508 daala_dist = av1_daala_dist(xd, src, src_stride, pred8, 8, 8, 8, 8, 8, qm,
Yushin Cho04749122017-05-25 14:19:07 -07004509 use_activity_masking, qindex) *
4510 16;
4511 sum_rd_stats.dist = daala_dist;
4512 tmp_rd = RDCOST(x->rdmult, sum_rd_stats.rate, sum_rd_stats.dist);
4513 }
4514#endif // CONFIG_DAALA_DIST
Yaowu Xuc27fc142016-08-22 16:08:15 -07004515 if (this_cost_valid) sum_rd = tmp_rd;
4516 }
4517
4518 if (this_rd < sum_rd) {
4519 int idx, idy;
Jingning Han58224042016-10-27 16:35:32 -07004520 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
4521 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
Jingning Han331662e2017-05-30 17:03:32 -07004522 txfm_partition_update(tx_above + blk_col, tx_left + blk_row, tx_size,
4523 tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004524 inter_tx_size[0][0] = tx_size;
Jingning Han58224042016-10-27 16:35:32 -07004525 for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
4526 for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004527 inter_tx_size[idy][idx] = tx_size;
4528 mbmi->tx_size = tx_size;
Jingning Hane3b81bc2017-06-23 11:43:52 -07004529#if CONFIG_TXK_SEL
4530 mbmi->txk_type[txk_idx] = best_tx_type;
4531#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004532 if (this_rd == INT64_MAX) *is_cost_valid = 0;
Angie Chiangb5dda482016-11-02 16:19:58 -07004533 x->blk_skip[plane][blk_row * bw + blk_col] = rd_stats->skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004534 } else {
Angie Chiangd7246172016-11-03 11:49:15 -07004535 *rd_stats = sum_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004536 if (sum_rd == INT64_MAX) *is_cost_valid = 0;
4537 }
4538}
4539
Angie Chiangb5dda482016-11-02 16:19:58 -07004540static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4541 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004542 int64_t ref_best_rd, RD_STATS *rd_stats_stack) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004543 MACROBLOCKD *const xd = &x->e_mbd;
4544 int is_cost_valid = 1;
4545 int64_t this_rd = 0;
4546
4547 if (ref_best_rd < 0) is_cost_valid = 0;
4548
Angie Chiangc0feea82016-11-03 15:36:18 -07004549 av1_init_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004550
4551 if (is_cost_valid) {
4552 const struct macroblockd_plane *const pd = &xd->plane[0];
4553 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004554 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4555 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004556 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004557 const int bh = tx_size_high_unit[max_tx_size];
4558 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004559 int idx, idy;
4560 int block = 0;
Jingning Han63cbf342016-11-09 15:37:48 -08004561 int block32 = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004562 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004563 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
4564 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
Jingning Han331662e2017-05-30 17:03:32 -07004565 TXFM_CONTEXT tx_above[MAX_MIB_SIZE * 2];
4566 TXFM_CONTEXT tx_left[MAX_MIB_SIZE * 2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004567
Angie Chiangb5dda482016-11-02 16:19:58 -07004568 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004569 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004570
Jingning Han9ca05b72017-01-03 14:41:36 -08004571 av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
Jingning Han331662e2017-05-30 17:03:32 -07004572 memcpy(tx_above, xd->above_txfm_context, sizeof(TXFM_CONTEXT) * mi_width);
4573 memcpy(tx_left, xd->left_txfm_context, sizeof(TXFM_CONTEXT) * mi_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004574
4575 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004576 for (idx = 0; idx < mi_width; idx += bw) {
Jingning Han63cbf342016-11-09 15:37:48 -08004577 select_tx_block(cpi, x, idy, idx, 0, block, block32, max_tx_size,
Jingning Han18482fe2016-11-02 17:01:58 -07004578 mi_height != mi_width, plane_bsize, ctxa, ctxl,
Angie Chiangb5dda482016-11-02 16:19:58 -07004579 tx_above, tx_left, &pn_rd_stats, ref_best_rd - this_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004580 &is_cost_valid, rd_stats_stack);
Angie Chiangc0feea82016-11-03 15:36:18 -07004581 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Urvang Joshi70006e42017-06-14 16:08:55 -07004582 this_rd += AOMMIN(RDCOST(x->rdmult, pn_rd_stats.rate, pn_rd_stats.dist),
4583 RDCOST(x->rdmult, 0, pn_rd_stats.sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004584 block += step;
Jingning Han63cbf342016-11-09 15:37:48 -08004585 ++block32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004586 }
4587 }
4588 }
4589
Urvang Joshi70006e42017-06-14 16:08:55 -07004590 this_rd = AOMMIN(RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist),
4591 RDCOST(x->rdmult, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004592 if (this_rd > ref_best_rd) is_cost_valid = 0;
4593
4594 if (!is_cost_valid) {
4595 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004596 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004597 }
4598}
4599
Yaowu Xuf883b422016-08-30 14:01:10 -07004600static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiangb5dda482016-11-02 16:19:58 -07004601 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Jingning Han63cbf342016-11-09 15:37:48 -08004602 int64_t ref_best_rd, TX_TYPE tx_type,
4603 RD_STATS *rd_stats_stack) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004604 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004605 MACROBLOCKD *const xd = &x->e_mbd;
4606 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004607 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004608 aom_prob skip_prob = av1_get_skip_prob(cm, xd);
4609 int s0 = av1_cost_bit(skip_prob, 0);
4610 int s1 = av1_cost_bit(skip_prob, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004611 int64_t rd;
Jingning Hane67b38a2016-11-04 10:30:00 -07004612 int row, col;
4613 const int max_blocks_high = max_block_high(xd, bsize, 0);
4614 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004615
4616 mbmi->tx_type = tx_type;
Jingning Han63cbf342016-11-09 15:37:48 -08004617 inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
Jingning Han70bd76e2017-05-30 10:53:00 -07004618 mbmi->min_tx_size = get_min_tx_size(mbmi->inter_tx_size[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004619
Angie Chiangb5dda482016-11-02 16:19:58 -07004620 if (rd_stats->rate == INT_MAX) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004621
Jingning Hane67b38a2016-11-04 10:30:00 -07004622 for (row = 0; row < max_blocks_high / 2; ++row)
4623 for (col = 0; col < max_blocks_wide / 2; ++col)
4624 mbmi->min_tx_size = AOMMIN(
4625 mbmi->min_tx_size, get_min_tx_size(mbmi->inter_tx_size[row][col]));
4626
Yaowu Xuc27fc142016-08-22 16:08:15 -07004627#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004628 if (get_ext_tx_types(mbmi->min_tx_size, bsize, is_inter,
4629 cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630 !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08004631 const int ext_tx_set = get_ext_tx_set(mbmi->min_tx_size, bsize, is_inter,
4632 cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004633 if (is_inter) {
4634 if (ext_tx_set > 0)
Angie Chiangb5dda482016-11-02 16:19:58 -07004635 rd_stats->rate +=
Jingning Hane67b38a2016-11-04 10:30:00 -07004636 cpi->inter_tx_type_costs[ext_tx_set]
4637 [txsize_sqr_map[mbmi->min_tx_size]]
Peter de Rivazb85a5a72016-10-18 11:47:56 +01004638 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004639 } else {
4640 if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
Jingning Hane67b38a2016-11-04 10:30:00 -07004641 rd_stats->rate +=
4642 cpi->intra_tx_type_costs[ext_tx_set][mbmi->min_tx_size][mbmi->mode]
4643 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644 }
4645 }
Jingning Han243b66b2017-06-23 12:11:47 -07004646#else // CONFIG_EXT_TX
4647#if !CONFIG_TXK_SEL
Jingning Hane67b38a2016-11-04 10:30:00 -07004648 if (mbmi->min_tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id])
4649 rd_stats->rate +=
4650 cpi->inter_tx_type_costs[mbmi->min_tx_size][mbmi->tx_type];
Jingning Han243b66b2017-06-23 12:11:47 -07004651#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004652#endif // CONFIG_EXT_TX
4653
Angie Chiangb5dda482016-11-02 16:19:58 -07004654 if (rd_stats->skip)
Urvang Joshi70006e42017-06-14 16:08:55 -07004655 rd = RDCOST(x->rdmult, s1, rd_stats->sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004656 else
Urvang Joshi70006e42017-06-14 16:08:55 -07004657 rd = RDCOST(x->rdmult, rd_stats->rate + s0, rd_stats->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004658
Angie Chiangb5dda482016-11-02 16:19:58 -07004659 if (is_inter && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
4660 !(rd_stats->skip))
Urvang Joshi70006e42017-06-14 16:08:55 -07004661 rd = AOMMIN(rd, RDCOST(x->rdmult, s1, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004662
4663 return rd;
4664}
4665
Angie Chiangb5dda482016-11-02 16:19:58 -07004666static void select_tx_type_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
4667 RD_STATS *rd_stats, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004668 int64_t ref_best_rd) {
Jingning Han2b0eeb12017-02-23 15:55:37 -08004669 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004670 const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
4671 MACROBLOCKD *const xd = &x->e_mbd;
4672 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4673 int64_t rd = INT64_MAX;
4674 int64_t best_rd = INT64_MAX;
4675 TX_TYPE tx_type, best_tx_type = DCT_DCT;
4676 const int is_inter = is_inter_block(mbmi);
4677 TX_SIZE best_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07004678 TX_SIZE best_tx = max_txsize_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07004679 TX_SIZE best_min_tx_size = TX_SIZES_ALL;
Jingning Han9ca05b72017-01-03 14:41:36 -08004680 uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
Jingning Hane3b81bc2017-06-23 11:43:52 -07004681 TX_TYPE txk_start = DCT_DCT;
4682#if CONFIG_TXK_SEL
4683 TX_TYPE txk_end = DCT_DCT + 1;
4684#else
4685 TX_TYPE txk_end = TX_TYPES;
4686#endif
Angie Chiangf1cb0752017-04-10 16:01:20 -07004687 const int n4 = bsize_to_num_blk(bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004688 int idx, idy;
4689 int prune = 0;
Jingning Han2b0eeb12017-02-23 15:55:37 -08004690 const int count32 =
4691 1 << (2 * (cm->mib_size_log2 - mi_width_log2_lookup[BLOCK_32X32]));
Jingning Han89d648b2016-11-22 11:22:08 -08004692#if CONFIG_EXT_PARTITION
4693 RD_STATS rd_stats_stack[16];
4694#else
Jingning Han63cbf342016-11-09 15:37:48 -08004695 RD_STATS rd_stats_stack[4];
Fergus Simpson4063a682017-02-28 16:52:22 -08004696#endif // CONFIG_EXT_PARTITION
Yaowu Xuc27fc142016-08-22 16:08:15 -07004697#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08004698 const int ext_tx_set =
4699 get_ext_tx_set(max_tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004700#endif // CONFIG_EXT_TX
4701
4702 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE)
4703#if CONFIG_EXT_TX
4704 prune = prune_tx_types(cpi, bsize, x, xd, ext_tx_set);
4705#else
4706 prune = prune_tx_types(cpi, bsize, x, xd, 0);
Fergus Simpson4063a682017-02-28 16:52:22 -08004707#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004708
Angie Chiangc0feea82016-11-03 15:36:18 -07004709 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710
Jingning Han89d648b2016-11-22 11:22:08 -08004711 for (idx = 0; idx < count32; ++idx)
4712 av1_invalid_rd_stats(&rd_stats_stack[idx]);
Jingning Han63cbf342016-11-09 15:37:48 -08004713
Jingning Hane3b81bc2017-06-23 11:43:52 -07004714 for (tx_type = txk_start; tx_type < txk_end; ++tx_type) {
Angie Chiangb5dda482016-11-02 16:19:58 -07004715 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004716 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004717#if CONFIG_EXT_TX
4718 if (is_inter) {
4719 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
4720 if (cpi->sf.tx_type_search.prune_mode > NO_PRUNE) {
4721 if (!do_tx_type_search(tx_type, prune)) continue;
4722 }
4723 } else {
4724 if (!ALLOW_INTRA_EXT_TX && bsize >= BLOCK_8X8) {
4725 if (tx_type != intra_mode_to_tx_type_context[mbmi->mode]) continue;
4726 }
4727 if (!ext_tx_used_intra[ext_tx_set][tx_type]) continue;
4728 }
4729#else // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07004730 if (is_inter && cpi->sf.tx_type_search.prune_mode > NO_PRUNE &&
4731 !do_tx_type_search(tx_type, prune))
4732 continue;
4733#endif // CONFIG_EXT_TX
4734 if (is_inter && x->use_default_inter_tx_type &&
4735 tx_type != get_default_tx_type(0, xd, 0, max_tx_size))
4736 continue;
4737
Jingning Hane67b38a2016-11-04 10:30:00 -07004738 if (xd->lossless[mbmi->segment_id])
4739 if (tx_type != DCT_DCT) continue;
4740
Angie Chiangb5dda482016-11-02 16:19:58 -07004741 rd = select_tx_size_fix_type(cpi, x, &this_rd_stats, bsize, ref_best_rd,
Jingning Han63cbf342016-11-09 15:37:48 -08004742 tx_type, rd_stats_stack);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004743
4744 if (rd < best_rd) {
4745 best_rd = rd;
Angie Chiangb5dda482016-11-02 16:19:58 -07004746 *rd_stats = this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004747 best_tx_type = mbmi->tx_type;
4748 best_tx = mbmi->tx_size;
Jingning Hane67b38a2016-11-04 10:30:00 -07004749 best_min_tx_size = mbmi->min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004750 memcpy(best_blk_skip, x->blk_skip[0], sizeof(best_blk_skip[0]) * n4);
4751 for (idy = 0; idy < xd->n8_h; ++idy)
4752 for (idx = 0; idx < xd->n8_w; ++idx)
4753 best_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
4754 }
4755 }
4756
4757 mbmi->tx_type = best_tx_type;
4758 for (idy = 0; idy < xd->n8_h; ++idy)
4759 for (idx = 0; idx < xd->n8_w; ++idx)
4760 mbmi->inter_tx_size[idy][idx] = best_tx_size[idy][idx];
4761 mbmi->tx_size = best_tx;
Jingning Hane67b38a2016-11-04 10:30:00 -07004762 mbmi->min_tx_size = best_min_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004763 memcpy(x->blk_skip[0], best_blk_skip, sizeof(best_blk_skip[0]) * n4);
4764}
4765
Yaowu Xuf883b422016-08-30 14:01:10 -07004766static void tx_block_rd(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004767 int blk_col, int plane, int block, TX_SIZE tx_size,
4768 BLOCK_SIZE plane_bsize, ENTROPY_CONTEXT *above_ctx,
Angie Chiangb5dda482016-11-02 16:19:58 -07004769 ENTROPY_CONTEXT *left_ctx, RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004770 MACROBLOCKD *const xd = &x->e_mbd;
4771 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4772 struct macroblock_plane *const p = &x->plane[plane];
4773 struct macroblockd_plane *const pd = &xd->plane[plane];
4774 BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
4775 const int tx_row = blk_row >> (1 - pd->subsampling_y);
4776 const int tx_col = blk_col >> (1 - pd->subsampling_x);
4777 TX_SIZE plane_tx_size;
Jingning Han18482fe2016-11-02 17:01:58 -07004778 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
4779 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004780
Jingning Hand3fada82016-11-22 10:46:55 -08004781 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004782
Yaowu Xuc27fc142016-08-22 16:08:15 -07004783 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
4784
Debargha Mukherjee2f123402016-08-30 17:43:38 -07004785 plane_tx_size =
4786 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
4787 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788
4789 if (tx_size == plane_tx_size) {
Angie Chiang77368af2017-03-23 16:22:07 -07004790 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004791 ENTROPY_CONTEXT *ta = above_ctx + blk_col;
4792 ENTROPY_CONTEXT *tl = left_ctx + blk_row;
Yaowu Xuf883b422016-08-30 14:01:10 -07004793 av1_tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
Angie Chiang77368af2017-03-23 16:22:07 -07004794 plane_bsize, ta, tl, rd_stats);
Jingning Han607fa6a2016-10-26 10:46:28 -07004795
Jingning Han58224042016-10-27 16:35:32 -07004796 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004797 ta[i] = !(p->eobs[block] == 0);
Jingning Han58224042016-10-27 16:35:32 -07004798 for (i = 0; i < tx_size_high_unit[tx_size]; ++i)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004799 tl[i] = !(p->eobs[block] == 0);
4800 } else {
Jingning Han18482fe2016-11-02 17:01:58 -07004801 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
4802 const int bsl = tx_size_wide_unit[sub_txs];
Jingning Han58224042016-10-27 16:35:32 -07004803 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004804 int i;
4805
4806 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004807
4808 for (i = 0; i < 4; ++i) {
Jingning Han98d6a1f2016-11-03 12:47:47 -07004809 int offsetr = blk_row + (i >> 1) * bsl;
4810 int offsetc = blk_col + (i & 0x01) * bsl;
4811
4812 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
4813
4814 tx_block_rd(cpi, x, offsetr, offsetc, plane, block, sub_txs, plane_bsize,
4815 above_ctx, left_ctx, rd_stats);
4816 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004817 }
4818 }
4819}
4820
4821// Return value 0: early termination triggered, no valid rd cost available;
4822// 1: rd cost values are valid.
Angie Chiangb5dda482016-11-02 16:19:58 -07004823static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
4824 RD_STATS *rd_stats, BLOCK_SIZE bsize,
4825 int64_t ref_best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004826 MACROBLOCKD *const xd = &x->e_mbd;
4827 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
4828 int plane;
4829 int is_cost_valid = 1;
4830 int64_t this_rd;
4831
4832 if (ref_best_rd < 0) is_cost_valid = 0;
4833
Angie Chiangc0feea82016-11-03 15:36:18 -07004834 av1_init_rd_stats(rd_stats);
Yue Chena1e48dc2016-08-29 17:29:33 -07004835
Jingning Han31b6a4f2017-02-23 11:05:53 -08004836#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004837 if (x->skip_chroma_rd) return is_cost_valid;
Jingning Han52d2b402017-05-19 09:31:17 -07004838 bsize = scale_chroma_bsize(mbmi->sb_type, xd->plane[1].subsampling_x,
4839 xd->plane[1].subsampling_y);
Fergus Simpson4063a682017-02-28 16:52:22 -08004840#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han9ce464c2017-02-20 15:36:30 -08004841
Yue Chena1e48dc2016-08-29 17:29:33 -07004842#if CONFIG_EXT_TX && CONFIG_RECT_TX
4843 if (is_rect_tx(mbmi->tx_size)) {
Angie Chiang284d7772016-11-08 11:06:45 -08004844 return super_block_uvrd(cpi, x, rd_stats, bsize, ref_best_rd);
Yue Chena1e48dc2016-08-29 17:29:33 -07004845 }
4846#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4847
Yaowu Xuc27fc142016-08-22 16:08:15 -07004848 if (is_inter_block(mbmi) && is_cost_valid) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004849 for (plane = 1; plane < MAX_MB_PLANE; ++plane)
Yaowu Xuf883b422016-08-30 14:01:10 -07004850 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004851 }
4852
Yaowu Xuc27fc142016-08-22 16:08:15 -07004853 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
4854 const struct macroblockd_plane *const pd = &xd->plane[plane];
4855 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han9ca05b72017-01-03 14:41:36 -08004856 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
4857 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08004858 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Han18482fe2016-11-02 17:01:58 -07004859 const int bh = tx_size_high_unit[max_tx_size];
4860 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004861 int idx, idy;
4862 int block = 0;
Jingning Han18482fe2016-11-02 17:01:58 -07004863 const int step = bh * bw;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004864 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
4865 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
Angie Chiangb5dda482016-11-02 16:19:58 -07004866 RD_STATS pn_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07004867 av1_init_rd_stats(&pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004868
Jingning Han9ca05b72017-01-03 14:41:36 -08004869 av1_get_entropy_contexts(bsize, 0, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004870
4871 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Han18482fe2016-11-02 17:01:58 -07004872 for (idx = 0; idx < mi_width; idx += bw) {
4873 tx_block_rd(cpi, x, idy, idx, plane, block, max_tx_size, plane_bsize,
Angie Chiangb5dda482016-11-02 16:19:58 -07004874 ta, tl, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004875 block += step;
4876 }
4877 }
4878
Angie Chiangb5dda482016-11-02 16:19:58 -07004879 if (pn_rd_stats.rate == INT_MAX) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004880 is_cost_valid = 0;
4881 break;
4882 }
4883
Angie Chiang628d7c92016-11-03 16:24:56 -07004884 av1_merge_rd_stats(rd_stats, &pn_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885
Urvang Joshi70006e42017-06-14 16:08:55 -07004886 this_rd = AOMMIN(RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist),
4887 RDCOST(x->rdmult, 0, rd_stats->sse));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004888
4889 if (this_rd > ref_best_rd) {
4890 is_cost_valid = 0;
4891 break;
4892 }
4893 }
4894
4895 if (!is_cost_valid) {
4896 // reset cost value
Angie Chiangc0feea82016-11-03 15:36:18 -07004897 av1_invalid_rd_stats(rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004898 }
4899
4900 return is_cost_valid;
4901}
4902#endif // CONFIG_VAR_TX
4903
Urvang Joshib100db72016-10-12 16:28:56 -07004904#if CONFIG_PALETTE
hui su83c26632017-01-24 17:19:06 -08004905static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
4906 int dc_mode_cost,
4907 uint8_t *best_palette_color_map,
4908 MB_MODE_INFO *const best_mbmi,
4909 int64_t *best_rd, int *rate,
4910 int *rate_tokenonly, int64_t *distortion,
4911 int *skippable) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004912 MACROBLOCKD *const xd = &x->e_mbd;
4913 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07004914 assert(!is_inter_block(mbmi));
hui sude0c70a2017-01-09 17:12:17 -08004915 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004916 const BLOCK_SIZE bsize = mbmi->sb_type;
Angie Chiang284d7772016-11-08 11:06:45 -08004917 int this_rate;
4918 int64_t this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004919 int colors_u, colors_v, colors;
4920 const int src_stride = x->plane[1].src.stride;
4921 const uint8_t *const src_u = x->plane[1].src.buf;
4922 const uint8_t *const src_v = x->plane[2].src.buf;
hui sude0c70a2017-01-09 17:12:17 -08004923 uint8_t *const color_map = xd->plane[1].color_index_map;
Angie Chiang284d7772016-11-08 11:06:45 -08004924 RD_STATS tokenonly_rd_stats;
Urvang Joshi56ba91b2017-01-10 13:22:09 -08004925 int plane_block_width, plane_block_height, rows, cols;
4926 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
4927 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004928 if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return;
4929
hui su83c26632017-01-24 17:19:06 -08004930 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07004931#if CONFIG_FILTER_INTRA
4932 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
4933#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07004934
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004935#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004936 if (cpi->common.use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004937 colors_u = av1_count_colors_highbd(src_u, src_stride, rows, cols,
4938 cpi->common.bit_depth);
4939 colors_v = av1_count_colors_highbd(src_v, src_stride, rows, cols,
4940 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004941 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004942#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004943 colors_u = av1_count_colors(src_u, src_stride, rows, cols);
4944 colors_v = av1_count_colors(src_v, src_stride, rows, cols);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004945#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004946 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004947#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004948
hui su33567b22017-04-30 16:40:19 -07004949#if CONFIG_PALETTE_DELTA_ENCODING
4950 const MODE_INFO *above_mi = xd->above_mi;
4951 const MODE_INFO *left_mi = xd->left_mi;
4952 uint16_t color_cache[2 * PALETTE_MAX_SIZE];
4953 const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
4954#endif // CONFIG_PALETTE_DELTA_ENCODING
4955
Yaowu Xuc27fc142016-08-22 16:08:15 -07004956 colors = colors_u > colors_v ? colors_u : colors_v;
4957 if (colors > 1 && colors <= 64) {
4958 int r, c, n, i, j;
4959 const int max_itr = 50;
Urvang Joshi967ff392016-09-07 14:57:49 -07004960 uint8_t color_order[PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961 float lb_u, ub_u, val_u;
4962 float lb_v, ub_v, val_v;
4963 float *const data = x->palette_buffer->kmeans_data_buf;
4964 float centroids[2 * PALETTE_MAX_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004965
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004966#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004967 uint16_t *src_u16 = CONVERT_TO_SHORTPTR(src_u);
4968 uint16_t *src_v16 = CONVERT_TO_SHORTPTR(src_v);
4969 if (cpi->common.use_highbitdepth) {
4970 lb_u = src_u16[0];
4971 ub_u = src_u16[0];
4972 lb_v = src_v16[0];
4973 ub_v = src_v16[0];
4974 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004975#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004976 lb_u = src_u[0];
4977 ub_u = src_u[0];
4978 lb_v = src_v[0];
4979 ub_v = src_v[0];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004980#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004981 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004982#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004983
Yaowu Xuc27fc142016-08-22 16:08:15 -07004984 for (r = 0; r < rows; ++r) {
4985 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004986#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004987 if (cpi->common.use_highbitdepth) {
4988 val_u = src_u16[r * src_stride + c];
4989 val_v = src_v16[r * src_stride + c];
4990 data[(r * cols + c) * 2] = val_u;
4991 data[(r * cols + c) * 2 + 1] = val_v;
4992 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004993#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004994 val_u = src_u[r * src_stride + c];
4995 val_v = src_v[r * src_stride + c];
4996 data[(r * cols + c) * 2] = val_u;
4997 data[(r * cols + c) * 2 + 1] = val_v;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004998#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004999 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005000#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005001 if (val_u < lb_u)
5002 lb_u = val_u;
5003 else if (val_u > ub_u)
5004 ub_u = val_u;
5005 if (val_v < lb_v)
5006 lb_v = val_v;
5007 else if (val_v > ub_v)
5008 ub_v = val_v;
5009 }
5010 }
5011
5012 for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
5013 --n) {
5014 for (i = 0; i < n; ++i) {
5015 centroids[i * 2] = lb_u + (2 * i + 1) * (ub_u - lb_u) / n / 2;
5016 centroids[i * 2 + 1] = lb_v + (2 * i + 1) * (ub_v - lb_v) / n / 2;
5017 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005018 av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
hui sud13c24a2017-04-07 16:13:07 -07005019#if CONFIG_PALETTE_DELTA_ENCODING
hui su33567b22017-04-30 16:40:19 -07005020 optimize_palette_colors(color_cache, n_cache, n, 2, centroids);
hui sud13c24a2017-04-07 16:13:07 -07005021 // Sort the U channel colors in ascending order.
5022 for (i = 0; i < 2 * (n - 1); i += 2) {
5023 int min_idx = i;
5024 float min_val = centroids[i];
5025 for (j = i + 2; j < 2 * n; j += 2)
5026 if (centroids[j] < min_val) min_val = centroids[j], min_idx = j;
5027 if (min_idx != i) {
5028 float temp_u = centroids[i], temp_v = centroids[i + 1];
5029 centroids[i] = centroids[min_idx];
5030 centroids[i + 1] = centroids[min_idx + 1];
5031 centroids[min_idx] = temp_u, centroids[min_idx + 1] = temp_v;
5032 }
5033 }
5034 av1_calc_indices(data, centroids, color_map, rows * cols, n, 2);
5035#endif // CONFIG_PALETTE_DELTA_ENCODING
Urvang Joshi56ba91b2017-01-10 13:22:09 -08005036 extend_palette_color_map(color_map, cols, rows, plane_block_width,
5037 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005038 pmi->palette_size[1] = n;
5039 for (i = 1; i < 3; ++i) {
5040 for (j = 0; j < n; ++j) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005041#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005042 if (cpi->common.use_highbitdepth)
5043 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] = clip_pixel_highbd(
5044 (int)centroids[j * 2 + i - 1], cpi->common.bit_depth);
5045 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005046#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005047 pmi->palette_colors[i * PALETTE_MAX_SIZE + j] =
5048 clip_pixel((int)centroids[j * 2 + i - 1]);
5049 }
5050 }
5051
Angie Chiang284d7772016-11-08 11:06:45 -08005052 super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd);
5053 if (tokenonly_rd_stats.rate == INT_MAX) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005054 this_rate =
Angie Chiang284d7772016-11-08 11:06:45 -08005055 tokenonly_rd_stats.rate + dc_mode_cost +
Alex Converse92109812017-02-22 10:21:40 -08005056 cpi->palette_uv_size_cost[bsize - BLOCK_8X8][n - PALETTE_MIN_SIZE] +
Yaowu Xuc27fc142016-08-22 16:08:15 -07005057 write_uniform_cost(n, color_map[0]) +
Yaowu Xuf883b422016-08-30 14:01:10 -07005058 av1_cost_bit(
5059 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
hui su33567b22017-04-30 16:40:19 -07005060 this_rate += av1_palette_color_cost_uv(pmi,
5061#if CONFIG_PALETTE_DELTA_ENCODING
5062 color_cache, n_cache,
5063#endif // CONFIG_PALETTE_DELTA_ENCODING
5064 cpi->common.bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005065 for (i = 0; i < rows; ++i) {
5066 for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
Urvang Joshi967ff392016-09-07 14:57:49 -07005067 int color_idx;
Urvang Joshi23a61112017-01-30 14:59:27 -08005068 const int color_ctx = av1_get_palette_color_index_context(
Urvang Joshi199a2f42017-01-23 15:02:07 -08005069 color_map, plane_block_width, i, j, n, color_order, &color_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070 assert(color_idx >= 0 && color_idx < n);
Alex Converse92109812017-02-22 10:21:40 -08005071 this_rate += cpi->palette_uv_color_cost[n - PALETTE_MIN_SIZE]
5072 [color_ctx][color_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005073 }
5074 }
5075
Urvang Joshi70006e42017-06-14 16:08:55 -07005076 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005077 if (this_rd < *best_rd) {
5078 *best_rd = this_rd;
hui su83c26632017-01-24 17:19:06 -08005079 *best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005080 memcpy(best_palette_color_map, color_map,
Urvang Joshi56ba91b2017-01-10 13:22:09 -08005081 plane_block_width * plane_block_height *
5082 sizeof(best_palette_color_map[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005083 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005084 *distortion = tokenonly_rd_stats.dist;
5085 *rate_tokenonly = tokenonly_rd_stats.rate;
5086 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005087 }
5088 }
5089 }
hui su83c26632017-01-24 17:19:06 -08005090 if (best_mbmi->palette_mode_info.palette_size[1] > 0) {
hui sude0c70a2017-01-09 17:12:17 -08005091 memcpy(color_map, best_palette_color_map,
5092 rows * cols * sizeof(best_palette_color_map[0]));
5093 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005094}
Urvang Joshib100db72016-10-12 16:28:56 -07005095#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005096
hui su5db97432016-10-14 16:10:14 -07005097#if CONFIG_FILTER_INTRA
5098// Return 1 if an filter intra mode is selected; return 0 otherwise.
5099static int rd_pick_filter_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
5100 int *rate, int *rate_tokenonly,
5101 int64_t *distortion, int *skippable,
5102 BLOCK_SIZE bsize, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005103 MACROBLOCKD *const xd = &x->e_mbd;
5104 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
hui su5db97432016-10-14 16:10:14 -07005105 int filter_intra_selected_flag = 0;
Angie Chiang284d7772016-11-08 11:06:45 -08005106 int this_rate;
5107 int64_t this_rd;
hui su5db97432016-10-14 16:10:14 -07005108 FILTER_INTRA_MODE mode;
5109 FILTER_INTRA_MODE_INFO filter_intra_mode_info;
Angie Chiang284d7772016-11-08 11:06:45 -08005110 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111
hui su5db97432016-10-14 16:10:14 -07005112 av1_zero(filter_intra_mode_info);
5113 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005114 mbmi->uv_mode = DC_PRED;
Urvang Joshib100db72016-10-12 16:28:56 -07005115#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005116 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -07005117#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005118
5119 for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
hui su5db97432016-10-14 16:10:14 -07005120 mbmi->filter_intra_mode_info.filter_intra_mode[1] = mode;
Angie Chiang284d7772016-11-08 11:06:45 -08005121 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, *best_rd))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005122 continue;
5123
Angie Chiang284d7772016-11-08 11:06:45 -08005124 this_rate = tokenonly_rd_stats.rate +
hui su5db97432016-10-14 16:10:14 -07005125 av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 1) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
5127 write_uniform_cost(FILTER_INTRA_MODES, mode);
Urvang Joshi70006e42017-06-14 16:08:55 -07005128 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005129 if (this_rd < *best_rd) {
5130 *best_rd = this_rd;
5131 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005132 *rate_tokenonly = tokenonly_rd_stats.rate;
5133 *distortion = tokenonly_rd_stats.dist;
5134 *skippable = tokenonly_rd_stats.skip;
hui su5db97432016-10-14 16:10:14 -07005135 filter_intra_mode_info = mbmi->filter_intra_mode_info;
5136 filter_intra_selected_flag = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137 }
5138 }
5139
hui su5db97432016-10-14 16:10:14 -07005140 if (filter_intra_selected_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005141 mbmi->uv_mode = DC_PRED;
hui su5db97432016-10-14 16:10:14 -07005142 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
5143 filter_intra_mode_info.use_filter_intra_mode[1];
5144 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
5145 filter_intra_mode_info.filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 return 1;
5147 } else {
5148 return 0;
5149 }
5150}
hui su5db97432016-10-14 16:10:14 -07005151#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005152
hui su5db97432016-10-14 16:10:14 -07005153#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -08005154// Run RD calculation with given chroma intra prediction angle., and return
5155// the RD cost. Update the best mode info. if the RD cost is the best so far.
5156static int64_t pick_intra_angle_routine_sbuv(
5157 const AV1_COMP *const cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
5158 int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
5159 int *best_angle_delta, int64_t *best_rd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005160 MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005161 assert(!is_inter_block(mbmi));
Angie Chiang284d7772016-11-08 11:06:45 -08005162 int this_rate;
5163 int64_t this_rd;
5164 RD_STATS tokenonly_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005165
hui su45dc5972016-12-08 17:42:50 -08005166 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd_in))
5167 return INT64_MAX;
Angie Chiang284d7772016-11-08 11:06:45 -08005168 this_rate = tokenonly_rd_stats.rate + rate_overhead;
Urvang Joshi70006e42017-06-14 16:08:55 -07005169 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005170 if (this_rd < *best_rd) {
5171 *best_rd = this_rd;
5172 *best_angle_delta = mbmi->angle_delta[1];
5173 *rate = this_rate;
hui su45dc5972016-12-08 17:42:50 -08005174 rd_stats->rate = tokenonly_rd_stats.rate;
5175 rd_stats->dist = tokenonly_rd_stats.dist;
5176 rd_stats->skip = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005177 }
hui su45dc5972016-12-08 17:42:50 -08005178 return this_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005179}
5180
hui su45dc5972016-12-08 17:42:50 -08005181// With given chroma directional intra prediction mode, pick the best angle
5182// delta. Return true if a RD cost that is smaller than the input one is found.
Urvang Joshi52648442016-10-13 17:27:51 -07005183static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
Urvang Joshi52648442016-10-13 17:27:51 -07005184 BLOCK_SIZE bsize, int rate_overhead,
hui su45dc5972016-12-08 17:42:50 -08005185 int64_t best_rd, int *rate,
5186 RD_STATS *rd_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187 MACROBLOCKD *const xd = &x->e_mbd;
5188 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005189 assert(!is_inter_block(mbmi));
hui su45dc5972016-12-08 17:42:50 -08005190 int i, angle_delta, best_angle_delta = 0;
hui su0a6731f2017-04-26 15:23:47 -07005191 int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005192
hui su45dc5972016-12-08 17:42:50 -08005193 rd_stats->rate = INT_MAX;
5194 rd_stats->skip = 0;
5195 rd_stats->dist = INT64_MAX;
hui su0a6731f2017-04-26 15:23:47 -07005196 for (i = 0; i < 2 * (MAX_ANGLE_DELTA + 2); ++i) rd_cost[i] = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005197
hui su0a6731f2017-04-26 15:23:47 -07005198 for (angle_delta = 0; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08005199 for (i = 0; i < 2; ++i) {
5200 best_rd_in = (best_rd == INT64_MAX)
5201 ? INT64_MAX
5202 : (best_rd + (best_rd >> ((angle_delta == 0) ? 3 : 5)));
5203 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
5204 this_rd = pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead,
5205 best_rd_in, rate, rd_stats,
5206 &best_angle_delta, &best_rd);
5207 rd_cost[2 * angle_delta + i] = this_rd;
5208 if (angle_delta == 0) {
5209 if (this_rd == INT64_MAX) return 0;
5210 rd_cost[1] = this_rd;
5211 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212 }
5213 }
hui su45dc5972016-12-08 17:42:50 -08005214 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215
hui su45dc5972016-12-08 17:42:50 -08005216 assert(best_rd != INT64_MAX);
hui su0a6731f2017-04-26 15:23:47 -07005217 for (angle_delta = 1; angle_delta <= MAX_ANGLE_DELTA; angle_delta += 2) {
hui su45dc5972016-12-08 17:42:50 -08005218 int64_t rd_thresh;
5219 for (i = 0; i < 2; ++i) {
5220 int skip_search = 0;
5221 rd_thresh = best_rd + (best_rd >> 5);
5222 if (rd_cost[2 * (angle_delta + 1) + i] > rd_thresh &&
5223 rd_cost[2 * (angle_delta - 1) + i] > rd_thresh)
5224 skip_search = 1;
5225 if (!skip_search) {
5226 mbmi->angle_delta[1] = (1 - 2 * i) * angle_delta;
Yue Chenb0f808b2017-04-26 11:55:14 -07005227 pick_intra_angle_routine_sbuv(cpi, x, bsize, rate_overhead, best_rd,
5228 rate, rd_stats, &best_angle_delta,
5229 &best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005230 }
5231 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232 }
5233
5234 mbmi->angle_delta[1] = best_angle_delta;
hui su45dc5972016-12-08 17:42:50 -08005235 return rd_stats->rate != INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236}
5237#endif // CONFIG_EXT_INTRA
5238
hui sueaddeee2017-05-30 12:19:38 -07005239static void init_sbuv_mode(MB_MODE_INFO *const mbmi) {
5240 mbmi->uv_mode = DC_PRED;
5241#if CONFIG_PALETTE
5242 mbmi->palette_mode_info.palette_size[1] = 0;
5243#endif // CONFIG_PALETTE
5244#if CONFIG_FILTER_INTRA
5245 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
5246#endif // CONFIG_FILTER_INTRA
5247}
5248
Urvang Joshi52648442016-10-13 17:27:51 -07005249static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
5250 int *rate, int *rate_tokenonly,
5251 int64_t *distortion, int *skippable,
5252 BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005253 MACROBLOCKD *xd = &x->e_mbd;
5254 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Urvang Joshi330aec82017-05-08 15:37:42 -07005255 assert(!is_inter_block(mbmi));
hui su83c26632017-01-24 17:19:06 -08005256 MB_MODE_INFO best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005257 PREDICTION_MODE mode;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005258 int64_t best_rd = INT64_MAX, this_rd;
Angie Chiang284d7772016-11-08 11:06:45 -08005259 int this_rate;
5260 RD_STATS tokenonly_rd_stats;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005261#if CONFIG_PVQ
5262 od_rollback_buffer buf;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005263 od_encode_checkpoint(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005264#endif // CONFIG_PVQ
Urvang Joshib100db72016-10-12 16:28:56 -07005265#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -08005266 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005267 uint8_t *best_palette_color_map = NULL;
Urvang Joshib100db72016-10-12 16:28:56 -07005268#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005269
Yaowu Xuc27fc142016-08-22 16:08:15 -07005270 for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
hui su83c26632017-01-24 17:19:06 -08005271#if CONFIG_EXT_INTRA
5272 const int is_directional_mode =
5273 av1_is_directional_mode(mode, mbmi->sb_type);
5274#endif // CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08005275 if (!(cpi->sf.intra_uv_mode_mask[txsize_sqr_up_map[max_tx_size]] &
5276 (1 << mode)))
5277 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005278
5279 mbmi->uv_mode = mode;
5280#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005281 mbmi->angle_delta[1] = 0;
Joe Young830d4ce2017-05-30 17:48:13 -07005282 if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
hui su0a6731f2017-04-26 15:23:47 -07005283 const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
5284 write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
hui su45dc5972016-12-08 17:42:50 -08005285 if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
5286 &this_rate, &tokenonly_rd_stats))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005287 continue;
5288 } else {
hui su83c26632017-01-24 17:19:06 -08005289#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08005290 if (!super_block_uvrd(cpi, x, &tokenonly_rd_stats, bsize, best_rd)) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07005291#if CONFIG_PVQ
5292 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005293#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07005294 continue;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005295 }
hui su83c26632017-01-24 17:19:06 -08005296#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297 }
hui su83c26632017-01-24 17:19:06 -08005298#endif // CONFIG_EXT_INTRA
Angie Chiang284d7772016-11-08 11:06:45 -08005299 this_rate =
5300 tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
hui su83c26632017-01-24 17:19:06 -08005301
5302#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07005303 if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
hui su0a6731f2017-04-26 15:23:47 -07005304 this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
5305 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
hui su45dc5972016-12-08 17:42:50 -08005306 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005307#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005308#if CONFIG_FILTER_INTRA
5309 if (mbmi->sb_type >= BLOCK_8X8 && mode == DC_PRED)
5310 this_rate += av1_cost_bit(cpi->common.fc->filter_intra_probs[1], 0);
5311#endif // CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005312#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005313 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8 &&
5314 mode == DC_PRED)
Yaowu Xuf883b422016-08-30 14:01:10 -07005315 this_rate += av1_cost_bit(
5316 av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07005317#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005318
Yushin Cho77bba8d2016-11-04 16:36:56 -07005319#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07005320 od_encode_rollback(&x->daala_enc, &buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08005321#endif // CONFIG_PVQ
Urvang Joshi70006e42017-06-14 16:08:55 -07005322 this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005323
5324 if (this_rd < best_rd) {
hui su83c26632017-01-24 17:19:06 -08005325 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005326 best_rd = this_rd;
5327 *rate = this_rate;
Angie Chiang284d7772016-11-08 11:06:45 -08005328 *rate_tokenonly = tokenonly_rd_stats.rate;
5329 *distortion = tokenonly_rd_stats.dist;
5330 *skippable = tokenonly_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005331 }
5332 }
5333
Urvang Joshib100db72016-10-12 16:28:56 -07005334#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335 if (cpi->common.allow_screen_content_tools && mbmi->sb_type >= BLOCK_8X8) {
5336 best_palette_color_map = x->palette_buffer->best_palette_color_map;
hui su83c26632017-01-24 17:19:06 -08005337 rd_pick_palette_intra_sbuv(cpi, x,
5338 cpi->intra_uv_mode_cost[mbmi->mode][DC_PRED],
5339 best_palette_color_map, &best_mbmi, &best_rd,
5340 rate, rate_tokenonly, distortion, skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005341 }
Urvang Joshib100db72016-10-12 16:28:56 -07005342#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07005343
hui su5db97432016-10-14 16:10:14 -07005344#if CONFIG_FILTER_INTRA
5345 if (mbmi->sb_type >= BLOCK_8X8) {
5346 if (rd_pick_filter_intra_sbuv(cpi, x, rate, rate_tokenonly, distortion,
hui su83c26632017-01-24 17:19:06 -08005347 skippable, bsize, &best_rd))
5348 best_mbmi = *mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005349 }
hui su5db97432016-10-14 16:10:14 -07005350#endif // CONFIG_FILTER_INTRA
5351
hui su83c26632017-01-24 17:19:06 -08005352 *mbmi = best_mbmi;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005353 // Make sure we actually chose a mode
5354 assert(best_rd < INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 return best_rd;
5356}
5357
Urvang Joshi52648442016-10-13 17:27:51 -07005358static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005359 PICK_MODE_CONTEXT *ctx, BLOCK_SIZE bsize,
5360 TX_SIZE max_tx_size, int *rate_uv,
5361 int *rate_uv_tokenonly, int64_t *dist_uv,
5362 int *skip_uv, PREDICTION_MODE *mode_uv) {
5363 // Use an estimated rd for uv_intra based on DC_PRED if the
5364 // appropriate speed flag is set.
Jingning Han3f167252016-06-07 16:11:42 -07005365 (void)ctx;
hui sueaddeee2017-05-30 12:19:38 -07005366 init_sbuv_mode(&x->e_mbd.mi[0]->mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08005367#if CONFIG_CB4X4
Jingning Han31b6a4f2017-02-23 11:05:53 -08005368#if CONFIG_CHROMA_2X2
5369 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
5370 bsize, max_tx_size);
5371#else
Jingning Han9ce464c2017-02-20 15:36:30 -08005372 if (x->skip_chroma_rd) {
5373 *rate_uv = 0;
5374 *rate_uv_tokenonly = 0;
5375 *dist_uv = 0;
5376 *skip_uv = 1;
5377 *mode_uv = DC_PRED;
5378 return;
5379 }
Jingning Han65113f32017-04-12 10:06:58 -07005380 BLOCK_SIZE bs = scale_chroma_bsize(bsize, x->e_mbd.plane[1].subsampling_x,
5381 x->e_mbd.plane[1].subsampling_y);
Jingning Han3f167252016-06-07 16:11:42 -07005382 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
Jingning Han65113f32017-04-12 10:06:58 -07005383 bs, max_tx_size);
Jingning Han31b6a4f2017-02-23 11:05:53 -08005384#endif // CONFIG_CHROMA_2X2
5385#else
5386 rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
5387 bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
5388#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389 *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
5390}
5391
Urvang Joshi52648442016-10-13 17:27:51 -07005392static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005393 int16_t mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005394#if CONFIG_EXT_INTER
5395 if (is_inter_compound_mode(mode)) {
clang-format55ce9e02017-02-15 22:27:12 -08005396 return cpi
5397 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
Zoe Liu85b66462017-04-20 14:28:19 -07005398#if CONFIG_COMPOUND_SINGLEREF
5399 } else if (is_inter_singleref_comp_mode(mode)) {
5400 return cpi
5401 ->inter_singleref_comp_mode_cost[mode_context]
5402 [INTER_SINGLEREF_COMP_OFFSET(mode)];
5403#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005404 }
David Barkercb03dc32017-04-07 13:05:09 +01005405#endif
5406
David Barkercb03dc32017-04-07 13:05:09 +01005407 int mode_cost = 0;
5408 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
5409 int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
5410
5411 assert(is_inter_mode(mode));
5412
5413 if (mode == NEWMV) {
5414 mode_cost = cpi->newmv_mode_cost[mode_ctx][0];
5415 return mode_cost;
5416 } else {
5417 mode_cost = cpi->newmv_mode_cost[mode_ctx][1];
5418 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
5419
5420 if (is_all_zero_mv) return mode_cost;
5421
5422 if (mode == ZEROMV) {
5423 mode_cost += cpi->zeromv_mode_cost[mode_ctx][0];
5424 return mode_cost;
5425 } else {
5426 mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
5427 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
5428
5429 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
5430 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
5431 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
5432
5433 mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
5434 return mode_cost;
5435 }
5436 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005437}
5438
Yue Chen5e606542017-05-24 17:03:17 -07005439#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005440static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
5441 COMPOUND_TYPE comp_type) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005442 (void)bsize;
Sarah Parker6fdc8532016-11-16 17:47:13 -08005443 switch (comp_type) {
5444 case COMPOUND_AVERAGE: return 0;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005445#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08005446 case COMPOUND_WEDGE: return get_interinter_wedge_bits(bsize);
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00005447#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08005448#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08005449 case COMPOUND_SEG: return 1;
Sarah Parker2f6ce752016-12-08 15:26:46 -08005450#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08005451 default: assert(0); return 0;
5452 }
5453}
Yue Chen5e606542017-05-24 17:03:17 -07005454#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
Sarah Parker6fdc8532016-11-16 17:47:13 -08005455
Yaowu Xuc27fc142016-08-22 16:08:15 -07005456typedef struct {
5457 int eobs;
5458 int brate;
5459 int byrate;
5460 int64_t bdist;
5461 int64_t bsse;
5462 int64_t brdcost;
5463 int_mv mvs[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005464 int_mv pred_mv[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465#if CONFIG_EXT_INTER
5466 int_mv ref_mv[2];
5467#endif // CONFIG_EXT_INTER
Jingning Han276c2942016-12-05 12:37:02 -08005468
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005469#if CONFIG_CHROMA_2X2
Jingning Han276c2942016-12-05 12:37:02 -08005470 ENTROPY_CONTEXT ta[4];
5471 ENTROPY_CONTEXT tl[4];
5472#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005473 ENTROPY_CONTEXT ta[2];
5474 ENTROPY_CONTEXT tl[2];
Timothy B. Terriberryfe67ed62017-04-26 16:53:47 -07005475#endif // CONFIG_CHROMA_2X2
Yaowu Xuc27fc142016-08-22 16:08:15 -07005476} SEG_RDSTAT;
5477
5478typedef struct {
5479 int_mv *ref_mv[2];
5480 int_mv mvp;
5481
5482 int64_t segment_rd;
5483 int r;
5484 int64_t d;
5485 int64_t sse;
5486 int segment_yrate;
5487 PREDICTION_MODE modes[4];
5488#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07005489#if CONFIG_COMPOUND_SINGLEREF
5490 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_SINGLEREF_COMP_MODES +
5491 INTER_COMPOUND_MODES];
5492#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493 SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
Zoe Liu85b66462017-04-20 14:28:19 -07005494#endif // CONFIG_COMPOUND_SINGLEREF
5495#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496 SEG_RDSTAT rdstat[4][INTER_MODES];
5497#endif // CONFIG_EXT_INTER
5498 int mvthresh;
5499} BEST_SEG_INFO;
5500
Alex Converse0fa0f422017-04-24 12:51:14 -07005501static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
5502 return (mv->row >> 3) < mv_limits->row_min ||
5503 (mv->row >> 3) > mv_limits->row_max ||
5504 (mv->col >> 3) < mv_limits->col_min ||
5505 (mv->col >> 3) > mv_limits->col_max;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005506}
5507
Yaowu Xuc27fc142016-08-22 16:08:15 -07005508// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
5509// TODO(aconverse): Find out if this is still productive then clean up or remove
5510static int check_best_zero_mv(
Urvang Joshi52648442016-10-13 17:27:51 -07005511 const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005512#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513 const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
Sebastien Alaiwane140c502017-04-27 09:52:34 +02005514#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005515 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
David Barker45390c12017-02-20 14:44:40 +00005516 const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
5517 int mi_row, int mi_col) {
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005518 int_mv zeromv[2] = { {.as_int = 0 } };
Yushin Choc9751c52017-06-12 10:38:29 -07005519#if CONFIG_GLOBAL_MOTION
Sarah Parkerc2d38712017-01-24 15:15:41 -08005520 int comp_pred_mode = ref_frames[1] > INTRA_FRAME;
Yushin Choc9751c52017-06-12 10:38:29 -07005521#endif
David Barker45390c12017-02-20 14:44:40 +00005522 (void)mi_row;
5523 (void)mi_col;
Sarah Parkerc2d38712017-01-24 15:15:41 -08005524#if CONFIG_GLOBAL_MOTION
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005525 if (this_mode == ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005526#if CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005527 || this_mode == ZERO_ZEROMV
Sarah Parkerc2d38712017-01-24 15:15:41 -08005528#endif // CONFIG_EXT_INTER
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005529 ) {
5530 for (int cur_frm = 0; cur_frm < 1 + comp_pred_mode; cur_frm++) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08005531 zeromv[cur_frm].as_int =
5532 gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
Sarah Parkerae7c4582017-02-28 16:30:30 -08005533 cpi->common.allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08005534 mi_col, mi_row, block)
Sarah Parkerc2d38712017-01-24 15:15:41 -08005535 .as_int;
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005536 }
Sarah Parkerc2d38712017-01-24 15:15:41 -08005537 }
Luc Trudeaud28e91d2017-06-05 14:42:26 -04005538#endif // CONFIG_GLOBAL_MOTION
5539
Yaowu Xuc27fc142016-08-22 16:08:15 -07005540#if !CONFIG_EXT_INTER
5541 assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
Fergus Simpson4063a682017-02-28 16:52:22 -08005542#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543 if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005544 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545 (ref_frames[1] <= INTRA_FRAME ||
Sarah Parkerc2d38712017-01-24 15:15:41 -08005546 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005547 int16_t rfc =
Yaowu Xuf883b422016-08-30 14:01:10 -07005548 av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549 int c1 = cost_mv_ref(cpi, NEARMV, rfc);
5550 int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
5551 int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552
Yaowu Xuc27fc142016-08-22 16:08:15 -07005553 if (this_mode == NEARMV) {
5554 if (c1 > c3) return 0;
5555 } else if (this_mode == NEARESTMV) {
5556 if (c2 > c3) return 0;
5557 } else {
5558 assert(this_mode == ZEROMV);
5559 if (ref_frames[1] <= INTRA_FRAME) {
5560 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
5561 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
5562 return 0;
5563 } else {
5564 if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0 &&
5565 frame_mv[NEARESTMV][ref_frames[1]].as_int == 0) ||
5566 (c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0 &&
5567 frame_mv[NEARMV][ref_frames[1]].as_int == 0))
5568 return 0;
5569 }
5570 }
5571 }
5572#if CONFIG_EXT_INTER
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005573 else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 this_mode == ZERO_ZEROMV) &&
Sarah Parkerc2d38712017-01-24 15:15:41 -08005575 frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
5576 frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577 int16_t rfc = compound_mode_context[ref_frames[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005578 int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
5579 int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005580 int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005582 if (this_mode == NEAREST_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583 if (c2 > c3) return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005584 } else if (this_mode == NEAR_NEARMV) {
5585 if (c5 > c3) return 0;
5586 } else {
5587 assert(this_mode == ZERO_ZEROMV);
5588 if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
5589 frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
Yaowu Xuc27fc142016-08-22 16:08:15 -07005590 (c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07005591 frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005592 return 0;
5593 }
5594 }
5595#endif // CONFIG_EXT_INTER
5596 return 1;
5597}
5598
Urvang Joshi52648442016-10-13 17:27:51 -07005599static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
Zoe Liu85b66462017-04-20 14:28:19 -07005600 BLOCK_SIZE bsize, int_mv *frame_mv,
5601#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5602 int_mv *frame_comp_mv,
5603#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5604 int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605#if CONFIG_EXT_INTER
David Barkerc155e012017-05-11 13:54:54 +01005606 int_mv *ref_mv_sub8x8[2], const uint8_t *mask,
5607 int mask_stride,
Fergus Simpson4063a682017-02-28 16:52:22 -08005608#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609 int *rate_mv, const int block) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005610 const AV1_COMMON *const cm = &cpi->common;
Jingning Hanae5cfde2016-11-30 12:01:44 -08005611 const int pw = block_size_wide[bsize];
5612 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613 MACROBLOCKD *xd = &x->e_mbd;
5614 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07005615// This function should only ever be called for compound modes
5616#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5617 if (!has_second_ref(mbmi)) {
5618 assert(is_inter_singleref_comp_mode(mbmi->mode));
5619 assert(frame_comp_mv);
5620 }
5621 assert(has_second_ref(mbmi) || is_inter_singleref_comp_mode(mbmi->mode));
5622 const int refs[2] = { mbmi->ref_frame[0], has_second_ref(mbmi)
5623 ? mbmi->ref_frame[1]
5624 : mbmi->ref_frame[0] };
5625#else
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005626 assert(has_second_ref(mbmi));
Zoe Liu122f3942017-04-25 11:18:38 -07005627 const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
Zoe Liu85b66462017-04-20 14:28:19 -07005628#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005629 int_mv ref_mv[2];
5630 int ite, ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005631 struct scale_factors sf;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005632#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005633 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
5634 const int ic = block & 1;
5635 const int ir = (block - ic) >> 1;
Jingning Hancb637672017-06-22 09:14:40 -07005636 struct macroblockd_plane *const pd = &xd->plane[0];
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005637 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
5638 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005639#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005640 int is_global[2];
Zoe Liu85b66462017-04-20 14:28:19 -07005641#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5642 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5643#else
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005644 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005645#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005646 WarpedMotionParams *const wm =
5647 &xd->global_motion[xd->mi[0]->mbmi.ref_frame[ref]];
5648 is_global[ref] = is_global_mv_block(xd->mi[0], block, wm->wmtype);
5649 }
Zoe Liu85b66462017-04-20 14:28:19 -07005650#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5651 if (!has_second_ref(mbmi)) is_global[1] = is_global[0];
5652#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005653#endif // CONFIG_GLOBAL_MOTION
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005654#else // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5655 (void)block;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005656#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005657
5658 // Do joint motion search in compound mode to get more accurate mv.
5659 struct buf_2d backup_yv12[2][MAX_MB_PLANE];
5660 int last_besterr[2] = { INT_MAX, INT_MAX };
5661 const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
Zoe Liu122f3942017-04-25 11:18:38 -07005662 av1_get_scaled_ref_frame(cpi, refs[0]),
5663 av1_get_scaled_ref_frame(cpi, refs[1])
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664 };
5665
5666// Prediction buffer from second frame.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005667#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005668 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
5669 uint8_t *second_pred;
5670#else
5671 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005672#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005673
Jingning Han61418bb2017-01-23 17:12:48 -08005674#if CONFIG_EXT_INTER && CONFIG_CB4X4
5675 (void)ref_mv_sub8x8;
Fergus Simpson4063a682017-02-28 16:52:22 -08005676#endif // CONFIG_EXT_INTER && CONFIG_CB4X4
Jingning Han61418bb2017-01-23 17:12:48 -08005677
Zoe Liu85b66462017-04-20 14:28:19 -07005678#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5679 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5680#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005681 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005682#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Jingning Han61418bb2017-01-23 17:12:48 -08005683#if CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005684 if (bsize < BLOCK_8X8 && ref_mv_sub8x8 != NULL)
5685 ref_mv[ref].as_int = ref_mv_sub8x8[ref]->as_int;
5686 else
Fergus Simpson4063a682017-02-28 16:52:22 -08005687#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688 ref_mv[ref] = x->mbmi_ext->ref_mvs[refs[ref]][0];
5689
5690 if (scaled_ref_frame[ref]) {
5691 int i;
5692 // Swap out the reference frame for a version that's been scaled to
5693 // match the resolution of the current frame, allowing the existing
5694 // motion search code to be used without additional modifications.
5695 for (i = 0; i < MAX_MB_PLANE; i++)
5696 backup_yv12[ref][i] = xd->plane[i].pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07005697 av1_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
5698 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005699 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005700 }
5701
Zoe Liu85b66462017-04-20 14:28:19 -07005702#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5703 if (!has_second_ref(mbmi)) {
5704 assert(is_inter_singleref_comp_mode(mbmi->mode));
5705 // NOTE: For single ref comp mode, set up the 2nd set of ref_mv/pre_planes
5706 // all from the 1st reference frame, i.e. refs[0].
5707 ref_mv[1] = x->mbmi_ext->ref_mvs[refs[0]][0];
5708 if (scaled_ref_frame[0]) {
5709 int i;
5710 // Swap out the reference frame for a version that's been scaled to
5711 // match the resolution of the current frame, allowing the existing
5712 // motion search code to be used without additional modifications.
5713 for (i = 0; i < MAX_MB_PLANE; i++)
5714 backup_yv12[1][i] = xd->plane[i].pre[1];
5715 av1_setup_pre_planes(xd, 1, scaled_ref_frame[0], mi_row, mi_col, NULL);
5716 }
5717 }
5718#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5719
Yaowu Xuc27fc142016-08-22 16:08:15 -07005720// Since we have scaled the reference frames to match the size of the current
5721// frame we must use a unit scaling factor during mode selection.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005722#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005723 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5724 cm->height, cm->use_highbitdepth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005725#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005726 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
5727 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005728#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005729
Zoe Liu85b66462017-04-20 14:28:19 -07005730// Allow joint search multiple times iteratively for each reference frame
5731// and break out of the search loop if it couldn't find a better mv.
5732#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5733 const int num_ites =
5734 (has_second_ref(mbmi) || mbmi->mode == SR_NEW_NEWMV) ? 4 : 1;
5735 const int start_ite = has_second_ref(mbmi) ? 0 : 1;
5736 for (ite = start_ite; ite < (start_ite + num_ites); ite++) {
5737#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005738 for (ite = 0; ite < 4; ite++) {
Zoe Liu85b66462017-04-20 14:28:19 -07005739#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005740 struct buf_2d ref_yv12[2];
5741 int bestsme = INT_MAX;
5742 int sadpb = x->sadperbit16;
5743 MV *const best_mv = &x->best_mv.as_mv;
5744 int search_range = 3;
5745
Alex Converse0fa0f422017-04-24 12:51:14 -07005746 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005747 int id = ite % 2; // Even iterations search in the first reference frame,
5748 // odd iterations search in the second. The predictor
5749 // found for the 'other' reference frame is factored in.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005750 const int plane = 0;
David Barkere64d51a2017-06-09 14:52:42 +01005751 ConvolveParams conv_params = get_conv_params(!id, 0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005752#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5753 WarpTypesAllowed warp_types;
5754#if CONFIG_GLOBAL_MOTION
5755 warp_types.global_warp_allowed = is_global[!id];
5756#endif // CONFIG_GLOBAL_MOTION
5757#if CONFIG_WARPED_MOTION
5758 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
5759#endif // CONFIG_WARPED_MOTION
5760#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005761
5762 // Initialized here because of compiler problem in Visual Studio.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005763 ref_yv12[0] = xd->plane[plane].pre[0];
5764 ref_yv12[1] = xd->plane[plane].pre[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005765
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766// Get the prediction block from the 'other' reference frame.
Zoe Liu85b66462017-04-20 14:28:19 -07005767#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5768 MV *const the_other_mv = (has_second_ref(mbmi) || id)
5769 ? &frame_mv[refs[!id]].as_mv
5770 : &frame_comp_mv[refs[0]].as_mv;
5771#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5772
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005773#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005774 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5775 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
Yaowu Xuf883b422016-08-30 14:01:10 -07005776 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005777 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
Zoe Liu85b66462017-04-20 14:28:19 -07005778#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5779 the_other_mv,
5780#else // !(CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF)
5781 &frame_mv[refs[!id]].as_mv,
5782#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5783 &sf, pw, ph, 0, mbmi->interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005784#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
5785 &warp_types, p_col, p_row,
5786#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08005787 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 } else {
5789 second_pred = (uint8_t *)second_pred_alloc_16;
Zoe Liu76fcff72017-04-24 17:50:53 -07005790#endif // CONFIG_HIGHBITDEPTH
Zoe Liu85b66462017-04-20 14:28:19 -07005791 av1_build_inter_predictor(
5792 ref_yv12[!id].buf, ref_yv12[!id].stride, second_pred, pw,
5793#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5794 the_other_mv,
5795#else // !(CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF)
5796 &frame_mv[refs[!id]].as_mv,
5797#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5798 &sf, pw, ph, &conv_params, mbmi->interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005799#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Zoe Liu85b66462017-04-20 14:28:19 -07005800 &warp_types, p_col, p_row, plane, !id,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07005801#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Zoe Liu85b66462017-04-20 14:28:19 -07005802 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
Zoe Liu76fcff72017-04-24 17:50:53 -07005803#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005804 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005805#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005806
5807 // Do compound motion search on the current reference frame.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005808 if (id) xd->plane[plane].pre[0] = ref_yv12[id];
Alex Converse0fa0f422017-04-24 12:51:14 -07005809 av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005810
Zoe Liu85b66462017-04-20 14:28:19 -07005811// Use the mv result from the single mode as mv predictor.
5812// Use the mv result from the single mode as mv predictor.
5813#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5814 if (!has_second_ref(mbmi) && id)
5815 *best_mv = frame_comp_mv[refs[0]].as_mv;
5816 else
5817#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5818 *best_mv = frame_mv[refs[id]].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819
5820 best_mv->col >>= 3;
5821 best_mv->row >>= 3;
5822
Zoe Liu85b66462017-04-20 14:28:19 -07005823#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5824 if (!has_second_ref(mbmi))
5825 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
5826 else
5827#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5828 av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005829
5830 // Small-range full-pixel motion search.
5831 bestsme =
Yaowu Xuf883b422016-08-30 14:01:10 -07005832 av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
David Barkerc155e012017-05-11 13:54:54 +01005833#if CONFIG_EXT_INTER
5834 mask, mask_stride, id,
5835#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07005836 &ref_mv[id].as_mv, second_pred);
David Barkerc155e012017-05-11 13:54:54 +01005837 if (bestsme < INT_MAX) {
5838#if CONFIG_EXT_INTER
5839 if (mask)
5840 bestsme = av1_get_mvpred_mask_var(x, best_mv, &ref_mv[id].as_mv,
5841 second_pred, mask, mask_stride, id,
5842 &cpi->fn_ptr[bsize], 1);
5843 else
5844#endif
5845 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
5846 second_pred, &cpi->fn_ptr[bsize], 1);
5847 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848
Alex Converse0fa0f422017-04-24 12:51:14 -07005849 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005850
5851 if (bestsme < INT_MAX) {
5852 int dis; /* TODO: use dis in distortion calculation later. */
5853 unsigned int sse;
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005854 bestsme = cpi->find_fractional_mv_step(
5855 x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
5856 x->errorperbit, &cpi->fn_ptr[bsize], 0,
5857 cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
5858 &dis, &sse, second_pred,
David Barkerc155e012017-05-11 13:54:54 +01005859#if CONFIG_EXT_INTER
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005860 mask, mask_stride, id,
David Barkerc155e012017-05-11 13:54:54 +01005861#endif
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07005862 pw, ph, cpi->sf.use_upsampled_references);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863 }
5864
5865 // Restore the pointer to the first (possibly scaled) prediction buffer.
Angie Chiange3a4c1c2017-02-10 16:26:49 -08005866 if (id) xd->plane[plane].pre[0] = ref_yv12[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005867
5868 if (bestsme < last_besterr[id]) {
Zoe Liu85b66462017-04-20 14:28:19 -07005869#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5870 // NOTE: For single ref comp mode, frame_mv stores the first mv and
5871 // frame_comp_mv stores the second mv.
5872 if (!has_second_ref(mbmi) && id)
5873 frame_comp_mv[refs[0]].as_mv = *best_mv;
5874 else
5875#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5876 frame_mv[refs[id]].as_mv = *best_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005877 last_besterr[id] = bestsme;
Zoe Liu85b66462017-04-20 14:28:19 -07005878#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5879 if (!has_second_ref(mbmi)) last_besterr[!id] = last_besterr[id];
5880#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005881 } else {
5882 break;
5883 }
5884 }
5885
5886 *rate_mv = 0;
5887
Zoe Liu85b66462017-04-20 14:28:19 -07005888#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5889 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
5890#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005891 for (ref = 0; ref < 2; ++ref) {
Zoe Liu85b66462017-04-20 14:28:19 -07005892#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005893 if (scaled_ref_frame[ref]) {
5894 // Restore the prediction frame pointers to their unscaled versions.
5895 int i;
5896 for (i = 0; i < MAX_MB_PLANE; i++)
5897 xd->plane[i].pre[ref] = backup_yv12[ref][i];
5898 }
Zoe Liu85b66462017-04-20 14:28:19 -07005899
5900#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5901 if (!has_second_ref(mbmi))
5902 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005903 else
Zoe Liu85b66462017-04-20 14:28:19 -07005904#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5905 av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
5906
5907#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5908 if (!has_second_ref(mbmi)) {
5909 // NOTE: For single ref comp mode, i.e. !has_second_ref(mbmi) is true, the
5910 // first mv is stored in frame_mv[] and the second mv is stored in
5911 // frame_comp_mv[].
5912 if (compound_ref0_mode(mbmi->mode) == NEWMV) // SR_NEW_NEWMV
5913 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
5914 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5915 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5916 assert(compound_ref1_mode(mbmi->mode) == NEWMV);
5917 *rate_mv += av1_mv_bit_cost(&frame_comp_mv[refs[0]].as_mv,
5918 &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
5919 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5920 } else {
5921#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5922#if CONFIG_EXT_INTER && !CONFIG_CB4X4
5923 if (bsize >= BLOCK_8X8)
Fergus Simpson4063a682017-02-28 16:52:22 -08005924#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
Zoe Liu85b66462017-04-20 14:28:19 -07005925 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5926 &x->mbmi_ext->ref_mvs[refs[ref]][0].as_mv,
5927 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
5928#if CONFIG_EXT_INTER && !CONFIG_CB4X4
5929 else
5930 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[ref]].as_mv,
5931 &ref_mv_sub8x8[ref]->as_mv, x->nmvjointcost,
5932 x->mvcost, MV_COST_WEIGHT);
5933#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
5934#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5935 }
5936#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937 }
Zoe Liu85b66462017-04-20 14:28:19 -07005938
5939#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
5940 if (!has_second_ref(mbmi)) {
5941 if (scaled_ref_frame[0]) {
5942 // Restore the prediction frame pointers to their unscaled versions.
5943 int i;
5944 for (i = 0; i < MAX_MB_PLANE; i++)
5945 xd->plane[i].pre[1] = backup_yv12[1][i];
5946 }
5947 }
5948#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07005949}
5950
Zoe Liuc082bbc2017-05-17 13:31:37 -07005951static void estimate_ref_frame_costs(
5952 const AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
5953 unsigned int *ref_costs_single,
5954#if CONFIG_EXT_COMP_REFS
5955 unsigned int (*ref_costs_comp)[TOTAL_REFS_PER_FRAME],
5956#else
5957 unsigned int *ref_costs_comp,
5958#endif // CONFIG_EXT_COMP_REFS
5959 aom_prob *comp_mode_p) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005960 int seg_ref_active =
5961 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
5962 if (seg_ref_active) {
5963 memset(ref_costs_single, 0,
5964 TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_single));
Zoe Liuc082bbc2017-05-17 13:31:37 -07005965#if CONFIG_EXT_COMP_REFS
5966 int ref_frame;
5967 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
5968 memset(ref_costs_comp[ref_frame], 0,
5969 TOTAL_REFS_PER_FRAME * sizeof((*ref_costs_comp)[0]));
5970#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971 memset(ref_costs_comp, 0, TOTAL_REFS_PER_FRAME * sizeof(*ref_costs_comp));
Zoe Liuc082bbc2017-05-17 13:31:37 -07005972#endif // CONFIG_EXT_COMP_REFS
5973
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974 *comp_mode_p = 128;
5975 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005976 aom_prob intra_inter_p = av1_get_intra_inter_prob(cm, xd);
5977 aom_prob comp_inter_p = 128;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978
5979 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005980 comp_inter_p = av1_get_reference_mode_prob(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005981 *comp_mode_p = comp_inter_p;
5982 } else {
5983 *comp_mode_p = 128;
5984 }
5985
Yaowu Xuf883b422016-08-30 14:01:10 -07005986 ref_costs_single[INTRA_FRAME] = av1_cost_bit(intra_inter_p, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005987
5988 if (cm->reference_mode != COMPOUND_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005989 aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
5990 aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005991#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005992 aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
5993 aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
5994 aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005995#endif // CONFIG_EXT_REFS
5996
Yaowu Xuf883b422016-08-30 14:01:10 -07005997 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005998
5999 ref_costs_single[LAST_FRAME] =
6000#if CONFIG_EXT_REFS
6001 ref_costs_single[LAST2_FRAME] = ref_costs_single[LAST3_FRAME] =
6002 ref_costs_single[BWDREF_FRAME] =
6003#endif // CONFIG_EXT_REFS
6004 ref_costs_single[GOLDEN_FRAME] =
6005 ref_costs_single[ALTREF_FRAME] = base_cost;
6006
6007#if CONFIG_EXT_REFS
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006008#if CONFIG_VAR_REFS
6009 // Test need to explicitly code (L,L2,L3,G) vs (BWD,ALT) branch node in
6010 // tree
6011 if ((L_OR_L2(cm) || L3_OR_G(cm)) && BWD_OR_ALT(cm)) {
6012#endif // CONFIG_VAR_REFS
6013 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6014 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
6015 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
6016 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
6017 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6018 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
6019#if CONFIG_VAR_REFS
6020 }
6021#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006022
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006023#if CONFIG_VAR_REFS
6024 // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree
6025 if (L_OR_L2(cm) && L3_OR_G(cm)) {
6026#endif // CONFIG_VAR_REFS
6027 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
6028 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
6029 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
6030 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
6031#if CONFIG_VAR_REFS
6032 }
6033#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006034
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006035#if CONFIG_VAR_REFS
6036 // Test need to explicitly code (BWD) vs (ALT) branch node in tree
6037 if (BWD_AND_ALT(cm)) {
6038#endif // CONFIG_VAR_REFS
6039 ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
6040 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
6041#if CONFIG_VAR_REFS
6042 }
6043#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006044
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006045#if CONFIG_VAR_REFS
6046 // Test need to explicitly code (L) vs (L2) branch node in tree
6047 if (L_AND_L2(cm)) {
6048#endif // CONFIG_VAR_REFS
6049 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
6050 ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
6051#if CONFIG_VAR_REFS
6052 }
6053#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006054
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006055#if CONFIG_VAR_REFS
6056 // Test need to explicitly code (L3) vs (G) branch node in tree
6057 if (L3_AND_G(cm)) {
6058#endif // CONFIG_VAR_REFS
6059 ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
6060 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
6061#if CONFIG_VAR_REFS
6062 }
6063#endif // CONFIG_VAR_REFS
6064#else // !CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006065 ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
6066 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 1);
6067 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006068
Yaowu Xuf883b422016-08-30 14:01:10 -07006069 ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p2, 0);
6070 ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006071#endif // CONFIG_EXT_REFS
6072 } else {
6073 ref_costs_single[LAST_FRAME] = 512;
6074#if CONFIG_EXT_REFS
6075 ref_costs_single[LAST2_FRAME] = 512;
6076 ref_costs_single[LAST3_FRAME] = 512;
6077 ref_costs_single[BWDREF_FRAME] = 512;
6078#endif // CONFIG_EXT_REFS
6079 ref_costs_single[GOLDEN_FRAME] = 512;
6080 ref_costs_single[ALTREF_FRAME] = 512;
6081 }
6082
6083 if (cm->reference_mode != SINGLE_REFERENCE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006084 aom_prob ref_comp_p = av1_get_pred_prob_comp_ref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006085#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006086 aom_prob ref_comp_p1 = av1_get_pred_prob_comp_ref_p1(cm, xd);
6087 aom_prob ref_comp_p2 = av1_get_pred_prob_comp_ref_p2(cm, xd);
6088 aom_prob bwdref_comp_p = av1_get_pred_prob_comp_bwdref_p(cm, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006089#endif // CONFIG_EXT_REFS
6090
Yaowu Xuf883b422016-08-30 14:01:10 -07006091 unsigned int base_cost = av1_cost_bit(intra_inter_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006092
Zoe Liuc082bbc2017-05-17 13:31:37 -07006093#if CONFIG_EXT_COMP_REFS
6094 aom_prob comp_ref_type_p = av1_get_comp_reference_type_prob(cm, xd);
6095 unsigned int ref_bicomp_costs[TOTAL_REFS_PER_FRAME] = { 0 };
6096
6097 ref_bicomp_costs[LAST_FRAME] = ref_bicomp_costs[LAST2_FRAME] =
6098 ref_bicomp_costs[LAST3_FRAME] = ref_bicomp_costs[GOLDEN_FRAME] =
6099#if USE_UNI_COMP_REFS
6100 base_cost + av1_cost_bit(comp_ref_type_p, 1);
6101#else
6102 base_cost;
6103#endif // USE_UNI_COMP_REFS
6104 ref_bicomp_costs[BWDREF_FRAME] = ref_bicomp_costs[ALTREF_FRAME] = 0;
6105
6106 ref_bicomp_costs[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6107 ref_bicomp_costs[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6108 ref_bicomp_costs[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6109 ref_bicomp_costs[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
6110
6111 ref_bicomp_costs[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6112 ref_bicomp_costs[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
6113
6114 ref_bicomp_costs[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6115 ref_bicomp_costs[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
6116
6117 ref_bicomp_costs[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6118 ref_bicomp_costs[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
6119
6120 int ref0;
6121 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
6122 ref_costs_comp[ref0][BWDREF_FRAME] =
6123 ref_bicomp_costs[ref0] + ref_bicomp_costs[BWDREF_FRAME];
6124 ref_costs_comp[ref0][ALTREF_FRAME] =
6125 ref_bicomp_costs[ref0] + ref_bicomp_costs[ALTREF_FRAME];
6126 }
6127
6128 aom_prob uni_comp_ref_p = av1_get_pred_prob_uni_comp_ref_p(cm, xd);
6129 aom_prob uni_comp_ref_p1 = av1_get_pred_prob_uni_comp_ref_p1(cm, xd);
6130
6131 ref_costs_comp[LAST_FRAME][LAST2_FRAME] =
6132 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6133 av1_cost_bit(uni_comp_ref_p, 0) + av1_cost_bit(uni_comp_ref_p1, 0);
6134 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] =
6135 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6136 av1_cost_bit(uni_comp_ref_p, 0) + av1_cost_bit(uni_comp_ref_p1, 1);
6137
6138 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] =
6139 base_cost + av1_cost_bit(comp_ref_type_p, 0) +
6140 av1_cost_bit(uni_comp_ref_p, 1);
6141
6142#else // !CONFIG_EXT_COMP_REFS
6143
Yaowu Xuc27fc142016-08-22 16:08:15 -07006144 ref_costs_comp[LAST_FRAME] =
6145#if CONFIG_EXT_REFS
6146 ref_costs_comp[LAST2_FRAME] = ref_costs_comp[LAST3_FRAME] =
6147#endif // CONFIG_EXT_REFS
6148 ref_costs_comp[GOLDEN_FRAME] = base_cost;
6149
6150#if CONFIG_EXT_REFS
6151 ref_costs_comp[BWDREF_FRAME] = ref_costs_comp[ALTREF_FRAME] = 0;
6152#endif // CONFIG_EXT_REFS
6153
6154#if CONFIG_EXT_REFS
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006155#if CONFIG_VAR_REFS
6156 // Test need to explicitly code (L,L2) vs (L3,G) branch node in tree
6157 if (L_OR_L2(cm) && L3_OR_G(cm)) {
6158#endif // CONFIG_VAR_REFS
6159 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6160 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p, 0);
6161 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p, 1);
6162 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
6163#if CONFIG_VAR_REFS
6164 }
6165#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006166
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006167#if CONFIG_VAR_REFS
6168 // Test need to explicitly code (L) vs (L2) branch node in tree
6169 if (L_AND_L2(cm)) {
6170#endif // CONFIG_VAR_REFS
6171 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p1, 1);
6172 ref_costs_comp[LAST2_FRAME] += av1_cost_bit(ref_comp_p1, 0);
6173#if CONFIG_VAR_REFS
6174 }
6175#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006176
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006177#if CONFIG_VAR_REFS
6178 // Test need to explicitly code (L3) vs (G) branch node in tree
6179 if (L3_AND_G(cm)) {
6180#endif // CONFIG_VAR_REFS
6181 ref_costs_comp[LAST3_FRAME] += av1_cost_bit(ref_comp_p2, 0);
6182 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p2, 1);
6183#if CONFIG_VAR_REFS
6184 }
6185#endif // CONFIG_VAR_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006186
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07006187// NOTE(zoeliu): BWDREF and ALTREF each add an extra cost by coding 1
6188// more bit.
6189#if CONFIG_VAR_REFS
6190 // Test need to explicitly code (BWD) vs (ALT) branch node in tree
6191 if (BWD_AND_ALT(cm)) {
6192#endif // CONFIG_VAR_REFS
6193 ref_costs_comp[BWDREF_FRAME] += av1_cost_bit(bwdref_comp_p, 0);
6194 ref_costs_comp[ALTREF_FRAME] += av1_cost_bit(bwdref_comp_p, 1);
6195#if CONFIG_VAR_REFS
6196 }
6197#endif // CONFIG_VAR_REFS
6198#else // !CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07006199 ref_costs_comp[LAST_FRAME] += av1_cost_bit(ref_comp_p, 0);
6200 ref_costs_comp[GOLDEN_FRAME] += av1_cost_bit(ref_comp_p, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006201#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -07006202#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 } else {
Zoe Liuc082bbc2017-05-17 13:31:37 -07006204#if CONFIG_EXT_COMP_REFS
6205 int ref0;
6206 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
6207 ref_costs_comp[ref0][BWDREF_FRAME] = 512;
6208 ref_costs_comp[ref0][ALTREF_FRAME] = 512;
6209 }
6210 ref_costs_comp[LAST_FRAME][LAST2_FRAME] = 512;
6211 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] = 512;
6212 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] = 512;
6213#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006214 ref_costs_comp[LAST_FRAME] = 512;
6215#if CONFIG_EXT_REFS
6216 ref_costs_comp[LAST2_FRAME] = 512;
6217 ref_costs_comp[LAST3_FRAME] = 512;
6218 ref_costs_comp[BWDREF_FRAME] = 512;
6219 ref_costs_comp[ALTREF_FRAME] = 512;
6220#endif // CONFIG_EXT_REFS
6221 ref_costs_comp[GOLDEN_FRAME] = 512;
Zoe Liuc082bbc2017-05-17 13:31:37 -07006222#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07006223 }
6224 }
6225}
6226
6227static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
6228 int mode_index,
6229 int64_t comp_pred_diff[REFERENCE_MODES],
6230 int skippable) {
6231 MACROBLOCKD *const xd = &x->e_mbd;
6232
6233 // Take a snapshot of the coding context so it can be
6234 // restored if we decide to encode this way
6235 ctx->skip = x->skip;
6236 ctx->skippable = skippable;
6237 ctx->best_mode_index = mode_index;
6238 ctx->mic = *xd->mi[0];
6239 ctx->mbmi_ext = *x->mbmi_ext;
6240 ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
6241 ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
6242 ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
6243}
6244
clang-format55ce9e02017-02-15 22:27:12 -08006245static void setup_buffer_inter(
6246 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
6247 BLOCK_SIZE block_size, int mi_row, int mi_col,
6248 int_mv frame_nearest_mv[TOTAL_REFS_PER_FRAME],
6249 int_mv frame_near_mv[TOTAL_REFS_PER_FRAME],
6250 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE]) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006251 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006252 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
6253 MACROBLOCKD *const xd = &x->e_mbd;
6254 MODE_INFO *const mi = xd->mi[0];
6255 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
6256 const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
6257 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
6258
6259 assert(yv12 != NULL);
6260
6261 // TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
6262 // use the UV scaling factors.
Yaowu Xuf883b422016-08-30 14:01:10 -07006263 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
6265 // Gets an initial list of candidate vectors from neighbours and orders them
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006266 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
6267 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07006268#if CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006269 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006270#endif // CONFIG_EXT_INTER
Sebastien Alaiwane140c502017-04-27 09:52:34 +02006271 candidates, mi_row, mi_col, NULL, NULL,
6272 mbmi_ext->mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273
6274 // Candidate refinement carried out at encoder and decoder
Yaowu Xuf883b422016-08-30 14:01:10 -07006275 av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
6276 &frame_nearest_mv[ref_frame],
6277 &frame_near_mv[ref_frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006278
Jingning Han271bb2c2016-12-14 12:34:46 -08006279// Further refinement that is encode side only to test the top few candidates
6280// in full and choose the best as the centre point for subsequent searches.
6281// The current implementation doesn't support scaling.
6282#if CONFIG_CB4X4
6283 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6284 block_size);
6285#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006286 if (!av1_is_scaled(sf) && block_size >= BLOCK_8X8)
6287 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12->y_stride, ref_frame,
6288 block_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08006289#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07006290}
6291
Urvang Joshi52648442016-10-13 17:27:51 -07006292static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
6293 BLOCK_SIZE bsize, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006294#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006295 int ref_idx,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006296#endif // CONFIG_EXT_INTER
6297 int *rate_mv) {
6298 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuf883b422016-08-30 14:01:10 -07006299 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006300 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6301 struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
6302 int bestsme = INT_MAX;
6303 int step_param;
6304 int sadpb = x->sadperbit16;
6305 MV mvp_full;
6306#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07006307#if CONFIG_COMPOUND_SINGLEREF
6308 int ref =
6309 has_second_ref(mbmi) ? mbmi->ref_frame[ref_idx] : mbmi->ref_frame[0];
6310#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07006311 int ref = mbmi->ref_frame[ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006312#endif // CONFIG_COMPOUND_SINGLEREF
6313#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07006314 int ref = mbmi->ref_frame[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006315 int ref_idx = 0;
6316#endif // CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006317 MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006318
Alex Converse0fa0f422017-04-24 12:51:14 -07006319 MvLimits tmp_mv_limits = x->mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006320 int cost_list[5];
6321
6322 const YV12_BUFFER_CONFIG *scaled_ref_frame =
Yaowu Xuf883b422016-08-30 14:01:10 -07006323 av1_get_scaled_ref_frame(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324
6325 MV pred_mv[3];
6326 pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
6327 pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
6328 pred_mv[2] = x->pred_mv[ref];
6329
Yaowu Xuc27fc142016-08-22 16:08:15 -07006330 if (scaled_ref_frame) {
6331 int i;
6332 // Swap out the reference frame for a version that's been scaled to
6333 // match the resolution of the current frame, allowing the existing
6334 // motion search code to be used without additional modifications.
6335 for (i = 0; i < MAX_MB_PLANE; i++)
6336 backup_yv12[i] = xd->plane[i].pre[ref_idx];
6337
Yaowu Xuf883b422016-08-30 14:01:10 -07006338 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006339 }
6340
Alex Converse0fa0f422017-04-24 12:51:14 -07006341 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006342
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006343 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
Yaowu Xu4306b6e2016-09-27 12:55:32 -07006344
Yaowu Xuc27fc142016-08-22 16:08:15 -07006345 // Work out the size of the first step in the mv step search.
Yaowu Xuf883b422016-08-30 14:01:10 -07006346 // 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
Yaowu Xuc27fc142016-08-22 16:08:15 -07006347 if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
6348 // Take wtd average of the step_params based on the last frame's
6349 // max mv magnitude and that based on the best ref mvs of the current
6350 // block for the given reference.
6351 step_param =
Yaowu Xuf883b422016-08-30 14:01:10 -07006352 (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
Yaowu Xuc27fc142016-08-22 16:08:15 -07006353 2;
6354 } else {
6355 step_param = cpi->mv_step_param;
6356 }
6357
6358 if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size) {
6359 int boffset =
6360 2 * (b_width_log2_lookup[cm->sb_size] -
Yaowu Xuf883b422016-08-30 14:01:10 -07006361 AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
6362 step_param = AOMMAX(step_param, boffset);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006363 }
6364
6365 if (cpi->sf.adaptive_motion_search) {
6366 int bwl = b_width_log2_lookup[bsize];
6367 int bhl = b_height_log2_lookup[bsize];
6368 int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
6369
6370 if (tlevel < 5) step_param += 2;
6371
6372 // prev_mv_sad is not setup for dynamically scaled frames.
6373 if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
6374 int i;
6375 for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
6376 if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
6377 x->pred_mv[ref].row = 0;
6378 x->pred_mv[ref].col = 0;
6379 x->best_mv.as_int = INVALID_MV;
6380
6381 if (scaled_ref_frame) {
Urvang Joshi454280d2016-10-14 16:51:44 -07006382 int j;
6383 for (j = 0; j < MAX_MB_PLANE; ++j)
6384 xd->plane[j].pre[ref_idx] = backup_yv12[j];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006385 }
6386 return;
6387 }
6388 }
6389 }
6390 }
6391
Alex Converse0fa0f422017-04-24 12:51:14 -07006392 av1_set_mv_search_range(&x->mv_limits, &ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006393
Yue Chene9638cc2016-10-10 12:37:54 -07006394#if CONFIG_MOTION_VAR
6395 if (mbmi->motion_mode != SIMPLE_TRANSLATION)
6396 mvp_full = mbmi->mv[0].as_mv;
6397 else
6398#endif // CONFIG_MOTION_VAR
6399 mvp_full = pred_mv[x->mv_best_ref_index[ref]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006400
6401 mvp_full.col >>= 3;
6402 mvp_full.row >>= 3;
6403
6404 x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
6405
Yue Chene9638cc2016-10-10 12:37:54 -07006406#if CONFIG_MOTION_VAR
6407 switch (mbmi->motion_mode) {
6408 case SIMPLE_TRANSLATION:
6409#endif // CONFIG_MOTION_VAR
6410 bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
6411 sadpb, cond_cost_list(cpi, cost_list),
6412 &ref_mv, INT_MAX, 1);
6413#if CONFIG_MOTION_VAR
6414 break;
6415 case OBMC_CAUSAL:
6416 bestsme = av1_obmc_full_pixel_diamond(
6417 cpi, x, &mvp_full, step_param, sadpb,
6418 MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
6419 &(x->best_mv.as_mv), 0);
6420 break;
James Zern88896732017-06-23 15:55:09 -07006421 default: assert(0 && "Invalid motion mode!\n");
Yue Chene9638cc2016-10-10 12:37:54 -07006422 }
6423#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006424
Alex Converse0fa0f422017-04-24 12:51:14 -07006425 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006426
6427 if (bestsme < INT_MAX) {
6428 int dis; /* TODO: use dis in distortion calculation later. */
Yue Chene9638cc2016-10-10 12:37:54 -07006429#if CONFIG_MOTION_VAR
6430 switch (mbmi->motion_mode) {
6431 case SIMPLE_TRANSLATION:
6432#endif // CONFIG_MOTION_VAR
6433 if (cpi->sf.use_upsampled_references) {
6434 int best_mv_var;
6435 const int try_second = x->second_best_mv.as_int != INVALID_MV &&
6436 x->second_best_mv.as_int != x->best_mv.as_int;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006437 const int pw = block_size_wide[bsize];
6438 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006439
Yue Chene9638cc2016-10-10 12:37:54 -07006440 best_mv_var = cpi->find_fractional_mv_step(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006441 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6442 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6443 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01006444 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
6445#if CONFIG_EXT_INTER
6446 NULL, 0, 0,
6447#endif
6448 pw, ph, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006449
Yue Chene9638cc2016-10-10 12:37:54 -07006450 if (try_second) {
Alex Converse0fa0f422017-04-24 12:51:14 -07006451 const int minc =
6452 AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
6453 const int maxc =
6454 AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
6455 const int minr =
6456 AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
6457 const int maxr =
6458 AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
Yue Chene9638cc2016-10-10 12:37:54 -07006459 int this_var;
6460 MV best_mv = x->best_mv.as_mv;
6461
6462 x->best_mv = x->second_best_mv;
6463 if (x->best_mv.as_mv.row * 8 <= maxr &&
6464 x->best_mv.as_mv.row * 8 >= minr &&
6465 x->best_mv.as_mv.col * 8 <= maxc &&
6466 x->best_mv.as_mv.col * 8 >= minc) {
6467 this_var = cpi->find_fractional_mv_step(
6468 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6469 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6470 cpi->sf.mv.subpel_iters_per_step,
6471 cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
David Barkerc155e012017-05-11 13:54:54 +01006472 &dis, &x->pred_sse[ref], NULL,
6473#if CONFIG_EXT_INTER
6474 NULL, 0, 0,
6475#endif
6476 pw, ph, 1);
Yue Chene9638cc2016-10-10 12:37:54 -07006477 if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
6478 x->best_mv.as_mv = best_mv;
6479 }
6480 }
Yue Chene9638cc2016-10-10 12:37:54 -07006481 } else {
6482 cpi->find_fractional_mv_step(
6483 x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
6484 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6485 cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
David Barkerc155e012017-05-11 13:54:54 +01006486 x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
6487#if CONFIG_EXT_INTER
6488 NULL, 0, 0,
6489#endif
6490 0, 0, 0);
Yue Chene9638cc2016-10-10 12:37:54 -07006491 }
6492#if CONFIG_MOTION_VAR
6493 break;
6494 case OBMC_CAUSAL:
6495 av1_find_best_obmc_sub_pixel_tree_up(
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006496 x, &x->best_mv.as_mv, &ref_mv, cm->allow_high_precision_mv,
6497 x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
6498 cpi->sf.mv.subpel_iters_per_step, x->nmvjointcost, x->mvcost, &dis,
6499 &x->pred_sse[ref], 0, cpi->sf.use_upsampled_references);
Yue Chene9638cc2016-10-10 12:37:54 -07006500 break;
James Zern88896732017-06-23 15:55:09 -07006501 default: assert(0 && "Invalid motion mode!\n");
Yaowu Xuc27fc142016-08-22 16:08:15 -07006502 }
Yue Chene9638cc2016-10-10 12:37:54 -07006503#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07006504 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006505 *rate_mv = av1_mv_bit_cost(&x->best_mv.as_mv, &ref_mv, x->nmvjointcost,
6506 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006507
Yue Chene9638cc2016-10-10 12:37:54 -07006508#if CONFIG_MOTION_VAR
6509 if (cpi->sf.adaptive_motion_search && mbmi->motion_mode == SIMPLE_TRANSLATION)
6510#else
6511 if (cpi->sf.adaptive_motion_search)
6512#endif // CONFIG_MOTION_VAR
6513 x->pred_mv[ref] = x->best_mv.as_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006514
6515 if (scaled_ref_frame) {
6516 int i;
6517 for (i = 0; i < MAX_MB_PLANE; i++)
6518 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6519 }
6520}
6521
David Barkerac37fa32016-12-02 12:30:21 +00006522static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006523 int i;
6524 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00006525 xd->plane[i].dst.buf = dst.plane[i];
6526 xd->plane[i].dst.stride = dst.stride[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006527 }
6528}
6529
Yaowu Xuc27fc142016-08-22 16:08:15 -07006530#if CONFIG_EXT_INTER
David Barker8dd9b572017-05-12 16:31:38 +01006531static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x,
David Barkerf19f35f2017-05-22 16:33:22 +01006532 BLOCK_SIZE bsize, const MV *other_mv,
David Barker8dd9b572017-05-12 16:31:38 +01006533 int mi_row, int mi_col, const int block,
6534 int ref_idx, uint8_t *second_pred) {
6535 const AV1_COMMON *const cm = &cpi->common;
6536 const int pw = block_size_wide[bsize];
6537 const int ph = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006538 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006539 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07006540#if CONFIG_COMPOUND_SINGLEREF
6541 const int other_ref =
6542 has_second_ref(mbmi) ? mbmi->ref_frame[!ref_idx] : mbmi->ref_frame[0];
6543#else // !CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006544 const int other_ref = mbmi->ref_frame[!ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006545#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006546 struct scale_factors sf;
6547#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6548 struct macroblockd_plane *const pd = &xd->plane[0];
6549 // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
6550 const int ic = block & 1;
6551 const int ir = (block - ic) >> 1;
6552 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
6553 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
6554#if CONFIG_GLOBAL_MOTION
6555 WarpedMotionParams *const wm = &xd->global_motion[other_ref];
6556 int is_global = is_global_mv_block(xd->mi[0], block, wm->wmtype);
6557#endif // CONFIG_GLOBAL_MOTION
6558#else
6559 (void)block;
6560#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07006561
Zoe Liu85b66462017-04-20 14:28:19 -07006562// This function should only ever be called for compound modes
6563#if CONFIG_COMPOUND_SINGLEREF
6564 assert(has_second_ref(mbmi) || is_inter_singleref_comp_mode(mbmi->mode));
6565#else // !CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006566 assert(has_second_ref(mbmi));
Zoe Liu85b66462017-04-20 14:28:19 -07006567#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07006568
David Barker8dd9b572017-05-12 16:31:38 +01006569 struct buf_2d backup_yv12[MAX_MB_PLANE];
6570 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
6571 av1_get_scaled_ref_frame(cpi, other_ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006572
6573 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01006574 int i;
6575 // Swap out the reference frame for a version that's been scaled to
6576 // match the resolution of the current frame, allowing the existing
6577 // motion search code to be used without additional modifications.
6578 for (i = 0; i < MAX_MB_PLANE; i++)
6579 backup_yv12[i] = xd->plane[i].pre[!ref_idx];
6580 av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
6581 }
6582
6583// Since we have scaled the reference frames to match the size of the current
6584// frame we must use a unit scaling factor during mode selection.
6585#if CONFIG_HIGHBITDEPTH
6586 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
6587 cm->height, cm->use_highbitdepth);
6588#else
6589 av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
6590 cm->height);
6591#endif // CONFIG_HIGHBITDEPTH
6592
6593 struct buf_2d ref_yv12;
6594
6595 const int plane = 0;
David Barkere64d51a2017-06-09 14:52:42 +01006596 ConvolveParams conv_params = get_conv_params(!ref_idx, 0, plane);
David Barker8dd9b572017-05-12 16:31:38 +01006597#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6598 WarpTypesAllowed warp_types;
6599#if CONFIG_GLOBAL_MOTION
6600 warp_types.global_warp_allowed = is_global;
6601#endif // CONFIG_GLOBAL_MOTION
6602#if CONFIG_WARPED_MOTION
6603 warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
6604#endif // CONFIG_WARPED_MOTION
6605#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6606
6607 // Initialized here because of compiler problem in Visual Studio.
6608 ref_yv12 = xd->plane[plane].pre[!ref_idx];
6609
6610// Get the prediction block from the 'other' reference frame.
6611#if CONFIG_HIGHBITDEPTH
6612 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6613 av1_highbd_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01006614 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
David Barkere64d51a2017-06-09 14:52:42 +01006615 0, mbmi->interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01006616#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6617 &warp_types, p_col, p_row,
6618#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6619 plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
6620 } else {
6621#endif // CONFIG_HIGHBITDEPTH
6622 av1_build_inter_predictor(
David Barkerf19f35f2017-05-22 16:33:22 +01006623 ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
David Barkere64d51a2017-06-09 14:52:42 +01006624 &conv_params, mbmi->interp_filter,
David Barker8dd9b572017-05-12 16:31:38 +01006625#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6626 &warp_types, p_col, p_row, plane, !ref_idx,
6627#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
6628 MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
6629#if CONFIG_HIGHBITDEPTH
6630 }
6631#endif // CONFIG_HIGHBITDEPTH
6632
6633 if (scaled_ref_frame) {
6634 // Restore the prediction frame pointers to their unscaled versions.
6635 int i;
6636 for (i = 0; i < MAX_MB_PLANE; i++)
6637 xd->plane[i].pre[!ref_idx] = backup_yv12[i];
6638 }
6639}
6640
6641// Search for the best mv for one component of a compound,
6642// given that the other component is fixed.
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006643static void compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
6644 BLOCK_SIZE bsize, MV *this_mv,
6645 int mi_row, int mi_col,
6646 const uint8_t *second_pred,
6647 const uint8_t *mask, int mask_stride,
6648 int *rate_mv, int ref_idx) {
David Barker8dd9b572017-05-12 16:31:38 +01006649 const int pw = block_size_wide[bsize];
6650 const int ph = block_size_high[bsize];
6651 MACROBLOCKD *xd = &x->e_mbd;
6652 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Zoe Liu85b66462017-04-20 14:28:19 -07006653#if CONFIG_COMPOUND_SINGLEREF
6654 const int ref =
6655 has_second_ref(mbmi) ? mbmi->ref_frame[ref_idx] : mbmi->ref_frame[0];
6656#else
David Barker8dd9b572017-05-12 16:31:38 +01006657 const int ref = mbmi->ref_frame[ref_idx];
Zoe Liu85b66462017-04-20 14:28:19 -07006658#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006659 int_mv ref_mv = x->mbmi_ext->ref_mvs[ref][0];
David Barker8dd9b572017-05-12 16:31:38 +01006660 struct macroblockd_plane *const pd = &xd->plane[0];
6661
6662 struct buf_2d backup_yv12[MAX_MB_PLANE];
David Barker8dd9b572017-05-12 16:31:38 +01006663 const YV12_BUFFER_CONFIG *const scaled_ref_frame =
6664 av1_get_scaled_ref_frame(cpi, ref);
6665
Ryan Lei1d1df182017-06-15 11:38:59 -07006666// Check that this is either an interinter or an interintra block
Zoe Liu85b66462017-04-20 14:28:19 -07006667#if CONFIG_COMPOUND_SINGLEREF
Ryan Lei1d1df182017-06-15 11:38:59 -07006668 assert(has_second_ref(mbmi) ||
Zoe Liu85b66462017-04-20 14:28:19 -07006669 // or a single ref comp pred mode
6670 is_inter_singleref_comp_mode(mbmi->mode) ||
David Barker8dd9b572017-05-12 16:31:38 +01006671 (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
Ryan Lei1d1df182017-06-15 11:38:59 -07006672#else
6673 assert(has_second_ref(mbmi) ||
6674 (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
6675#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006676
David Barker8dd9b572017-05-12 16:31:38 +01006677 if (scaled_ref_frame) {
6678 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006679 // Swap out the reference frame for a version that's been scaled to
6680 // match the resolution of the current frame, allowing the existing
6681 // motion search code to be used without additional modifications.
6682 for (i = 0; i < MAX_MB_PLANE; i++)
6683 backup_yv12[i] = xd->plane[i].pre[ref_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -07006684 av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006685 }
6686
David Barker8dd9b572017-05-12 16:31:38 +01006687 struct buf_2d orig_yv12;
6688 int bestsme = INT_MAX;
6689 int sadpb = x->sadperbit16;
6690 MV *const best_mv = &x->best_mv.as_mv;
6691 int search_range = 3;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006692
David Barker8dd9b572017-05-12 16:31:38 +01006693 MvLimits tmp_mv_limits = x->mv_limits;
David Barker8dd9b572017-05-12 16:31:38 +01006694
6695 // Initialized here because of compiler problem in Visual Studio.
6696 if (ref_idx) {
David Barkerf19f35f2017-05-22 16:33:22 +01006697 orig_yv12 = pd->pre[0];
6698 pd->pre[0] = pd->pre[ref_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006699 }
6700
David Barker8dd9b572017-05-12 16:31:38 +01006701 // Do compound motion search on the current reference frame.
6702 av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
6703
6704 // Use the mv result from the single mode as mv predictor.
David Barkerf19f35f2017-05-22 16:33:22 +01006705 *best_mv = *this_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006706
6707 best_mv->col >>= 3;
6708 best_mv->row >>= 3;
6709
Zoe Liu85b66462017-04-20 14:28:19 -07006710#if CONFIG_COMPOUND_SINGLEREF
6711 if (!has_second_ref(mbmi))
6712 av1_set_mvcost(x, ref, 0, mbmi->ref_mv_idx);
6713 else
6714#endif // CONFIG_COMPOUND_SINGLEREF
6715 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
David Barker8dd9b572017-05-12 16:31:38 +01006716
6717 // Small-range full-pixel motion search.
6718 bestsme = av1_refining_search_8p_c(x, sadpb, search_range,
6719 &cpi->fn_ptr[bsize], mask, mask_stride,
6720 ref_idx, &ref_mv.as_mv, second_pred);
6721 if (bestsme < INT_MAX) {
6722 if (mask)
6723 bestsme =
6724 av1_get_mvpred_mask_var(x, best_mv, &ref_mv.as_mv, second_pred, mask,
6725 mask_stride, ref_idx, &cpi->fn_ptr[bsize], 1);
6726 else
6727 bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv.as_mv, second_pred,
6728 &cpi->fn_ptr[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006729 }
6730
Alex Converse0fa0f422017-04-24 12:51:14 -07006731 x->mv_limits = tmp_mv_limits;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006732
6733 if (bestsme < INT_MAX) {
6734 int dis; /* TODO: use dis in distortion calculation later. */
David Barker8dd9b572017-05-12 16:31:38 +01006735 unsigned int sse;
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006736 bestsme = cpi->find_fractional_mv_step(
6737 x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
6738 &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
6739 x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask, mask_stride,
6740 ref_idx, pw, ph, cpi->sf.use_upsampled_references);
David Barker8dd9b572017-05-12 16:31:38 +01006741 }
6742
6743 // Restore the pointer to the first (possibly scaled) prediction buffer.
David Barkerf19f35f2017-05-22 16:33:22 +01006744 if (ref_idx) pd->pre[0] = orig_yv12;
David Barker8dd9b572017-05-12 16:31:38 +01006745
Yue Chenf03907a2017-05-31 12:04:04 -07006746 if (bestsme < INT_MAX) *this_mv = *best_mv;
David Barker8dd9b572017-05-12 16:31:38 +01006747
6748 *rate_mv = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006749
6750 if (scaled_ref_frame) {
David Barker8dd9b572017-05-12 16:31:38 +01006751 // Restore the prediction frame pointers to their unscaled versions.
6752 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006753 for (i = 0; i < MAX_MB_PLANE; i++)
6754 xd->plane[i].pre[ref_idx] = backup_yv12[i];
6755 }
David Barker8dd9b572017-05-12 16:31:38 +01006756
Zoe Liu85b66462017-04-20 14:28:19 -07006757#if CONFIG_COMPOUND_SINGLEREF
6758 if (!has_second_ref(mbmi))
6759 av1_set_mvcost(x, ref, 0, mbmi->ref_mv_idx);
6760 else
6761#endif // CONFIG_COMPOUND_SINGLEREF
6762 av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
David Barkerf19f35f2017-05-22 16:33:22 +01006763 *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmvjointcost,
6764 x->mvcost, MV_COST_WEIGHT);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006765}
6766
David Barker8dd9b572017-05-12 16:31:38 +01006767// Wrapper for compound_single_motion_search, for the common case
6768// where the second prediction is also an inter mode.
6769static void compound_single_motion_search_interinter(
6770 const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *frame_mv,
Zoe Liu85b66462017-04-20 14:28:19 -07006771#if CONFIG_COMPOUND_SINGLEREF
6772 int_mv *frame_comp_mv,
6773#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006774 int mi_row, int mi_col, const uint8_t *mask, int mask_stride, int *rate_mv,
6775 const int block, int ref_idx) {
6776 MACROBLOCKD *xd = &x->e_mbd;
6777 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6778
Zoe Liu85b66462017-04-20 14:28:19 -07006779// This function should only ever be called for compound modes
6780#if CONFIG_COMPOUND_SINGLEREF
6781 int is_singleref_comp_mode =
6782 !has_second_ref(mbmi) && is_inter_singleref_comp_mode(mbmi->mode);
6783 assert(has_second_ref(mbmi) || is_singleref_comp_mode);
6784 if (is_singleref_comp_mode && ref_idx) assert(frame_comp_mv);
6785#else // !CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006786 assert(has_second_ref(mbmi));
Zoe Liu85b66462017-04-20 14:28:19 -07006787#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006788
6789// Prediction buffer from second frame.
6790#if CONFIG_HIGHBITDEPTH
David Barker8dd9b572017-05-12 16:31:38 +01006791 DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
6792 uint8_t *second_pred;
6793 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
6794 second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
6795 else
6796 second_pred = (uint8_t *)second_pred_alloc_16;
6797#else
6798 DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
6799#endif // CONFIG_HIGHBITDEPTH
6800
Zoe Liu85b66462017-04-20 14:28:19 -07006801#if CONFIG_COMPOUND_SINGLEREF
6802 MV *this_mv = has_second_ref(mbmi)
6803 ? &frame_mv[mbmi->ref_frame[ref_idx]].as_mv
6804 : (ref_idx ? &frame_comp_mv[mbmi->ref_frame[0]].as_mv
6805 : &frame_mv[mbmi->ref_frame[0]].as_mv);
6806 const MV *other_mv =
6807 has_second_ref(mbmi)
6808 ? &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv
6809 : (ref_idx ? &frame_mv[mbmi->ref_frame[0]].as_mv
6810 : &frame_comp_mv[mbmi->ref_frame[0]].as_mv);
6811#else // !CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006812 MV *this_mv = &frame_mv[mbmi->ref_frame[ref_idx]].as_mv;
6813 const MV *other_mv = &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv;
Zoe Liu85b66462017-04-20 14:28:19 -07006814#endif // CONFIG_COMPOUND_SINGLEREF
David Barkerf19f35f2017-05-22 16:33:22 +01006815
6816 build_second_inter_pred(cpi, x, bsize, other_mv, mi_row, mi_col, block,
David Barker8dd9b572017-05-12 16:31:38 +01006817 ref_idx, second_pred);
6818
David Barkerf19f35f2017-05-22 16:33:22 +01006819 compound_single_motion_search(cpi, x, bsize, this_mv, mi_row, mi_col,
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07006820 second_pred, mask, mask_stride, rate_mv,
David Barkerf19f35f2017-05-22 16:33:22 +01006821 ref_idx);
David Barker8dd9b572017-05-12 16:31:38 +01006822}
6823
6824#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08006825static void do_masked_motion_search_indexed(
David Barkerc155e012017-05-11 13:54:54 +01006826 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006827 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006828 int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006829 // NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
6830 MACROBLOCKD *xd = &x->e_mbd;
6831 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6832 BLOCK_SIZE sb_type = mbmi->sb_type;
6833 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -08006834 const int mask_stride = block_size_wide[bsize];
Sarah Parker569edda2016-12-14 14:57:38 -08006835
Sarah Parkerb9f757c2017-01-06 17:12:24 -08006836 mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006837
David Barker8dd9b572017-05-12 16:31:38 +01006838 int_mv frame_mv[TOTAL_REFS_PER_FRAME];
Zoe Liu85b66462017-04-20 14:28:19 -07006839#if CONFIG_COMPOUND_SINGLEREF
6840 int_mv frame_comp_mv[TOTAL_REFS_PER_FRAME];
6841#endif // CONFIG_COMPOUND_SINGLEREF
David Barker8dd9b572017-05-12 16:31:38 +01006842 MV_REFERENCE_FRAME rf[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
6843 assert(bsize >= BLOCK_8X8 || CONFIG_CB4X4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006844
David Barker8dd9b572017-05-12 16:31:38 +01006845 frame_mv[rf[0]].as_int = cur_mv[0].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07006846#if CONFIG_COMPOUND_SINGLEREF
6847 if (!has_second_ref(mbmi))
6848 frame_comp_mv[rf[0]].as_int = cur_mv[1].as_int;
6849 else
6850#endif // CONFIG_COMPOUND_SINGLEREF
6851 frame_mv[rf[1]].as_int = cur_mv[1].as_int;
David Barkerf19f35f2017-05-22 16:33:22 +01006852 if (which == 0 || which == 1) {
Zoe Liu85b66462017-04-20 14:28:19 -07006853 compound_single_motion_search_interinter(
6854 cpi, x, bsize, frame_mv,
6855#if CONFIG_COMPOUND_SINGLEREF
6856 has_second_ref(mbmi) ? NULL : frame_comp_mv,
6857#endif // CONFIG_COMPOUND_SINGLEREF
6858 mi_row, mi_col, mask, mask_stride, rate_mv, 0, which);
David Barkerf19f35f2017-05-22 16:33:22 +01006859 } else if (which == 2) {
Zoe Liu85b66462017-04-20 14:28:19 -07006860 joint_motion_search(cpi, x, bsize, frame_mv,
6861#if CONFIG_COMPOUND_SINGLEREF
6862 has_second_ref(mbmi) ? NULL : frame_comp_mv,
6863#endif // CONFIG_COMPOUND_SINGLEREF
6864 mi_row, mi_col, NULL, mask, mask_stride, rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006865 }
David Barker8dd9b572017-05-12 16:31:38 +01006866 tmp_mv[0].as_int = frame_mv[rf[0]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07006867#if CONFIG_COMPOUND_SINGLEREF
6868 if (!has_second_ref(mbmi))
6869 tmp_mv[1].as_int = frame_comp_mv[rf[0]].as_int;
6870 else // comp ref
6871#endif // CONFIG_COMPOUND_SINGLEREF
6872 tmp_mv[1].as_int = frame_mv[rf[1]].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006873}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006874#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006875#endif // CONFIG_EXT_INTER
6876
6877// In some situations we want to discount tha pparent cost of a new motion
6878// vector. Where there is a subtle motion field and especially where there is
6879// low spatial complexity then it can be hard to cover the cost of a new motion
6880// vector in a single block, even if that motion vector reduces distortion.
6881// However, once established that vector may be usable through the nearest and
6882// near mv modes to reduce distortion in subsequent blocks and also improve
6883// visual quality.
Urvang Joshi52648442016-10-13 17:27:51 -07006884static int discount_newmv_test(const AV1_COMP *const cpi, int this_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006885 int_mv this_mv,
6886 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
6887 int ref_frame) {
6888 return (!cpi->rc.is_src_frame_alt_ref && (this_mode == NEWMV) &&
6889 (this_mv.as_int != 0) &&
6890 ((mode_mv[NEARESTMV][ref_frame].as_int == 0) ||
6891 (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) &&
6892 ((mode_mv[NEARMV][ref_frame].as_int == 0) ||
6893 (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV)));
6894}
6895
Yaowu Xu671f2bd2016-09-30 15:07:57 -07006896#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
6897#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006898
6899// TODO(jingning): this mv clamping function should be block size dependent.
6900static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
6901 clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
6902 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
6903 xd->mb_to_top_edge - LEFT_TOP_MARGIN,
6904 xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
6905}
6906
6907#if CONFIG_EXT_INTER
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006908#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07006909static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006910 const BLOCK_SIZE bsize, const uint8_t *pred0,
6911 int stride0, const uint8_t *pred1, int stride1) {
6912 const struct macroblock_plane *const p = &x->plane[0];
6913 const uint8_t *src = p->src.buf;
6914 int src_stride = p->src.stride;
6915 const int f_index = bsize - BLOCK_8X8;
Jingning Han61418bb2017-01-23 17:12:48 -08006916 const int bw = block_size_wide[bsize];
6917 const int bh = block_size_high[bsize];
Yue Chenf03907a2017-05-31 12:04:04 -07006918 uint32_t esq[2][4];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006919 int64_t tl, br;
6920
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006921#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006922 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6923 pred0 = CONVERT_TO_BYTEPTR(pred0);
6924 pred1 = CONVERT_TO_BYTEPTR(pred1);
6925 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02006926#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006927
Yue Chenf03907a2017-05-31 12:04:04 -07006928 cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
6929 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2, stride0,
6930 &esq[0][1]);
6931 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6932 pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
6933 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6934 pred0 + bh / 2 * stride0 + bw / 2, stride0,
6935 &esq[0][3]);
6936 cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
6937 cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2, stride1,
6938 &esq[1][1]);
6939 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
6940 pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
6941 cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
6942 pred1 + bh / 2 * stride1 + bw / 2, stride0,
6943 &esq[1][3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006944
6945 tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
6946 (int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
6947 br = (int64_t)(esq[1][3] + esq[1][1] + esq[1][2]) -
6948 (int64_t)(esq[0][3] + esq[0][1] + esq[0][2]);
6949 return (tl + br > 0);
6950}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00006951#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07006952#endif // CONFIG_EXT_INTER
6953
6954#if !CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -07006955static InterpFilter predict_interp_filter(
Yaowu Xuf883b422016-08-30 14:01:10 -07006956 const AV1_COMP *cpi, const MACROBLOCK *x, const BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006957 const int mi_row, const int mi_col,
James Zern7b9407a2016-05-18 23:48:05 -07006958 InterpFilter (*single_filter)[TOTAL_REFS_PER_FRAME]) {
6959 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006960 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006961 const MACROBLOCKD *xd = &x->e_mbd;
6962 int bsl = mi_width_log2_lookup[bsize];
6963 int pred_filter_search =
6964 cpi->sf.cb_pred_filter_search
6965 ? (((mi_row + mi_col) >> bsl) +
6966 get_chessboard_index(cm->current_video_frame)) &
6967 0x1
6968 : 0;
6969 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6970 const int is_comp_pred = has_second_ref(mbmi);
6971 const int this_mode = mbmi->mode;
6972 int refs[2] = { mbmi->ref_frame[0],
6973 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
Yaowu Xuc27fc142016-08-22 16:08:15 -07006974 if (pred_filter_search) {
James Zern7b9407a2016-05-18 23:48:05 -07006975 InterpFilter af = SWITCHABLE, lf = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006976 if (xd->up_available) af = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
6977 if (xd->left_available) lf = xd->mi[-1]->mbmi.interp_filter;
6978
6979#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -07006980 if ((this_mode != NEWMV && this_mode != NEW_NEWMV) || (af == lf))
Yaowu Xuc27fc142016-08-22 16:08:15 -07006981#else
6982 if ((this_mode != NEWMV) || (af == lf))
6983#endif // CONFIG_EXT_INTER
6984 best_filter = af;
6985 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006986 if (is_comp_pred) {
6987 if (cpi->sf.adaptive_mode_search) {
6988#if CONFIG_EXT_INTER
6989 switch (this_mode) {
6990 case NEAREST_NEARESTMV:
6991 if (single_filter[NEARESTMV][refs[0]] ==
6992 single_filter[NEARESTMV][refs[1]])
6993 best_filter = single_filter[NEARESTMV][refs[0]];
6994 break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006995 case NEAR_NEARMV:
6996 if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
6997 best_filter = single_filter[NEARMV][refs[0]];
6998 break;
6999 case ZERO_ZEROMV:
7000 if (single_filter[ZEROMV][refs[0]] == single_filter[ZEROMV][refs[1]])
7001 best_filter = single_filter[ZEROMV][refs[0]];
7002 break;
7003 case NEW_NEWMV:
7004 if (single_filter[NEWMV][refs[0]] == single_filter[NEWMV][refs[1]])
7005 best_filter = single_filter[NEWMV][refs[0]];
7006 break;
7007 case NEAREST_NEWMV:
7008 if (single_filter[NEARESTMV][refs[0]] ==
7009 single_filter[NEWMV][refs[1]])
7010 best_filter = single_filter[NEARESTMV][refs[0]];
7011 break;
7012 case NEAR_NEWMV:
7013 if (single_filter[NEARMV][refs[0]] == single_filter[NEWMV][refs[1]])
7014 best_filter = single_filter[NEARMV][refs[0]];
7015 break;
7016 case NEW_NEARESTMV:
7017 if (single_filter[NEWMV][refs[0]] ==
7018 single_filter[NEARESTMV][refs[1]])
7019 best_filter = single_filter[NEWMV][refs[0]];
7020 break;
7021 case NEW_NEARMV:
7022 if (single_filter[NEWMV][refs[0]] == single_filter[NEARMV][refs[1]])
7023 best_filter = single_filter[NEWMV][refs[0]];
7024 break;
7025 default:
7026 if (single_filter[this_mode][refs[0]] ==
7027 single_filter[this_mode][refs[1]])
7028 best_filter = single_filter[this_mode][refs[0]];
7029 break;
7030 }
7031#else
7032 if (single_filter[this_mode][refs[0]] ==
7033 single_filter[this_mode][refs[1]])
7034 best_filter = single_filter[this_mode][refs[0]];
7035#endif // CONFIG_EXT_INTER
7036 }
7037 }
Angie Chiang75c22092016-10-25 12:19:16 -07007038 if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
7039 best_filter = EIGHTTAP_REGULAR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007040 }
7041 return best_filter;
7042}
Fergus Simpson4063a682017-02-28 16:52:22 -08007043#endif // !CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07007044
7045#if CONFIG_EXT_INTER
7046// Choose the best wedge index and sign
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007047#if CONFIG_WEDGE
Yaowu Xuf883b422016-08-30 14:01:10 -07007048static int64_t pick_wedge(const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007049 const BLOCK_SIZE bsize, const uint8_t *const p0,
7050 const uint8_t *const p1, int *const best_wedge_sign,
7051 int *const best_wedge_index) {
7052 const MACROBLOCKD *const xd = &x->e_mbd;
7053 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007054 const int bw = block_size_wide[bsize];
7055 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007056 const int N = bw * bh;
7057 int rate;
7058 int64_t dist;
7059 int64_t rd, best_rd = INT64_MAX;
7060 int wedge_index;
7061 int wedge_sign;
7062 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7063 const uint8_t *mask;
7064 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007065#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007066 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7067 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7068#else
7069 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007070#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007071
7072 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7073 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7074 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7075 DECLARE_ALIGNED(32, int16_t, ds[MAX_SB_SQUARE]);
7076
7077 int64_t sign_limit;
7078
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007079#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007080 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007081 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007082 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007083 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007084 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007085 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007086 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7087 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007088#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007089 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007090 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7091 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7092 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007093 }
7094
Yaowu Xuf883b422016-08-30 14:01:10 -07007095 sign_limit = ((int64_t)aom_sum_squares_i16(r0, N) -
7096 (int64_t)aom_sum_squares_i16(r1, N)) *
Yaowu Xuc27fc142016-08-22 16:08:15 -07007097 (1 << WEDGE_WEIGHT_BITS) / 2;
7098
Jingning Han61418bb2017-01-23 17:12:48 -08007099 if (N < 64)
7100 av1_wedge_compute_delta_squares_c(ds, r0, r1, N);
7101 else
7102 av1_wedge_compute_delta_squares(ds, r0, r1, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007103
7104 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007105 mask = av1_get_contiguous_soft_mask(wedge_index, 0, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007106
7107 // TODO(jingning): Make sse2 functions support N = 16 case
7108 if (N < 64)
7109 wedge_sign = av1_wedge_sign_from_residuals_c(ds, mask, N, sign_limit);
7110 else
7111 wedge_sign = av1_wedge_sign_from_residuals(ds, mask, N, sign_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007112
Yaowu Xuf883b422016-08-30 14:01:10 -07007113 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007114 if (N < 64)
7115 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7116 else
7117 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007118 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7119
7120 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007121 rd = RDCOST(x->rdmult, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007122
7123 if (rd < best_rd) {
7124 *best_wedge_index = wedge_index;
7125 *best_wedge_sign = wedge_sign;
7126 best_rd = rd;
7127 }
7128 }
7129
7130 return best_rd;
7131}
7132
7133// Choose the best wedge index the specified sign
7134static int64_t pick_wedge_fixed_sign(
Yaowu Xuf883b422016-08-30 14:01:10 -07007135 const AV1_COMP *const cpi, const MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007136 const BLOCK_SIZE bsize, const uint8_t *const p0, const uint8_t *const p1,
7137 const int wedge_sign, int *const best_wedge_index) {
7138 const MACROBLOCKD *const xd = &x->e_mbd;
7139 const struct buf_2d *const src = &x->plane[0].src;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007140 const int bw = block_size_wide[bsize];
7141 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007142 const int N = bw * bh;
7143 int rate;
7144 int64_t dist;
7145 int64_t rd, best_rd = INT64_MAX;
7146 int wedge_index;
7147 int wedge_types = (1 << get_wedge_bits_lookup(bsize));
7148 const uint8_t *mask;
7149 uint64_t sse;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007150#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007151 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7152 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7153#else
7154 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007155#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007156
7157 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7158 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7159
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007160#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007161 if (hbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007162 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007163 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
Yaowu Xuf883b422016-08-30 14:01:10 -07007164 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007165 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7166 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007167#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07007168 {
Yaowu Xuf883b422016-08-30 14:01:10 -07007169 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7170 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007171 }
7172
7173 for (wedge_index = 0; wedge_index < wedge_types; ++wedge_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07007174 mask = av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Jingning Han61418bb2017-01-23 17:12:48 -08007175 if (N < 64)
7176 sse = av1_wedge_sse_from_residuals_c(r1, d10, mask, N);
7177 else
7178 sse = av1_wedge_sse_from_residuals(r1, d10, mask, N);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007179 sse = ROUND_POWER_OF_TWO(sse, bd_round);
7180
7181 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007182 rd = RDCOST(x->rdmult, rate, dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007183
7184 if (rd < best_rd) {
7185 *best_wedge_index = wedge_index;
7186 best_rd = rd;
7187 }
7188 }
7189
7190 return best_rd;
7191}
7192
Yaowu Xuf883b422016-08-30 14:01:10 -07007193static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007194 MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007195 const BLOCK_SIZE bsize,
7196 const uint8_t *const p0,
7197 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007198 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007199 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Jingning Hanae5cfde2016-11-30 12:01:44 -08007200 const int bw = block_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07007201
7202 int64_t rd;
7203 int wedge_index = -1;
7204 int wedge_sign = 0;
7205
Sarah Parker42d96102017-01-31 21:05:27 -08007206 assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007207 assert(cpi->common.allow_masked_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007208
7209 if (cpi->sf.fast_wedge_sign_estimate) {
7210 wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
7211 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, wedge_sign, &wedge_index);
7212 } else {
7213 rd = pick_wedge(cpi, x, bsize, p0, p1, &wedge_sign, &wedge_index);
7214 }
7215
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007216 mbmi->wedge_sign = wedge_sign;
7217 mbmi->wedge_index = wedge_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -07007218 return rd;
7219}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007220#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007221
Sarah Parker569edda2016-12-14 14:57:38 -08007222#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerddcea392017-04-25 15:57:22 -07007223static int64_t pick_interinter_seg(const AV1_COMP *const cpi,
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007224 MACROBLOCK *const x, const BLOCK_SIZE bsize,
Sarah Parkerddcea392017-04-25 15:57:22 -07007225 const uint8_t *const p0,
7226 const uint8_t *const p1) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007227 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker569edda2016-12-14 14:57:38 -08007228 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7229 const struct buf_2d *const src = &x->plane[0].src;
7230 const int bw = block_size_wide[bsize];
7231 const int bh = block_size_high[bsize];
7232 const int N = bw * bh;
7233 int rate;
7234 uint64_t sse;
7235 int64_t dist;
Debargha Mukherjeec30934b2017-04-25 01:23:51 -07007236 int64_t rd0;
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007237 SEG_MASK_TYPE cur_mask_type;
7238 int64_t best_rd = INT64_MAX;
7239 SEG_MASK_TYPE best_mask_type = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007240#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007241 const int hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
7242 const int bd_round = hbd ? (xd->bd - 8) * 2 : 0;
7243#else
7244 const int bd_round = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007245#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007246 DECLARE_ALIGNED(32, int16_t, r0[MAX_SB_SQUARE]);
7247 DECLARE_ALIGNED(32, int16_t, r1[MAX_SB_SQUARE]);
7248 DECLARE_ALIGNED(32, int16_t, d10[MAX_SB_SQUARE]);
7249
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007250#if CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007251 if (hbd) {
7252 aom_highbd_subtract_block(bh, bw, r0, bw, src->buf, src->stride,
7253 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7254 aom_highbd_subtract_block(bh, bw, r1, bw, src->buf, src->stride,
7255 CONVERT_TO_BYTEPTR(p1), bw, xd->bd);
7256 aom_highbd_subtract_block(bh, bw, d10, bw, CONVERT_TO_BYTEPTR(p1), bw,
7257 CONVERT_TO_BYTEPTR(p0), bw, xd->bd);
7258 } else // NOLINT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007259#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08007260 {
7261 aom_subtract_block(bh, bw, r0, bw, src->buf, src->stride, p0, bw);
7262 aom_subtract_block(bh, bw, r1, bw, src->buf, src->stride, p1, bw);
7263 aom_subtract_block(bh, bw, d10, bw, p1, bw, p0, bw);
7264 }
7265
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007266 // try each mask type and its inverse
7267 for (cur_mask_type = 0; cur_mask_type < SEG_MASK_TYPES; cur_mask_type++) {
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007268// build mask and inverse
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007269#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007270 if (hbd)
7271 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007272 xd->seg_mask, cur_mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007273 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7274 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007275#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007276 build_compound_seg_mask(xd->seg_mask, cur_mask_type, p0, bw, p1, bw,
7277 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007278
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007279 // compute rd for mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007280 sse = av1_wedge_sse_from_residuals(r1, d10, xd->seg_mask, N);
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007281 sse = ROUND_POWER_OF_TWO(sse, bd_round);
Sarah Parker569edda2016-12-14 14:57:38 -08007282
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007283 model_rd_from_sse(cpi, xd, bsize, 0, sse, &rate, &dist);
Urvang Joshi70006e42017-06-14 16:08:55 -07007284 rd0 = RDCOST(x->rdmult, rate, dist);
Sarah Parker569edda2016-12-14 14:57:38 -08007285
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007286 if (rd0 < best_rd) {
7287 best_mask_type = cur_mask_type;
7288 best_rd = rd0;
7289 }
7290 }
Sarah Parker569edda2016-12-14 14:57:38 -08007291
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007292 // make final mask
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007293 mbmi->mask_type = best_mask_type;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007294#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007295 if (hbd)
7296 build_compound_seg_mask_highbd(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007297 xd->seg_mask, mbmi->mask_type, CONVERT_TO_BYTEPTR(p0), bw,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08007298 CONVERT_TO_BYTEPTR(p1), bw, bsize, bh, bw, xd->bd);
7299 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02007300#endif // CONFIG_HIGHBITDEPTH
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007301 build_compound_seg_mask(xd->seg_mask, mbmi->mask_type, p0, bw, p1, bw,
7302 bsize, bh, bw);
Sarah Parker569edda2016-12-14 14:57:38 -08007303
Sarah Parkerb9f757c2017-01-06 17:12:24 -08007304 return best_rd;
Sarah Parker569edda2016-12-14 14:57:38 -08007305}
7306#endif // CONFIG_COMPOUND_SEGMENT
7307
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007308#if CONFIG_WEDGE && CONFIG_INTERINTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07007309static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07007310 const MACROBLOCK *const x,
7311 const BLOCK_SIZE bsize,
7312 const uint8_t *const p0,
7313 const uint8_t *const p1) {
7314 const MACROBLOCKD *const xd = &x->e_mbd;
7315 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7316
7317 int64_t rd;
7318 int wedge_index = -1;
7319
7320 assert(is_interintra_wedge_used(bsize));
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07007321 assert(cpi->common.allow_interintra_compound);
Yaowu Xuc27fc142016-08-22 16:08:15 -07007322
7323 rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
7324
7325 mbmi->interintra_wedge_sign = 0;
7326 mbmi->interintra_wedge_index = wedge_index;
7327 return rd;
7328}
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007329#endif // CONFIG_WEDGE && CONFIG_INTERINTRA
Sarah Parker6fdc8532016-11-16 17:47:13 -08007330
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00007331#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007332static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
Sarah Parkerddcea392017-04-25 15:57:22 -07007333 const BLOCK_SIZE bsize,
7334 const uint8_t *const p0,
7335 const uint8_t *const p1) {
7336 const COMPOUND_TYPE compound_type =
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007337 x->e_mbd.mi[0]->mbmi.interinter_compound_type;
Sarah Parkerddcea392017-04-25 15:57:22 -07007338 switch (compound_type) {
7339#if CONFIG_WEDGE
7340 case COMPOUND_WEDGE: return pick_interinter_wedge(cpi, x, bsize, p0, p1);
7341#endif // CONFIG_WEDGE
7342#if CONFIG_COMPOUND_SEGMENT
7343 case COMPOUND_SEG: return pick_interinter_seg(cpi, x, bsize, p0, p1);
7344#endif // CONFIG_COMPOUND_SEGMENT
7345 default: assert(0); return 0;
7346 }
7347}
7348
David Barkerc155e012017-05-11 13:54:54 +01007349static int interinter_compound_motion_search(
7350 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7351 const BLOCK_SIZE bsize, const int this_mode, int mi_row, int mi_col) {
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007352 MACROBLOCKD *const xd = &x->e_mbd;
Sarah Parker6fdc8532016-11-16 17:47:13 -08007353 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7354 int_mv tmp_mv[2];
David Barkerc155e012017-05-11 13:54:54 +01007355 int tmp_rate_mv = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007356 const INTERINTER_COMPOUND_DATA compound_data = {
7357#if CONFIG_WEDGE
7358 mbmi->wedge_index,
7359 mbmi->wedge_sign,
7360#endif // CONFIG_WEDGE
7361#if CONFIG_COMPOUND_SEGMENT
7362 mbmi->mask_type,
7363 xd->seg_mask,
7364#endif // CONFIG_COMPOUND_SEGMENT
7365 mbmi->interinter_compound_type
7366 };
Zoe Liu85b66462017-04-20 14:28:19 -07007367#if CONFIG_COMPOUND_SINGLEREF
7368 // NOTE: Mode is needed to identify the compound mode prediction, regardless
7369 // of comp refs or single ref.
7370 mbmi->mode = this_mode;
7371#endif // CONFIG_COMPOUND_SINGLEREF
7372
7373 if (this_mode == NEW_NEWMV
7374#if CONFIG_COMPOUND_SINGLEREF
7375 || this_mode == SR_NEW_NEWMV
7376#endif // CONFIG_COMPOUND_SINGLEREF
7377 ) {
David Barkerc155e012017-05-11 13:54:54 +01007378 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7379 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 2);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007380 mbmi->mv[0].as_int = tmp_mv[0].as_int;
7381 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7382 } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
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, 0);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007385 mbmi->mv[0].as_int = tmp_mv[0].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007386 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV
7387#if CONFIG_COMPOUND_SINGLEREF
7388 // || this_mode == SR_NEAREST_NEWMV
7389 || this_mode == SR_NEAR_NEWMV || this_mode == SR_ZERO_NEWMV
7390#endif // CONFIG_COMPOUND_SINGLEREF
7391 ) {
David Barkerc155e012017-05-11 13:54:54 +01007392 do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
7393 mi_row, mi_col, tmp_mv, &tmp_rate_mv, 1);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007394 mbmi->mv[1].as_int = tmp_mv[1].as_int;
7395 }
7396 return tmp_rate_mv;
7397}
7398
Sarah Parkerddcea392017-04-25 15:57:22 -07007399static int64_t build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08007400 const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
7401 const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
7402 BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
7403 int *strides, int mi_row, int mi_col) {
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007404 const AV1_COMMON *const cm = &cpi->common;
Sarah Parker569edda2016-12-14 14:57:38 -08007405 MACROBLOCKD *xd = &x->e_mbd;
7406 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7407 int rate_sum;
7408 int64_t dist_sum;
7409 int64_t best_rd_cur = INT64_MAX;
7410 int64_t rd = INT64_MAX;
7411 int tmp_skip_txfm_sb;
7412 int64_t tmp_skip_sse_sb;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00007413 const COMPOUND_TYPE compound_type = mbmi->interinter_compound_type;
Sarah Parker569edda2016-12-14 14:57:38 -08007414
Sarah Parkerddcea392017-04-25 15:57:22 -07007415 best_rd_cur = pick_interinter_mask(cpi, x, bsize, *preds0, *preds1);
Urvang Joshi70006e42017-06-14 16:08:55 -07007416 best_rd_cur += RDCOST(x->rdmult, rs2 + rate_mv, 0);
Sarah Parker569edda2016-12-14 14:57:38 -08007417
Sarah Parker2e604882017-01-17 17:31:25 -08007418 if (have_newmv_in_inter_mode(this_mode) &&
Sarah Parkerddcea392017-04-25 15:57:22 -07007419 use_masked_motion_search(compound_type)) {
David Barkerc155e012017-05-11 13:54:54 +01007420 *out_rate_mv = interinter_compound_motion_search(cpi, x, cur_mv, bsize,
7421 this_mode, mi_row, mi_col);
Debargha Mukherjeead8be032017-05-09 15:28:45 -07007422 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007423 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
7424 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07007425 rd = RDCOST(x->rdmult, rs2 + *out_rate_mv + rate_sum, dist_sum);
Zoe Liu4d44f5a2016-12-14 17:46:19 -08007426 if (rd >= best_rd_cur) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08007427 mbmi->mv[0].as_int = cur_mv[0].as_int;
7428 mbmi->mv[1].as_int = cur_mv[1].as_int;
7429 *out_rate_mv = rate_mv;
David Barker426a9972017-01-27 11:03:11 +00007430 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7431#if CONFIG_SUPERTX
7432 0, 0,
7433#endif // CONFIG_SUPERTX
7434 preds0, strides, preds1,
7435 strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007436 }
7437 av1_subtract_plane(x, bsize, 0);
7438 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7439 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7440 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07007441 rd = RDCOST(x->rdmult, rs2 + *out_rate_mv + rate_sum, dist_sum);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007442 best_rd_cur = rd;
7443
7444 } else {
David Barker426a9972017-01-27 11:03:11 +00007445 av1_build_wedge_inter_predictor_from_buf(xd, bsize, 0, 0,
7446#if CONFIG_SUPERTX
7447 0, 0,
7448#endif // CONFIG_SUPERTX
7449 preds0, strides, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007450 av1_subtract_plane(x, bsize, 0);
7451 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
7452 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
7453 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07007454 rd = RDCOST(x->rdmult, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker6fdc8532016-11-16 17:47:13 -08007455 best_rd_cur = rd;
7456 }
7457 return best_rd_cur;
7458}
Sarah Parkerddcea392017-04-25 15:57:22 -07007459#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07007460#endif // CONFIG_EXT_INTER
7461
Fergus Simpson073c6f32017-02-17 12:13:48 -08007462typedef struct {
7463#if CONFIG_MOTION_VAR
7464 // Inter prediction buffers and respective strides
7465 uint8_t *above_pred_buf[MAX_MB_PLANE];
7466 int above_pred_stride[MAX_MB_PLANE];
7467 uint8_t *left_pred_buf[MAX_MB_PLANE];
7468 int left_pred_stride[MAX_MB_PLANE];
7469#endif // CONFIG_MOTION_VAR
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007470 int_mv *single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007471#if CONFIG_EXT_INTER
7472 // Pointer to array of motion vectors to use for each ref and their rates
7473 // Should point to first of 2 arrays in 2D array
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007474 int *single_newmv_rate;
Fergus Simpson073c6f32017-02-17 12:13:48 -08007475 // Pointer to array of predicted rate-distortion
7476 // Should point to first of 2 arrays in 2D array
7477 int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007478#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08007479 InterpFilter single_filter[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Fergus Simpson073c6f32017-02-17 12:13:48 -08007480} HandleInterModeArgs;
7481
Fergus Simpson45509632017-02-22 15:30:50 -08007482static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
7483 const BLOCK_SIZE bsize,
7484 int_mv (*const mode_mv)[TOTAL_REFS_PER_FRAME],
Zoe Liu85b66462017-04-20 14:28:19 -07007485#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7486 int_mv (*const mode_comp_mv)[TOTAL_REFS_PER_FRAME],
7487#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007488 const int mi_row, const int mi_col,
7489 int *const rate_mv, int_mv *const single_newmv,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007490 HandleInterModeArgs *const args) {
Fergus Simpson45509632017-02-22 15:30:50 -08007491 const MACROBLOCKD *const xd = &x->e_mbd;
7492 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7493 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
7494 const int is_comp_pred = has_second_ref(mbmi);
7495 const PREDICTION_MODE this_mode = mbmi->mode;
7496#if CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007497 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
7498#endif // CONFIG_EXT_INTER
7499 int_mv *const frame_mv = mode_mv[this_mode];
Zoe Liu85b66462017-04-20 14:28:19 -07007500#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7501 int_mv *const frame_comp_mv = mode_comp_mv[this_mode];
7502#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007503 const int refs[2] = { mbmi->ref_frame[0],
7504 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
7505 int i;
7506
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08007507 (void)args;
Fergus Simpson45509632017-02-22 15:30:50 -08007508
7509 if (is_comp_pred) {
7510#if CONFIG_EXT_INTER
7511 for (i = 0; i < 2; ++i) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007512 single_newmv[refs[i]].as_int = args->single_newmv[refs[i]].as_int;
Fergus Simpson45509632017-02-22 15:30:50 -08007513 }
7514
7515 if (this_mode == NEW_NEWMV) {
7516 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7517 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7518
7519 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu85b66462017-04-20 14:28:19 -07007520 joint_motion_search(cpi, x, bsize, frame_mv,
7521#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7522 NULL, // int_mv *frame_comp_mv
7523#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7524 mi_row, mi_col, NULL, NULL, 0, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007525 } else {
7526 *rate_mv = 0;
7527 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007528 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007529 *rate_mv += av1_mv_bit_cost(
7530 &frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7531 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7532 }
7533 }
7534 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
7535 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01007536 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7537 frame_mv[refs[0]].as_int =
7538 mode_mv[compound_ref0_mode(this_mode)][refs[0]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007539 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7540#if CONFIG_COMPOUND_SINGLEREF
7541 NULL,
7542#endif // CONFIG_COMPOUND_SINGLEREF
7543 mi_row, mi_col, NULL, 0,
7544 rate_mv, 0, 1);
David Barker8dd9b572017-05-12 16:31:38 +01007545 } else {
7546 av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
7547 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
7548 &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
7549 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7550 }
Fergus Simpson45509632017-02-22 15:30:50 -08007551 } else {
David Barkercb03dc32017-04-07 13:05:09 +01007552 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
Fergus Simpson45509632017-02-22 15:30:50 -08007553 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
David Barker8dd9b572017-05-12 16:31:38 +01007554 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7555 frame_mv[refs[1]].as_int =
7556 mode_mv[compound_ref1_mode(this_mode)][refs[1]].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07007557 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7558#if CONFIG_COMPOUND_SINGLEREF
7559 NULL,
7560#endif // CONFIG_COMPOUND_SINGLEREF
7561 mi_row, mi_col, NULL, 0,
7562 rate_mv, 0, 0);
David Barker8dd9b572017-05-12 16:31:38 +01007563 } else {
7564 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
7565 *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7566 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7567 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7568 }
Fergus Simpson45509632017-02-22 15:30:50 -08007569 }
Zoe Liu85b66462017-04-20 14:28:19 -07007570#else // !CONFIG_EXT_INTER
Fergus Simpson45509632017-02-22 15:30:50 -08007571 // Initialize mv using single prediction mode result.
7572 frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7573 frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
7574
7575 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
Zoe Liu122f3942017-04-25 11:18:38 -07007576 joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, rate_mv, 0);
Fergus Simpson45509632017-02-22 15:30:50 -08007577 } else {
7578 *rate_mv = 0;
7579 for (i = 0; i < 2; ++i) {
Zoe Liu122f3942017-04-25 11:18:38 -07007580 av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
Fergus Simpson45509632017-02-22 15:30:50 -08007581 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
7582 &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
7583 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7584 }
7585 }
7586#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07007587#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7588 } else if (is_inter_singleref_comp_mode(this_mode)) {
7589 // Single ref comp mode
7590 const int mode0 = compound_ref0_mode(this_mode);
7591
7592 single_newmv[refs[0]].as_int = args->single_newmv[refs[0]].as_int;
7593 frame_mv[refs[0]].as_int = (mode0 == NEWMV)
7594 ? single_newmv[refs[0]].as_int
7595 : mode_mv[mode0][refs[0]].as_int;
7596 assert(compound_ref1_mode(this_mode) == NEWMV);
7597 frame_comp_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
7598
7599 if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
7600 if (this_mode == SR_NEW_NEWMV) {
7601 joint_motion_search(cpi, x, bsize, frame_mv, frame_comp_mv, mi_row,
7602 mi_col, NULL, NULL, 0, rate_mv, 0);
7603 } else {
7604 assert( // this_mode == SR_NEAREST_NEWMV ||
7605 this_mode == SR_NEAR_NEWMV || this_mode == SR_ZERO_NEWMV);
7606 compound_single_motion_search_interinter(cpi, x, bsize, frame_mv,
7607 frame_comp_mv, mi_row, mi_col,
7608 NULL, 0, rate_mv, 0, 1);
7609 }
7610 } else {
7611 *rate_mv = 0;
7612 av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
7613 if (mode0 == NEWMV)
7614 *rate_mv += av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
7615 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7616 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7617 *rate_mv += av1_mv_bit_cost(&frame_comp_mv[refs[0]].as_mv,
7618 &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
7619 x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
7620 }
7621#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson45509632017-02-22 15:30:50 -08007622 } else {
7623#if CONFIG_EXT_INTER
7624 if (is_comp_interintra_pred) {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007625 x->best_mv = args->single_newmv[refs[0]];
7626 *rate_mv = args->single_newmv_rate[refs[0]];
Fergus Simpson45509632017-02-22 15:30:50 -08007627 } else {
Zoe Liu7f24e1b2017-03-17 17:42:05 -07007628 single_motion_search(cpi, x, bsize, mi_row, mi_col, 0, rate_mv);
7629 args->single_newmv[refs[0]] = x->best_mv;
7630 args->single_newmv_rate[refs[0]] = *rate_mv;
Fergus Simpson45509632017-02-22 15:30:50 -08007631 }
7632#else
7633 single_motion_search(cpi, x, bsize, mi_row, mi_col, rate_mv);
7634 single_newmv[refs[0]] = x->best_mv;
7635#endif // CONFIG_EXT_INTER
7636
7637 if (x->best_mv.as_int == INVALID_MV) return INT64_MAX;
7638
7639 frame_mv[refs[0]] = x->best_mv;
7640 xd->mi[0]->bmi[0].as_mv[0] = x->best_mv;
7641
7642 // Estimate the rate implications of a new mv but discount this
7643 // under certain circumstances where we want to help initiate a weak
7644 // motion field, where the distortion gain for a single block may not
7645 // be enough to overcome the cost of a new mv.
7646 if (discount_newmv_test(cpi, this_mode, x->best_mv, mode_mv, refs[0])) {
7647 *rate_mv = AOMMAX(*rate_mv / NEW_MV_DISCOUNT_FACTOR, 1);
7648 }
7649 }
7650
7651 return 0;
7652}
7653
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007654int64_t interpolation_filter_search(
7655 MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
7656 int mi_row, int mi_col, const BUFFER_SET *const tmp_dst,
7657 BUFFER_SET *const orig_dst,
7658 InterpFilter (*const single_filter)[TOTAL_REFS_PER_FRAME],
7659 int64_t *const rd, int *const switchable_rate, int *const skip_txfm_sb,
7660 int64_t *const skip_sse_sb) {
7661 const AV1_COMMON *cm = &cpi->common;
7662 MACROBLOCKD *const xd = &x->e_mbd;
7663 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
7664 int i;
7665 int tmp_rate;
7666 int64_t tmp_dist;
7667
7668 (void)single_filter;
7669
7670 InterpFilter assign_filter = SWITCHABLE;
7671
7672 if (cm->interp_filter == SWITCHABLE) {
7673#if !CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007674 assign_filter = av1_is_interp_needed(xd)
7675 ? predict_interp_filter(cpi, x, bsize, mi_row, mi_col,
7676 single_filter)
7677 : cm->interp_filter;
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007678#endif // !CONFIG_DUAL_FILTER
7679 } else {
7680 assign_filter = cm->interp_filter;
7681 }
7682
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007683 set_default_interp_filters(mbmi, assign_filter);
7684
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007685 *switchable_rate = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007686 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007687 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
7688 skip_txfm_sb, skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07007689 *rd = RDCOST(x->rdmult, *switchable_rate + tmp_rate, tmp_dist);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007690
7691 if (assign_filter == SWITCHABLE) {
7692 // do interp_filter search
Debargha Mukherjee0df711f2017-05-02 16:00:20 -07007693 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) {
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007694#if CONFIG_DUAL_FILTER
7695 const int filter_set_size = DUAL_FILTER_SET_SIZE;
7696#else
7697 const int filter_set_size = SWITCHABLE_FILTERS;
7698#endif // CONFIG_DUAL_FILTER
7699 int best_in_temp = 0;
7700#if CONFIG_DUAL_FILTER
7701 InterpFilter best_filter[4];
7702 av1_copy(best_filter, mbmi->interp_filter);
7703#else
7704 InterpFilter best_filter = mbmi->interp_filter;
7705#endif // CONFIG_DUAL_FILTER
7706 restore_dst_buf(xd, *tmp_dst);
7707 // EIGHTTAP_REGULAR mode is calculated beforehand
7708 for (i = 1; i < filter_set_size; ++i) {
7709 int tmp_skip_sb = 0;
7710 int64_t tmp_skip_sse = INT64_MAX;
7711 int tmp_rs;
7712 int64_t tmp_rd;
7713#if CONFIG_DUAL_FILTER
7714 mbmi->interp_filter[0] = filter_sets[i][0];
7715 mbmi->interp_filter[1] = filter_sets[i][1];
7716 mbmi->interp_filter[2] = filter_sets[i][0];
7717 mbmi->interp_filter[3] = filter_sets[i][1];
7718#else
7719 mbmi->interp_filter = (InterpFilter)i;
7720#endif // CONFIG_DUAL_FILTER
7721 tmp_rs = av1_get_switchable_rate(cpi, xd);
Jingning Hanc44009c2017-05-06 11:36:49 -07007722 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007723 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7724 &tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
Urvang Joshi70006e42017-06-14 16:08:55 -07007725 tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08007726
7727 if (tmp_rd < *rd) {
7728 *rd = tmp_rd;
7729 *switchable_rate = av1_get_switchable_rate(cpi, xd);
7730#if CONFIG_DUAL_FILTER
7731 av1_copy(best_filter, mbmi->interp_filter);
7732#else
7733 best_filter = mbmi->interp_filter;
7734#endif // CONFIG_DUAL_FILTER
7735 *skip_txfm_sb = tmp_skip_sb;
7736 *skip_sse_sb = tmp_skip_sse;
7737 best_in_temp = !best_in_temp;
7738 if (best_in_temp) {
7739 restore_dst_buf(xd, *orig_dst);
7740 } else {
7741 restore_dst_buf(xd, *tmp_dst);
7742 }
7743 }
7744 }
7745 if (best_in_temp) {
7746 restore_dst_buf(xd, *tmp_dst);
7747 } else {
7748 restore_dst_buf(xd, *orig_dst);
7749 }
7750#if CONFIG_DUAL_FILTER
7751 av1_copy(mbmi->interp_filter, best_filter);
7752#else
7753 mbmi->interp_filter = best_filter;
7754#endif // CONFIG_DUAL_FILTER
7755 } else {
7756#if CONFIG_DUAL_FILTER
7757 for (i = 0; i < 4; ++i)
7758 assert(mbmi->interp_filter[i] == EIGHTTAP_REGULAR);
7759#else
7760 assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
7761#endif // CONFIG_DUAL_FILTER
7762 }
7763 }
7764
7765 return 0;
7766}
7767
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007768// TODO(afergs): Refactor the MBMI references in here - there's four
7769// TODO(afergs): Refactor optional args - add them to a struct or remove
7770static int64_t motion_mode_rd(
7771 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
7772 RD_STATS *rd_stats, RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
7773 int *disable_skip, int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME], int mi_row,
7774 int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
7775 const int *refs, int rate_mv,
7776#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07007777 // only used when WARPED_MOTION is on?
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007778 int_mv *const single_newmv,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007779#if CONFIG_EXT_INTER
Yunqing Wang562a3932017-06-20 12:20:45 -07007780 int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi, int rate_mv_bmc,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007781#endif // CONFIG_EXT_INTER
7782#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7783 int rs, int *skip_txfm_sb, int64_t *skip_sse_sb, BUFFER_SET *orig_dst) {
7784 const AV1_COMMON *const cm = &cpi->common;
7785 MACROBLOCKD *xd = &x->e_mbd;
7786 MODE_INFO *mi = xd->mi[0];
7787 MB_MODE_INFO *mbmi = &mi->mbmi;
7788 const int is_comp_pred = has_second_ref(mbmi);
7789 const PREDICTION_MODE this_mode = mbmi->mode;
7790
7791 (void)mode_mv;
7792 (void)mi_row;
7793 (void)mi_col;
7794 (void)args;
7795 (void)refs;
7796 (void)rate_mv;
7797 (void)is_comp_pred;
7798 (void)this_mode;
7799
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007800#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7801 MOTION_MODE motion_mode, last_motion_mode_allowed;
7802 int rate2_nocoeff = 0, best_xskip, best_disable_skip = 0;
7803 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
7804 MB_MODE_INFO base_mbmi, best_mbmi;
7805#if CONFIG_VAR_TX
7806 uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE * 4];
7807#endif // CONFIG_VAR_TX
7808#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7809
7810#if CONFIG_WARPED_MOTION
7811 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
7812#endif // CONFIG_WARPED_MOTION
7813
7814#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7815 av1_invalid_rd_stats(&best_rd_stats);
7816#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7817
7818 if (cm->interp_filter == SWITCHABLE) rd_stats->rate += rs;
7819#if CONFIG_WARPED_MOTION
7820 aom_clear_system_state();
7821 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
7822#if CONFIG_EXT_INTER
7823 best_bmc_mbmi->num_proj_ref[0] = mbmi->num_proj_ref[0];
7824#endif // CONFIG_EXT_INTER
7825#endif // CONFIG_WARPED_MOTION
7826#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7827 rate2_nocoeff = rd_stats->rate;
7828 last_motion_mode_allowed = motion_mode_allowed(
7829#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7830 0, xd->global_motion,
7831#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
7832 mi);
7833 base_mbmi = *mbmi;
7834#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7835
7836#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7837 int64_t best_rd = INT64_MAX;
7838 for (motion_mode = SIMPLE_TRANSLATION;
7839 motion_mode <= last_motion_mode_allowed; motion_mode++) {
7840 int64_t tmp_rd = INT64_MAX;
7841 int tmp_rate;
7842 int64_t tmp_dist;
7843#if CONFIG_EXT_INTER
7844 int tmp_rate2 =
7845 motion_mode != SIMPLE_TRANSLATION ? rate2_bmc_nocoeff : rate2_nocoeff;
7846#else
7847 int tmp_rate2 = rate2_nocoeff;
7848#endif // CONFIG_EXT_INTER
7849
7850 *mbmi = base_mbmi;
7851 mbmi->motion_mode = motion_mode;
7852#if CONFIG_MOTION_VAR
7853 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007854#if CONFIG_EXT_INTER
7855 *mbmi = *best_bmc_mbmi;
7856 mbmi->motion_mode = OBMC_CAUSAL;
7857#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07007858 if (!is_comp_pred &&
7859#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7860 !is_inter_singleref_comp_mode(this_mode) &&
7861#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
7862 have_newmv_in_inter_mode(this_mode)) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007863 int tmp_rate_mv = 0;
7864
7865 single_motion_search(cpi, x, bsize, mi_row, mi_col,
7866#if CONFIG_EXT_INTER
Yaowu Xua6317222017-04-17 11:29:51 -07007867 0,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007868#endif // CONFIG_EXT_INTER
7869 &tmp_rate_mv);
7870 mbmi->mv[0].as_int = x->best_mv.as_int;
7871 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7872 refs[0])) {
7873 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7874 }
7875#if CONFIG_EXT_INTER
7876 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7877#else
7878 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7879#endif // CONFIG_EXT_INTER
7880#if CONFIG_DUAL_FILTER
7881 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7882 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7883 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7884 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7885#endif // CONFIG_DUAL_FILTER
Jingning Hanc44009c2017-05-06 11:36:49 -07007886 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007887#if CONFIG_EXT_INTER
7888 } else {
Jingning Hanc44009c2017-05-06 11:36:49 -07007889 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007890#endif // CONFIG_EXT_INTER
7891 }
7892 av1_build_obmc_inter_prediction(
7893 cm, xd, mi_row, mi_col, args->above_pred_buf, args->above_pred_stride,
7894 args->left_pred_buf, args->left_pred_stride);
7895 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7896 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7897 }
7898#endif // CONFIG_MOTION_VAR
7899
7900#if CONFIG_WARPED_MOTION
7901 if (mbmi->motion_mode == WARPED_CAUSAL) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007902#if CONFIG_EXT_INTER
7903 *mbmi = *best_bmc_mbmi;
7904 mbmi->motion_mode = WARPED_CAUSAL;
7905#endif // CONFIG_EXT_INTER
7906 mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
7907#if CONFIG_DUAL_FILTER
Yue Chen05bbf9b2017-04-26 21:58:01 -07007908 for (int dir = 0; dir < 4; ++dir)
7909 mbmi->interp_filter[dir] = cm->interp_filter == SWITCHABLE
7910 ? EIGHTTAP_REGULAR
7911 : cm->interp_filter;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007912#else
7913 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
7914 : cm->interp_filter;
7915#endif // CONFIG_DUAL_FILTER
7916
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07007917 if (!find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
7918 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
7919 &mbmi->wm_params[0], mi_row, mi_col)) {
7920 // Refine MV for NEWMV mode
7921 if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
7922 int tmp_rate_mv = 0;
7923 const int_mv mv0 = mbmi->mv[0];
7924 WarpedMotionParams wm_params0 = mbmi->wm_params[0];
7925
7926 // Refine MV in a small range.
7927 av1_refine_warped_mv(cpi, x, bsize, mi_row, mi_col, pts, pts_inref);
7928
7929 // Keep the refined MV and WM parameters.
7930 if (mv0.as_int != mbmi->mv[0].as_int) {
7931 const int ref = refs[0];
7932 const MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
7933
7934 tmp_rate_mv =
7935 av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv, x->nmvjointcost,
7936 x->mvcost, MV_COST_WEIGHT);
7937
7938 if (cpi->sf.adaptive_motion_search)
7939 x->pred_mv[ref] = mbmi->mv[0].as_mv;
7940
7941 single_newmv[ref] = mbmi->mv[0];
7942
7943 if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
7944 refs[0])) {
7945 tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
7946 }
7947#if CONFIG_EXT_INTER
7948 tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
7949#else
7950 tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
7951#endif // CONFIG_EXT_INTER
7952#if CONFIG_DUAL_FILTER
7953 if (!has_subpel_mv_component(xd->mi[0], xd, 0))
7954 mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
7955 if (!has_subpel_mv_component(xd->mi[0], xd, 1))
7956 mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
7957#endif // CONFIG_DUAL_FILTER
7958 } else {
7959 // Restore the old MV and WM parameters.
7960 mbmi->mv[0] = mv0;
7961 mbmi->wm_params[0] = wm_params0;
7962 }
7963 }
7964
Jingning Hanc44009c2017-05-06 11:36:49 -07007965 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08007966 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
7967 &tmp_dist, skip_txfm_sb, skip_sse_sb);
7968 } else {
7969 continue;
7970 }
7971 }
7972#endif // CONFIG_WARPED_MOTION
7973 x->skip = 0;
7974
7975 rd_stats->dist = 0;
7976 rd_stats->sse = 0;
7977 rd_stats->skip = 1;
7978 rd_stats->rate = tmp_rate2;
7979 if (last_motion_mode_allowed > SIMPLE_TRANSLATION) {
7980#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7981 if (last_motion_mode_allowed == WARPED_CAUSAL)
7982#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7983 rd_stats->rate += cpi->motion_mode_cost[bsize][mbmi->motion_mode];
7984#if CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7985 else
7986 rd_stats->rate += cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
7987#endif // CONFIG_WARPED_MOTION && CONFIG_MOTION_VAR
7988 }
7989#if CONFIG_WARPED_MOTION
7990 if (mbmi->motion_mode == WARPED_CAUSAL) {
7991 rd_stats->rate -= rs;
7992 }
7993#endif // CONFIG_WARPED_MOTION
7994#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
7995 if (!*skip_txfm_sb) {
7996 int64_t rdcosty = INT64_MAX;
7997 int is_cost_valid_uv = 0;
7998
7999 // cost and distortion
8000 av1_subtract_plane(x, bsize, 0);
8001#if CONFIG_VAR_TX
8002 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id]) {
8003 select_tx_type_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8004 } else {
8005 int idx, idy;
8006 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8007 for (idy = 0; idy < xd->n8_h; ++idy)
8008 for (idx = 0; idx < xd->n8_w; ++idx)
8009 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
8010 memset(x->blk_skip[0], rd_stats_y->skip,
8011 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8012 }
8013#else
8014 /* clang-format off */
8015 super_block_yrd(cpi, x, rd_stats_y, bsize, ref_best_rd);
8016/* clang-format on */
8017#endif // CONFIG_VAR_TX
8018
8019 if (rd_stats_y->rate == INT_MAX) {
8020 av1_invalid_rd_stats(rd_stats);
8021#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8022 if (mbmi->motion_mode != SIMPLE_TRANSLATION) {
8023 continue;
8024 } else {
8025#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8026 restore_dst_buf(xd, *orig_dst);
8027 return INT64_MAX;
8028#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8029 }
8030#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8031 }
8032
8033 av1_merge_rd_stats(rd_stats, rd_stats_y);
8034
Urvang Joshi70006e42017-06-14 16:08:55 -07008035 rdcosty = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
8036 rdcosty = AOMMIN(rdcosty, RDCOST(x->rdmult, 0, rd_stats->sse));
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008037/* clang-format off */
8038#if CONFIG_VAR_TX
8039 is_cost_valid_uv =
8040 inter_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8041#else
8042 is_cost_valid_uv =
8043 super_block_uvrd(cpi, x, rd_stats_uv, bsize, ref_best_rd - rdcosty);
8044#endif // CONFIG_VAR_TX
8045 if (!is_cost_valid_uv) {
8046#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8047 continue;
8048#else
8049 restore_dst_buf(xd, *orig_dst);
8050 return INT64_MAX;
8051#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8052 }
8053 /* clang-format on */
8054 av1_merge_rd_stats(rd_stats, rd_stats_uv);
8055#if CONFIG_RD_DEBUG
8056 // record transform block coefficient cost
8057 // TODO(angiebird): So far rd_debug tool only detects discrepancy of
8058 // coefficient cost. Therefore, it is fine to copy rd_stats into mbmi
8059 // here because we already collect the coefficient cost. Move this part to
8060 // other place when we need to compare non-coefficient cost.
8061 mbmi->rd_stats = *rd_stats;
8062#endif // CONFIG_RD_DEBUG
8063#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8064 if (rd_stats->skip) {
8065 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8066 rd_stats_y->rate = 0;
8067 rd_stats_uv->rate = 0;
8068 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8069 mbmi->skip = 0;
8070 // here mbmi->skip temporarily plays a role as what this_skip2 does
8071 } else if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshi70006e42017-06-14 16:08:55 -07008072 (RDCOST(x->rdmult,
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008073 rd_stats_y->rate + rd_stats_uv->rate +
8074 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
8075 rd_stats->dist) >=
Urvang Joshi70006e42017-06-14 16:08:55 -07008076 RDCOST(x->rdmult, av1_cost_bit(av1_get_skip_prob(cm, xd), 1),
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008077 rd_stats->sse))) {
8078 rd_stats->rate -= rd_stats_uv->rate + rd_stats_y->rate;
8079 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8080 rd_stats->dist = rd_stats->sse;
8081 rd_stats_y->rate = 0;
8082 rd_stats_uv->rate = 0;
8083 mbmi->skip = 1;
8084 } else {
8085 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
8086 mbmi->skip = 0;
8087 }
8088 *disable_skip = 0;
8089#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8090 } else {
8091 x->skip = 1;
8092 *disable_skip = 1;
8093 mbmi->tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
8094
8095// The cost of skip bit needs to be added.
8096#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8097 mbmi->skip = 0;
8098#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8099 rd_stats->rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
8100
8101 rd_stats->dist = *skip_sse_sb;
8102 rd_stats->sse = *skip_sse_sb;
8103 rd_stats_y->rate = 0;
8104 rd_stats_uv->rate = 0;
8105 rd_stats->skip = 1;
8106 }
8107
8108#if CONFIG_GLOBAL_MOTION
8109 if (this_mode == ZEROMV
8110#if CONFIG_EXT_INTER
8111 || this_mode == ZERO_ZEROMV
8112#endif // CONFIG_EXT_INTER
8113 ) {
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008114 if (is_nontrans_global_motion(xd)) {
8115 rd_stats->rate -= rs;
8116#if CONFIG_DUAL_FILTER
8117 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
8118 ? EIGHTTAP_REGULAR
8119 : cm->interp_filter;
8120 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
8121 ? EIGHTTAP_REGULAR
8122 : cm->interp_filter;
8123#else
8124 mbmi->interp_filter = cm->interp_filter == SWITCHABLE
8125 ? EIGHTTAP_REGULAR
8126 : cm->interp_filter;
8127#endif // CONFIG_DUAL_FILTER
8128 }
8129 }
8130#endif // CONFIG_GLOBAL_MOTION
8131
8132#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Urvang Joshi70006e42017-06-14 16:08:55 -07008133 tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008134 if (mbmi->motion_mode == SIMPLE_TRANSLATION || (tmp_rd < best_rd)) {
8135 best_mbmi = *mbmi;
8136 best_rd = tmp_rd;
8137 best_rd_stats = *rd_stats;
8138 best_rd_stats_y = *rd_stats_y;
8139 best_rd_stats_uv = *rd_stats_uv;
8140#if CONFIG_VAR_TX
8141 for (int i = 0; i < MAX_MB_PLANE; ++i)
8142 memcpy(best_blk_skip[i], x->blk_skip[i],
8143 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8144#endif // CONFIG_VAR_TX
8145 best_xskip = x->skip;
8146 best_disable_skip = *disable_skip;
8147 }
8148 }
8149
8150 if (best_rd == INT64_MAX) {
8151 av1_invalid_rd_stats(rd_stats);
8152 restore_dst_buf(xd, *orig_dst);
8153 return INT64_MAX;
8154 }
8155 *mbmi = best_mbmi;
8156 *rd_stats = best_rd_stats;
8157 *rd_stats_y = best_rd_stats_y;
8158 *rd_stats_uv = best_rd_stats_uv;
8159#if CONFIG_VAR_TX
8160 for (int i = 0; i < MAX_MB_PLANE; ++i)
8161 memcpy(x->blk_skip[i], best_blk_skip[i],
8162 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
8163#endif // CONFIG_VAR_TX
8164 x->skip = best_xskip;
8165 *disable_skip = best_disable_skip;
8166#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8167
8168 restore_dst_buf(xd, *orig_dst);
8169 return 0;
8170}
8171
Zoe Liu85b66462017-04-20 14:28:19 -07008172static int64_t handle_inter_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
8173 BLOCK_SIZE bsize, RD_STATS *rd_stats,
8174 RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv,
8175 int *disable_skip,
8176 int_mv (*mode_mv)[TOTAL_REFS_PER_FRAME],
8177#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8178 int_mv (*mode_comp_mv)[TOTAL_REFS_PER_FRAME],
8179#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8180 int mi_row, int mi_col,
8181 HandleInterModeArgs *args,
8182 const int64_t ref_best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07008183 const AV1_COMMON *cm = &cpi->common;
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008184 (void)cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008185 MACROBLOCKD *xd = &x->e_mbd;
Sarah Parker19234cc2017-03-10 16:43:25 -08008186 MODE_INFO *mi = xd->mi[0];
8187 MB_MODE_INFO *mbmi = &mi->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008188 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8189 const int is_comp_pred = has_second_ref(mbmi);
8190 const int this_mode = mbmi->mode;
Zoe Liu85b66462017-04-20 14:28:19 -07008191#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8192 const int is_singleref_comp_mode = is_inter_singleref_comp_mode(this_mode);
8193#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008194 int_mv *frame_mv = mode_mv[this_mode];
Zoe Liu85b66462017-04-20 14:28:19 -07008195#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8196 // The comp mv for the compound mode in single ref
8197 int_mv *frame_comp_mv = mode_comp_mv[this_mode];
8198#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008199 int i;
8200 int refs[2] = { mbmi->ref_frame[0],
8201 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
8202 int_mv cur_mv[2];
8203 int rate_mv = 0;
8204#if CONFIG_EXT_INTER
Angie Chiang75c22092016-10-25 12:19:16 -07008205 int pred_exists = 1;
Yue Chen5e606542017-05-24 17:03:17 -07008206#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Jingning Hanae5cfde2016-11-30 12:01:44 -08008207 const int bw = block_size_wide[bsize];
Yue Chen5e606542017-05-24 17:03:17 -07008208#endif // ONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008209 int_mv single_newmv[TOTAL_REFS_PER_FRAME];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008210#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008211 const unsigned int *const interintra_mode_cost =
8212 cpi->interintra_mode_cost[size_group_lookup[bsize]];
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008213#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008214 const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
Yaowu Xuf883b422016-08-30 14:01:10 -07008215 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson073c6f32017-02-17 12:13:48 -08008216#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008217 int_mv *const single_newmv = args->single_newmv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008218#endif // CONFIG_EXT_INTER
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008219#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008220 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
8221#else
8222 DECLARE_ALIGNED(16, uint8_t, tmp_buf_[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008223#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008224 uint8_t *tmp_buf;
8225
Yue Chencb60b182016-10-13 15:18:22 -07008226#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008227#if CONFIG_EXT_INTER
8228 int rate2_bmc_nocoeff;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008229 MB_MODE_INFO best_bmc_mbmi;
Yue Chen69f18e12016-09-08 14:48:15 -07008230 int rate_mv_bmc;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008231#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008232#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Angie Chiang75c22092016-10-25 12:19:16 -07008233 int64_t rd = INT64_MAX;
David Barkerac37fa32016-12-02 12:30:21 +00008234 BUFFER_SET orig_dst, tmp_dst;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008235 int rs = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008236
8237 int skip_txfm_sb = 0;
8238 int64_t skip_sse_sb = INT64_MAX;
Yaowu Xub0d0d002016-11-22 09:26:43 -08008239 int16_t mode_ctx;
Wei-Ting Lin85a8f702017-06-22 13:55:15 -07008240#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
8241 // dummy fillers
8242 mbmi->ncobmc_mode[0] = NO_OVERLAP;
8243 mbmi->ncobmc_mode[1] = NO_OVERLAP;
8244#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008245
8246#if CONFIG_EXT_INTER
Yue Chen5e606542017-05-24 17:03:17 -07008247#if CONFIG_INTERINTRA
8248 int compmode_interintra_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008249 mbmi->use_wedge_interintra = 0;
Yue Chen5e606542017-05-24 17:03:17 -07008250#endif
8251#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
8252 int compmode_interinter_cost = 0;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008253 mbmi->interinter_compound_type = COMPOUND_AVERAGE;
Yue Chen5e606542017-05-24 17:03:17 -07008254#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07008255
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008256#if CONFIG_INTERINTRA
8257 if (!cm->allow_interintra_compound && is_comp_interintra_pred)
8258 return INT64_MAX;
8259#endif // CONFIG_INTERINTRA
8260
Yaowu Xuc27fc142016-08-22 16:08:15 -07008261 // is_comp_interintra_pred implies !is_comp_pred
8262 assert(!is_comp_interintra_pred || (!is_comp_pred));
8263 // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
8264 assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
8265#endif // CONFIG_EXT_INTER
8266
Yaowu Xuc27fc142016-08-22 16:08:15 -07008267#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -07008268#if CONFIG_COMPOUND_SINGLEREF
8269 if (is_comp_pred || is_singleref_comp_mode)
8270#else // !CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008271 if (is_comp_pred)
Zoe Liu85b66462017-04-20 14:28:19 -07008272#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008273 mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
8274 else
8275#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07008276 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
8277 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008278
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008279#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008280 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8281 tmp_buf = CONVERT_TO_BYTEPTR(tmp_buf_);
8282 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008283#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008284 tmp_buf = tmp_buf_;
David Barkerb8069f92016-11-18 14:49:56 +00008285 // Make sure that we didn't leave the plane destination buffers set
8286 // to tmp_buf at the end of the last iteration
8287 assert(xd->plane[0].dst.buf != tmp_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008288
Yue Chen69f18e12016-09-08 14:48:15 -07008289#if CONFIG_WARPED_MOTION
8290 mbmi->num_proj_ref[0] = 0;
8291 mbmi->num_proj_ref[1] = 0;
8292#endif // CONFIG_WARPED_MOTION
8293
Yaowu Xuc27fc142016-08-22 16:08:15 -07008294 if (is_comp_pred) {
8295 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8296 frame_mv[refs[1]].as_int == INVALID_MV)
8297 return INT64_MAX;
Zoe Liu85b66462017-04-20 14:28:19 -07008298#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8299 } else if (is_singleref_comp_mode) {
8300 if (frame_mv[refs[0]].as_int == INVALID_MV ||
8301 frame_comp_mv[refs[0]].as_int == INVALID_MV)
8302 return INT64_MAX;
8303#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008304 }
8305
Yue Chene9638cc2016-10-10 12:37:54 -07008306 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008307 if (have_newmv_in_inter_mode(this_mode)) {
Zoe Liu85b66462017-04-20 14:28:19 -07008308 const int64_t ret_val =
8309 handle_newmv(cpi, x, bsize, mode_mv,
8310#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8311 mode_comp_mv,
8312#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8313 mi_row, mi_col, &rate_mv, single_newmv, args);
Fergus Simpson45509632017-02-22 15:30:50 -08008314 if (ret_val != 0)
8315 return ret_val;
8316 else
8317 rd_stats->rate += rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008318 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008319 for (i = 0; i < is_comp_pred + 1; ++i) {
8320 cur_mv[i] = frame_mv[refs[i]];
Zoe Liued29ea22017-04-20 16:48:15 -07008321 // Clip "next_nearest" so that it does not extend to far out of image
8322 if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008323 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008324 mbmi->mv[i].as_int = cur_mv[i].as_int;
8325 }
8326
Zoe Liu85b66462017-04-20 14:28:19 -07008327#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8328 if (!is_comp_pred && is_singleref_comp_mode) {
8329 cur_mv[1] = frame_comp_mv[refs[0]];
8330 // Clip "next_nearest" so that it does not extend to far out of image
8331 if (this_mode != NEWMV) clamp_mv2(&cur_mv[1].as_mv, xd);
8332 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
8333 mbmi->mv[1].as_int = cur_mv[1].as_int;
8334 }
8335#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8336
Yaowu Xuc27fc142016-08-22 16:08:15 -07008337#if CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008338 if (this_mode == NEAREST_NEARESTMV)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008339#else
Angie Chiang78a3bc12016-11-06 12:55:46 -08008340 if (this_mode == NEARESTMV && is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008341#endif // CONFIG_EXT_INTER
Angie Chiang78a3bc12016-11-06 12:55:46 -08008342 {
8343#if !CONFIG_EXT_INTER
8344 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Fergus Simpson4063a682017-02-28 16:52:22 -08008345#endif // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008346 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
8347 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8348 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8349
8350 for (i = 0; i < 2; ++i) {
8351 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008352 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008353 mbmi->mv[i].as_int = cur_mv[i].as_int;
8354 }
8355 }
8356 }
8357
8358#if CONFIG_EXT_INTER
8359 if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
Zoe Liu85b66462017-04-20 14:28:19 -07008360#if CONFIG_COMPOUND_SINGLEREF
8361 if (this_mode == NEAREST_NEWMV || // this_mode == SR_NEAREST_NEWMV ||
8362 this_mode == SR_NEAREST_NEARMV) {
8363#else // !CONFIG_COMPOUND_SINGLEREF
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008364 if (this_mode == NEAREST_NEWMV) {
Zoe Liu85b66462017-04-20 14:28:19 -07008365#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07008366 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
8367
8368 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8369 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008370 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008371 mbmi->mv[0].as_int = cur_mv[0].as_int;
8372 }
8373
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -07008374 if (this_mode == NEW_NEARESTMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008375 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
8376
8377 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8378 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008379 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008380 mbmi->mv[1].as_int = cur_mv[1].as_int;
8381 }
8382 }
8383
8384 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +01008385 int ref_mv_idx = mbmi->ref_mv_idx + 1;
Zoe Liu85b66462017-04-20 14:28:19 -07008386 if (this_mode == NEAR_NEWMV ||
8387#if CONFIG_COMPOUND_SINGLEREF
8388 this_mode == SR_NEAR_NEWMV ||
8389#endif // CONFIG_COMPOUND_SINGLEREF
8390 this_mode == NEAR_NEARMV) {
David Barker404b2e82017-03-27 13:07:47 +01008391 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008392
8393 lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
8394 clamp_mv2(&cur_mv[0].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008395 if (mv_check_bounds(&x->mv_limits, &cur_mv[0].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008396 mbmi->mv[0].as_int = cur_mv[0].as_int;
8397 }
8398
Zoe Liu85b66462017-04-20 14:28:19 -07008399 if (this_mode == NEW_NEARMV ||
8400#if CONFIG_COMPOUND_SINGLEREF
8401 this_mode == SR_NEAREST_NEARMV ||
8402#endif // CONFIG_COMPOUND_SINGLEREF
8403 this_mode == NEAR_NEARMV) {
8404#if CONFIG_COMPOUND_SINGLEREF
8405 if (this_mode == SR_NEAREST_NEARMV)
8406 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8407 else
8408#endif // CONFIG_COMPOUND_SINGLEREF
8409 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008410
8411 lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
8412 clamp_mv2(&cur_mv[1].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008413 if (mv_check_bounds(&x->mv_limits, &cur_mv[1].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008414 mbmi->mv[1].as_int = cur_mv[1].as_int;
8415 }
8416 }
Zoe Liu85b66462017-04-20 14:28:19 -07008417#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008418 if (this_mode == NEARMV && is_comp_pred) {
Yaowu Xuf883b422016-08-30 14:01:10 -07008419 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008420 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
8421 int ref_mv_idx = mbmi->ref_mv_idx + 1;
8422 cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
8423 cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
8424
8425 for (i = 0; i < 2; ++i) {
8426 clamp_mv2(&cur_mv[i].as_mv, xd);
Alex Converse0fa0f422017-04-24 12:51:14 -07008427 if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008428 mbmi->mv[i].as_int = cur_mv[i].as_int;
8429 }
8430 }
8431 }
8432#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008433
8434 // do first prediction into the destination buffer. Do the next
8435 // prediction into a temporary buffer. Then keep track of which one
8436 // of these currently holds the best predictor, and use the other
8437 // one for future predictions. In the end, copy from tmp_buf to
8438 // dst if necessary.
8439 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008440 tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
8441 tmp_dst.stride[i] = MAX_SB_SIZE;
Angie Chiang75c22092016-10-25 12:19:16 -07008442 }
8443 for (i = 0; i < MAX_MB_PLANE; i++) {
David Barkerac37fa32016-12-02 12:30:21 +00008444 orig_dst.plane[i] = xd->plane[i].dst.buf;
8445 orig_dst.stride[i] = xd->plane[i].dst.stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008446 }
8447
8448 // We don't include the cost of the second reference here, because there
8449 // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
8450 // words if you present them in that order, the second one is always known
8451 // if the first is known.
8452 //
8453 // Under some circumstances we discount the cost of new mv mode to encourage
8454 // initiation of a motion field.
8455 if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], mode_mv,
8456 refs[0])) {
David Barkercb03dc32017-04-07 13:05:09 +01008457#if CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -08008458 rd_stats->rate +=
David Barkercb03dc32017-04-07 13:05:09 +01008459 AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8460 cost_mv_ref(cpi, is_comp_pred ? NEAREST_NEARESTMV : NEARESTMV,
8461 mode_ctx));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008462#else
Angie Chiang76159122016-11-09 12:13:22 -08008463 rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
8464 cost_mv_ref(cpi, NEARESTMV, mode_ctx));
Sebastien Alaiwane140c502017-04-27 09:52:34 +02008465#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008466 } else {
Angie Chiang76159122016-11-09 12:13:22 -08008467 rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008468 }
8469
Urvang Joshi70006e42017-06-14 16:08:55 -07008470 if (RDCOST(x->rdmult, rd_stats->rate, 0) > ref_best_rd &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07008471#if CONFIG_EXT_INTER
8472 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV
8473#else
8474 mbmi->mode != NEARESTMV
8475#endif // CONFIG_EXT_INTER
8476 )
8477 return INT64_MAX;
8478
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008479 int64_t ret_val = interpolation_filter_search(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008480 x, cpi, bsize, mi_row, mi_col, &tmp_dst, &orig_dst, args->single_filter,
8481 &rd, &rs, &skip_txfm_sb, &skip_sse_sb);
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08008482 if (ret_val != 0) return ret_val;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008483
Yaowu Xuc27fc142016-08-22 16:08:15 -07008484#if CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07008485#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008486 best_bmc_mbmi = *mbmi;
Angie Chiang76159122016-11-09 12:13:22 -08008487 rate2_bmc_nocoeff = rd_stats->rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008488 if (cm->interp_filter == SWITCHABLE) rate2_bmc_nocoeff += rs;
Yue Chen69f18e12016-09-08 14:48:15 -07008489 rate_mv_bmc = rate_mv;
Yue Chen69f18e12016-09-08 14:48:15 -07008490#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07008491
Yue Chen5e606542017-05-24 17:03:17 -07008492#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Zoe Liu85b66462017-04-20 14:28:19 -07008493#if CONFIG_COMPOUND_SINGLEREF
8494 if (is_comp_pred || is_singleref_comp_mode) {
8495#else
Sarah Parker6fdc8532016-11-16 17:47:13 -08008496 if (is_comp_pred) {
Zoe Liu85b66462017-04-20 14:28:19 -07008497#endif // CONFIG_COMPOUND_SINGLEREF
Urvang Joshi368fbc92016-10-17 16:31:34 -07008498 int rate_sum, rs2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008499 int64_t dist_sum;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008500 int64_t best_rd_compound = INT64_MAX, best_rd_cur = INT64_MAX;
8501 INTERINTER_COMPOUND_DATA best_compound_data;
8502 int_mv best_mv[2];
8503 int best_tmp_rate_mv = rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008504 int tmp_skip_txfm_sb;
8505 int64_t tmp_skip_sse_sb;
James Zern2c5f4712017-04-26 00:14:33 -07008506 int compound_type_cost[COMPOUND_TYPES];
Yaowu Xu5e8007f2017-06-28 12:39:18 -07008507 DECLARE_ALIGNED(16, uint8_t, pred0[2 * MAX_SB_SQUARE]);
8508 DECLARE_ALIGNED(16, uint8_t, pred1[2 * MAX_SB_SQUARE]);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008509 uint8_t *preds0[1] = { pred0 };
8510 uint8_t *preds1[1] = { pred1 };
8511 int strides[1] = { bw };
Sarah Parker2e604882017-01-17 17:31:25 -08008512 int tmp_rate_mv;
Sarah Parker42d96102017-01-31 21:05:27 -08008513 int masked_compound_used = is_any_masked_compound_used(bsize);
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008514#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
8515 masked_compound_used = masked_compound_used && cm->allow_masked_compound;
8516#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008517 COMPOUND_TYPE cur_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008518
Sarah Parker6fdc8532016-11-16 17:47:13 -08008519 best_mv[0].as_int = cur_mv[0].as_int;
8520 best_mv[1].as_int = cur_mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008521 memset(&best_compound_data, 0, sizeof(best_compound_data));
8522#if CONFIG_COMPOUND_SEGMENT
8523 uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
8524 best_compound_data.seg_mask = tmp_mask_buf;
8525#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008526
Zoe Liu85b66462017-04-20 14:28:19 -07008527#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8528 // TODO(zoeliu): To further check whether the following setups are needed.
8529 // Single ref compound mode: Prepare the 2nd ref frame predictor the same as
8530 // the 1st one.
8531 if (!is_comp_pred && is_singleref_comp_mode) {
8532 xd->block_refs[1] = xd->block_refs[0];
8533 for (i = 0; i < MAX_MB_PLANE; i++)
8534 xd->plane[i].pre[1] = xd->plane[i].pre[0];
8535 }
8536#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
8537
Sarah Parker42d96102017-01-31 21:05:27 -08008538 if (masked_compound_used) {
Debargha Mukherjeeee2dbf72017-05-01 11:55:17 -07008539 av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
8540 av1_compound_type_tree);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008541 // get inter predictors to use for masked compound modes
Yaowu Xuf883b422016-08-30 14:01:10 -07008542 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008543 xd, bsize, 0, 0, mi_row, mi_col, 0, preds0, strides);
Yaowu Xuf883b422016-08-30 14:01:10 -07008544 av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008545 xd, bsize, 0, 0, mi_row, mi_col, 1, preds1, strides);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008546 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008547
Sarah Parker6fdc8532016-11-16 17:47:13 -08008548 for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07008549 if (cur_type != COMPOUND_AVERAGE && !masked_compound_used) break;
Yue Chene2518252017-06-05 12:36:46 -07008550 if (!is_interinter_compound_used(cur_type, bsize)) continue;
Sarah Parker2e604882017-01-17 17:31:25 -08008551 tmp_rate_mv = rate_mv;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008552 best_rd_cur = INT64_MAX;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008553 mbmi->interinter_compound_type = cur_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008554 rs2 = av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008555 bsize, mbmi->interinter_compound_type)) +
Sarah Parker42d96102017-01-31 21:05:27 -08008556 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008557 ? compound_type_cost[mbmi->interinter_compound_type]
Sarah Parker42d96102017-01-31 21:05:27 -08008558 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008559
Sarah Parker6fdc8532016-11-16 17:47:13 -08008560 switch (cur_type) {
8561 case COMPOUND_AVERAGE:
Jingning Hanc44009c2017-05-06 11:36:49 -07008562 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8563 bsize);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008564 av1_subtract_plane(x, bsize, 0);
8565 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8566 &tmp_skip_txfm_sb, &tmp_skip_sse_sb,
8567 INT64_MAX);
8568 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008569 best_rd_cur = RDCOST(x->rdmult, rs2 + rate_mv + rate_sum, dist_sum);
Sarah Parker2e604882017-01-17 17:31:25 -08008570 best_rd_compound = best_rd_cur;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008571 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008572#if CONFIG_WEDGE
Sarah Parker6fdc8532016-11-16 17:47:13 -08008573 case COMPOUND_WEDGE:
Sarah Parker6fdc8532016-11-16 17:47:13 -08008574 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8575 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008576 best_rd_cur = build_and_cost_compound_type(
David Barkerac37fa32016-12-02 12:30:21 +00008577 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8578 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker6fdc8532016-11-16 17:47:13 -08008579 }
8580 break;
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008581#endif // CONFIG_WEDGE
Sarah Parker2f6ce752016-12-08 15:26:46 -08008582#if CONFIG_COMPOUND_SEGMENT
Sarah Parker569edda2016-12-14 14:57:38 -08008583 case COMPOUND_SEG:
Sarah Parker569edda2016-12-14 14:57:38 -08008584 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh &&
8585 best_rd_compound / 3 < ref_best_rd) {
Sarah Parkerddcea392017-04-25 15:57:22 -07008586 best_rd_cur = build_and_cost_compound_type(
Sarah Parker569edda2016-12-14 14:57:38 -08008587 cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
8588 &tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
Sarah Parker569edda2016-12-14 14:57:38 -08008589 }
8590 break;
Sarah Parker2f6ce752016-12-08 15:26:46 -08008591#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -08008592 default: assert(0); return 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008593 }
Sarah Parker2e604882017-01-17 17:31:25 -08008594
8595 if (best_rd_cur < best_rd_compound) {
8596 best_rd_compound = best_rd_cur;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008597#if CONFIG_WEDGE
8598 best_compound_data.wedge_index = mbmi->wedge_index;
8599 best_compound_data.wedge_sign = mbmi->wedge_sign;
8600#endif // CONFIG_WEDGE
8601#if CONFIG_COMPOUND_SEGMENT
8602 best_compound_data.mask_type = mbmi->mask_type;
8603 memcpy(best_compound_data.seg_mask, xd->seg_mask,
8604 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8605#endif // CONFIG_COMPOUND_SEGMENT
8606 best_compound_data.interinter_compound_type =
8607 mbmi->interinter_compound_type;
Sarah Parker2e604882017-01-17 17:31:25 -08008608 if (have_newmv_in_inter_mode(this_mode)) {
8609 if (use_masked_motion_search(cur_type)) {
8610 best_tmp_rate_mv = tmp_rate_mv;
8611 best_mv[0].as_int = mbmi->mv[0].as_int;
8612 best_mv[1].as_int = mbmi->mv[1].as_int;
8613 } else {
8614 best_mv[0].as_int = cur_mv[0].as_int;
8615 best_mv[1].as_int = cur_mv[1].as_int;
8616 }
8617 }
8618 }
8619 // reset to original mvs for next iteration
8620 mbmi->mv[0].as_int = cur_mv[0].as_int;
8621 mbmi->mv[1].as_int = cur_mv[1].as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008622 }
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008623#if CONFIG_WEDGE
8624 mbmi->wedge_index = best_compound_data.wedge_index;
8625 mbmi->wedge_sign = best_compound_data.wedge_sign;
8626#endif // CONFIG_WEDGE
8627#if CONFIG_COMPOUND_SEGMENT
8628 mbmi->mask_type = best_compound_data.mask_type;
8629 memcpy(xd->seg_mask, best_compound_data.seg_mask,
8630 2 * MAX_SB_SQUARE * sizeof(uint8_t));
8631#endif // CONFIG_COMPOUND_SEGMENT
8632 mbmi->interinter_compound_type =
8633 best_compound_data.interinter_compound_type;
Sarah Parker6fdc8532016-11-16 17:47:13 -08008634 if (have_newmv_in_inter_mode(this_mode)) {
8635 mbmi->mv[0].as_int = best_mv[0].as_int;
8636 mbmi->mv[1].as_int = best_mv[1].as_int;
8637 xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
8638 xd->mi[0]->bmi[0].as_mv[1].as_int = mbmi->mv[1].as_int;
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008639 if (use_masked_motion_search(mbmi->interinter_compound_type)) {
Sarah Parker6fdc8532016-11-16 17:47:13 -08008640 rd_stats->rate += best_tmp_rate_mv - rate_mv;
8641 rate_mv = best_tmp_rate_mv;
8642 }
8643 }
8644
8645 if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008646 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008647 return INT64_MAX;
David Barkerb8069f92016-11-18 14:49:56 +00008648 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07008649
8650 pred_exists = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008651
Yue Chen5e606542017-05-24 17:03:17 -07008652 compmode_interinter_cost =
Sarah Parker6fdc8532016-11-16 17:47:13 -08008653 av1_cost_literal(get_interinter_compound_type_bits(
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008654 bsize, mbmi->interinter_compound_type)) +
David Barkercb03dc32017-04-07 13:05:09 +01008655 (masked_compound_used
Sarah Parker2d0e9b72017-05-04 01:34:16 +00008656 ? compound_type_cost[mbmi->interinter_compound_type]
David Barkercb03dc32017-04-07 13:05:09 +01008657 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008658 }
Yue Chen5e606542017-05-24 17:03:17 -07008659#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -07008660
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008661#if CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008662 if (is_comp_interintra_pred) {
8663 INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
8664 int64_t best_interintra_rd = INT64_MAX;
8665 int rmode, rate_sum;
8666 int64_t dist_sum;
8667 int j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008668 int tmp_rate_mv = 0;
8669 int tmp_skip_txfm_sb;
8670 int64_t tmp_skip_sse_sb;
8671 DECLARE_ALIGNED(16, uint8_t, intrapred_[2 * MAX_SB_SQUARE]);
8672 uint8_t *intrapred;
8673
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008674#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008675 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
8676 intrapred = CONVERT_TO_BYTEPTR(intrapred_);
8677 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02008678#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07008679 intrapred = intrapred_;
8680
Emil Keyder01770b32017-01-20 18:03:11 -05008681 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008682 for (j = 0; j < MAX_MB_PLANE; j++) {
8683 xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
8684 xd->plane[j].dst.stride = bw;
8685 }
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008686 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst, bsize);
David Barkerac37fa32016-12-02 12:30:21 +00008687 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008688 mbmi->ref_frame[1] = INTRA_FRAME;
8689 mbmi->use_wedge_interintra = 0;
8690
8691 for (j = 0; j < INTERINTRA_MODES; ++j) {
8692 mbmi->interintra_mode = (INTERINTRA_MODE)j;
8693 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008694 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8695 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008696 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008697 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8698 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008699 rd = RDCOST(x->rdmult, tmp_rate_mv + rate_sum + rmode, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008700 if (rd < best_interintra_rd) {
8701 best_interintra_rd = rd;
8702 best_interintra_mode = mbmi->interintra_mode;
8703 }
8704 }
8705 mbmi->interintra_mode = best_interintra_mode;
8706 rmode = interintra_mode_cost[mbmi->interintra_mode];
David Barkerac37fa32016-12-02 12:30:21 +00008707 av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
8708 intrapred, bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07008709 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
8710 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008711 rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8712 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8713 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008714 rd = RDCOST(x->rdmult, rate_mv + rmode + rate_sum, dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008715 best_interintra_rd = rd;
8716
8717 if (ref_best_rd < INT64_MAX && best_interintra_rd > 2 * ref_best_rd) {
David Barkerb8069f92016-11-18 14:49:56 +00008718 // Don't need to call restore_dst_buf here
Yaowu Xuc27fc142016-08-22 16:08:15 -07008719 return INT64_MAX;
8720 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008721#if CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008722 if (is_interintra_wedge_used(bsize)) {
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008723 int64_t best_interintra_rd_nowedge = INT64_MAX;
8724 int64_t best_interintra_rd_wedge = INT64_MAX;
8725 int_mv tmp_mv;
8726 int rwedge = av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008727 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008728 rd = RDCOST(x->rdmult, rmode + rate_mv + rwedge + rate_sum, dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07008729 best_interintra_rd_nowedge = best_interintra_rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008730
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008731 // Disable wedge search if source variance is small
Yaowu Xuc27fc142016-08-22 16:08:15 -07008732 if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
8733 mbmi->use_wedge_interintra = 1;
8734
Yaowu Xuf883b422016-08-30 14:01:10 -07008735 rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
8736 av1_cost_bit(cm->fc->wedge_interintra_prob[bsize], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008737
8738 best_interintra_rd_wedge =
8739 pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
8740
8741 best_interintra_rd_wedge +=
Urvang Joshi70006e42017-06-14 16:08:55 -07008742 RDCOST(x->rdmult, rmode + rate_mv + rwedge, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008743 // Refine motion vector.
8744 if (have_newmv_in_inter_mode(this_mode)) {
8745 // get negative of mask
Yaowu Xuf883b422016-08-30 14:01:10 -07008746 const uint8_t *mask = av1_get_contiguous_soft_mask(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008747 mbmi->interintra_wedge_index, 1, bsize);
David Barkerf19f35f2017-05-22 16:33:22 +01008748 tmp_mv.as_int = x->mbmi_ext->ref_mvs[refs[0]][0].as_int;
8749 compound_single_motion_search(cpi, x, bsize, &tmp_mv.as_mv, mi_row,
8750 mi_col, intrapred, mask, bw,
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -07008751 &tmp_rate_mv, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008752 mbmi->mv[0].as_int = tmp_mv.as_int;
Debargha Mukherjeead8be032017-05-09 15:28:45 -07008753 av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
8754 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008755 model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
8756 &tmp_skip_txfm_sb, &tmp_skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008757 rd = RDCOST(x->rdmult, rmode + tmp_rate_mv + rwedge + rate_sum,
8758 dist_sum);
Yue Chenf03907a2017-05-31 12:04:04 -07008759 if (rd >= best_interintra_rd_wedge) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008760 tmp_mv.as_int = cur_mv[0].as_int;
8761 tmp_rate_mv = rate_mv;
8762 }
8763 } else {
8764 tmp_mv.as_int = cur_mv[0].as_int;
8765 tmp_rate_mv = rate_mv;
Yaowu Xuf883b422016-08-30 14:01:10 -07008766 av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008767 }
8768 // Evaluate closer to true rd
Yaowu Xuf883b422016-08-30 14:01:10 -07008769 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008770 rd =
8771 estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
8772 &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
8773 if (rd != INT64_MAX)
Urvang Joshi70006e42017-06-14 16:08:55 -07008774 rd = RDCOST(x->rdmult, rmode + tmp_rate_mv + rwedge + rate_sum,
8775 dist_sum);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008776 best_interintra_rd_wedge = rd;
8777 if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
8778 mbmi->use_wedge_interintra = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008779 mbmi->mv[0].as_int = tmp_mv.as_int;
Angie Chiang76159122016-11-09 12:13:22 -08008780 rd_stats->rate += tmp_rate_mv - rate_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008781 rate_mv = tmp_rate_mv;
8782 } else {
8783 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008784 mbmi->mv[0].as_int = cur_mv[0].as_int;
8785 }
8786 } else {
8787 mbmi->use_wedge_interintra = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008788 }
8789 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008790#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -07008791
8792 pred_exists = 0;
Yue Chen5e606542017-05-24 17:03:17 -07008793 compmode_interintra_cost =
8794 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1) +
Fergus Simpson073c6f32017-02-17 12:13:48 -08008795 interintra_mode_cost[mbmi->interintra_mode];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008796 if (is_interintra_wedge_used(bsize)) {
Yue Chen5e606542017-05-24 17:03:17 -07008797 compmode_interintra_cost += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07008798 cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
8799 if (mbmi->use_wedge_interintra) {
Yue Chen5e606542017-05-24 17:03:17 -07008800 compmode_interintra_cost +=
Yaowu Xuf883b422016-08-30 14:01:10 -07008801 av1_cost_literal(get_interintra_wedge_bits(bsize));
Yaowu Xuc27fc142016-08-22 16:08:15 -07008802 }
8803 }
8804 } else if (is_interintra_allowed(mbmi)) {
Yue Chen5e606542017-05-24 17:03:17 -07008805 compmode_interintra_cost =
Yaowu Xuf883b422016-08-30 14:01:10 -07008806 av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008807 }
Debargha Mukherjeec5f735f2017-04-26 03:25:28 +00008808#endif // CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07008809
Angie Chiang75c22092016-10-25 12:19:16 -07008810 if (pred_exists == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008811 int tmp_rate;
8812 int64_t tmp_dist;
Jingning Hanc44009c2017-05-06 11:36:49 -07008813 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008814 model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
8815 &tmp_dist, &skip_txfm_sb, &skip_sse_sb);
Urvang Joshi70006e42017-06-14 16:08:55 -07008816 rd = RDCOST(x->rdmult, rs + tmp_rate, tmp_dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008817 }
Angie Chiang75c22092016-10-25 12:19:16 -07008818#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008819
Fergus Simpson3424c2d2017-03-09 11:48:15 -08008820 if (!is_comp_pred)
Yaowu Xuc27fc142016-08-22 16:08:15 -07008821#if CONFIG_DUAL_FILTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008822 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07008823#else
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008824 args->single_filter[this_mode][refs[0]] = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -08008825#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07008826
8827#if CONFIG_EXT_INTER
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008828 if (args->modelled_rd != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07008829 if (is_comp_pred) {
8830 const int mode0 = compound_ref0_mode(this_mode);
8831 const int mode1 = compound_ref1_mode(this_mode);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008832 const int64_t mrd = AOMMIN(args->modelled_rd[mode0][refs[0]],
8833 args->modelled_rd[mode1][refs[1]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008834 if (rd / 4 * 3 > mrd && ref_best_rd < INT64_MAX) {
David Barkerac37fa32016-12-02 12:30:21 +00008835 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008836 return INT64_MAX;
8837 }
8838 } else if (!is_comp_interintra_pred) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08008839 args->modelled_rd[this_mode][refs[0]] = rd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07008840 }
8841 }
8842#endif // CONFIG_EXT_INTER
8843
8844 if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
8845 // if current pred_error modeled rd is substantially more than the best
8846 // so far, do not bother doing full rd
8847 if (rd / 2 > ref_best_rd) {
David Barkerac37fa32016-12-02 12:30:21 +00008848 restore_dst_buf(xd, orig_dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07008849 return INT64_MAX;
8850 }
8851 }
8852
Yue Chen5e606542017-05-24 17:03:17 -07008853#if CONFIG_EXT_INTER
8854#if CONFIG_INTERINTRA
8855 rd_stats->rate += compmode_interintra_cost;
8856#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
8857 rate2_bmc_nocoeff += compmode_interintra_cost;
8858#endif
8859#endif
8860#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
8861 rd_stats->rate += compmode_interinter_cost;
8862#endif
8863#endif
8864
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008865 ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
8866 disable_skip, mode_mv, mi_row, mi_col, args,
8867 ref_best_rd, refs, rate_mv,
Yue Chen69f18e12016-09-08 14:48:15 -07008868#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yunqing Wang68f3ccd2017-05-23 14:43:54 -07008869 single_newmv,
Yaowu Xuc27fc142016-08-22 16:08:15 -07008870#if CONFIG_EXT_INTER
Yunqing Wang562a3932017-06-20 12:20:45 -07008871 rate2_bmc_nocoeff, &best_bmc_mbmi, rate_mv_bmc,
Yue Chen69f18e12016-09-08 14:48:15 -07008872#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07008873#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Fergus Simpson10fb9fb2017-03-09 16:48:02 -08008874 rs, &skip_txfm_sb, &skip_sse_sb, &orig_dst);
8875 if (ret_val != 0) return ret_val;
Angie Chiang76159122016-11-09 12:13:22 -08008876
Yaowu Xuc27fc142016-08-22 16:08:15 -07008877 return 0; // The rate-distortion cost will be re-calculated by caller.
8878}
8879
Alex Converse28744302017-04-13 14:46:22 -07008880#if CONFIG_INTRABC
Alex Converse28744302017-04-13 14:46:22 -07008881static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07008882 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Alex Converse28744302017-04-13 14:46:22 -07008883 int64_t best_rd) {
Alex Converse3d8adf32017-04-24 12:35:42 -07008884 const AV1_COMMON *const cm = &cpi->common;
8885 if (bsize < BLOCK_8X8 || !cm->allow_screen_content_tools) return INT64_MAX;
8886
Alex Converse28744302017-04-13 14:46:22 -07008887 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse3d8adf32017-04-24 12:35:42 -07008888 const TileInfo *tile = &xd->tile;
Alex Converse7c412ea2017-06-01 15:16:22 -07008889#if CONFIG_EC_ADAPT
8890 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
8891#else
8892 FRAME_CONTEXT *const ec_ctx = cm->fc;
8893#endif // CONFIG_EC_ADAPT
Alex Converse3d8adf32017-04-24 12:35:42 -07008894 MODE_INFO *const mi = xd->mi[0];
8895 const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
8896 const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
8897 const int w = block_size_wide[bsize];
8898 const int h = block_size_high[bsize];
8899 const int sb_row = mi_row / MAX_MIB_SIZE;
Alex Converse861d7072017-05-15 14:19:53 -07008900 const int sb_col = mi_col / MAX_MIB_SIZE;
Alex Converse3d8adf32017-04-24 12:35:42 -07008901
Alex Converse44c2bad2017-05-11 09:36:10 -07008902 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
8903 MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
8904 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
8905 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
8906 mbmi_ext->ref_mv_stack[ref_frame],
8907#if CONFIG_EXT_INTER
8908 mbmi_ext->compound_mode_context,
8909#endif // CONFIG_EXT_INTER
8910 candidates, mi_row, mi_col, NULL, NULL,
8911 mbmi_ext->mode_context);
8912
8913 int_mv nearestmv, nearmv;
8914 av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
8915
8916 int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
8917 if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
8918 mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
Alex Converse3d8adf32017-04-24 12:35:42 -07008919
Alex Converse3d8adf32017-04-24 12:35:42 -07008920 struct buf_2d yv12_mb[MAX_MB_PLANE];
8921 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
8922 for (int i = 0; i < MAX_MB_PLANE; ++i) {
8923 xd->plane[i].pre[0] = yv12_mb[i];
8924 }
8925
Alex Converse861d7072017-05-15 14:19:53 -07008926 enum IntrabcMotionDirection {
8927 IBC_MOTION_ABOVE,
8928 IBC_MOTION_LEFT,
8929 IBC_MOTION_DIRECTIONS
8930 };
Alex Converse3d8adf32017-04-24 12:35:42 -07008931
Alex Converse3d8adf32017-04-24 12:35:42 -07008932 MB_MODE_INFO *mbmi = &mi->mbmi;
8933 MB_MODE_INFO best_mbmi = *mbmi;
8934 RD_STATS best_rdcost = *rd_cost;
8935 int best_skip = x->skip;
Alex Converse861d7072017-05-15 14:19:53 -07008936
8937 for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
8938 dir < IBC_MOTION_DIRECTIONS; ++dir) {
8939 const MvLimits tmp_mv_limits = x->mv_limits;
8940 switch (dir) {
8941 case IBC_MOTION_ABOVE:
8942 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8943 x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
8944 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8945 x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
8946 break;
8947 case IBC_MOTION_LEFT:
8948 x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
8949 x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
8950 // TODO(aconverse@google.com): Minimize the overlap between above and
8951 // left areas.
8952 x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
8953 int bottom_coded_mi_edge =
8954 AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
8955 x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
8956 break;
8957 default: assert(0);
8958 }
8959 assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
8960 assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
8961 assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
8962 assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
8963 av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
8964
8965 if (x->mv_limits.col_max < x->mv_limits.col_min ||
8966 x->mv_limits.row_max < x->mv_limits.row_min) {
8967 x->mv_limits = tmp_mv_limits;
8968 continue;
8969 }
8970
8971 int step_param = cpi->mv_step_param;
8972 MV mvp_full = dv_ref.as_mv;
8973 mvp_full.col >>= 3;
8974 mvp_full.row >>= 3;
8975 int sadpb = x->sadperbit16;
8976 int cost_list[5];
8977 int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
8978 sadpb, cond_cost_list(cpi, cost_list),
8979 &dv_ref.as_mv, INT_MAX, 1);
8980
8981 x->mv_limits = tmp_mv_limits;
8982 if (bestsme == INT_MAX) continue;
8983 mvp_full = x->best_mv.as_mv;
8984 MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
8985 if (mv_check_bounds(&x->mv_limits, &dv)) continue;
8986 if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
8987
Alex Converse3d8adf32017-04-24 12:35:42 -07008988#if CONFIG_PALETTE
Alex Converse861d7072017-05-15 14:19:53 -07008989 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
Alex Converse3d8adf32017-04-24 12:35:42 -07008990#endif
Alex Converse861d7072017-05-15 14:19:53 -07008991 mbmi->use_intrabc = 1;
8992 mbmi->mode = DC_PRED;
8993 mbmi->uv_mode = DC_PRED;
8994 mbmi->mv[0].as_mv = dv;
Alex Converse3d8adf32017-04-24 12:35:42 -07008995#if CONFIG_DUAL_FILTER
Alex Converse861d7072017-05-15 14:19:53 -07008996 for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07008997#else
Alex Converse861d7072017-05-15 14:19:53 -07008998 mbmi->interp_filter = BILINEAR;
Alex Converse3d8adf32017-04-24 12:35:42 -07008999#endif
Alex Converse861d7072017-05-15 14:19:53 -07009000 mbmi->skip = 0;
9001 x->skip = 0;
9002 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Alex Converse3d8adf32017-04-24 12:35:42 -07009003
Alex Conversed5d9b6c2017-05-23 15:23:45 -07009004 assert(x->mvcost == x->mv_cost_stack[0]);
9005 // TODO(aconverse@google.com): The full motion field defining discount
9006 // in MV_COST_WEIGHT is too large. Explore other values.
Alex Converse861d7072017-05-15 14:19:53 -07009007 int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
Alex Conversed5d9b6c2017-05-23 15:23:45 -07009008 x->mvcost, MV_COST_WEIGHT_SUB);
9009 const int rate_mode = av1_cost_bit(ec_ctx->intrabc_prob, 1);
Alex Converse3d8adf32017-04-24 12:35:42 -07009010
Alex Converse861d7072017-05-15 14:19:53 -07009011 RD_STATS rd_stats, rd_stats_uv;
9012 av1_subtract_plane(x, bsize, 0);
9013 super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
9014 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
9015 av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
Alex Converse3d8adf32017-04-24 12:35:42 -07009016#if CONFIG_RD_DEBUG
Alex Converse861d7072017-05-15 14:19:53 -07009017 mbmi->rd_stats = rd_stats;
Alex Converse3d8adf32017-04-24 12:35:42 -07009018#endif
9019
Alex Conversee16b2662017-05-24 14:00:00 -07009020#if CONFIG_VAR_TX
9021 // TODO(aconverse@google.com): Evaluate allowing VAR TX on intrabc blocks
9022 const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
9023 const int height = block_size_high[bsize] >> tx_size_high_log2[0];
9024 int idx, idy;
9025 for (idy = 0; idy < height; ++idy)
9026 for (idx = 0; idx < width; ++idx)
9027 mbmi->inter_tx_size[idy >> 1][idx >> 1] = mbmi->tx_size;
9028 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
9029#endif // CONFIG_VAR_TX
9030
Alex Converse861d7072017-05-15 14:19:53 -07009031 const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
Alex Converse3d8adf32017-04-24 12:35:42 -07009032
Alex Converse861d7072017-05-15 14:19:53 -07009033 RD_STATS rdc_noskip;
9034 av1_init_rd_stats(&rdc_noskip);
9035 rdc_noskip.rate =
9036 rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
9037 rdc_noskip.dist = rd_stats.dist;
Urvang Joshi70006e42017-06-14 16:08:55 -07009038 rdc_noskip.rdcost = RDCOST(x->rdmult, rdc_noskip.rate, rdc_noskip.dist);
Alex Converse861d7072017-05-15 14:19:53 -07009039 if (rdc_noskip.rdcost < best_rd) {
9040 best_rd = rdc_noskip.rdcost;
9041 best_mbmi = *mbmi;
9042 best_skip = x->skip;
9043 best_rdcost = rdc_noskip;
9044 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009045
Alex Converse861d7072017-05-15 14:19:53 -07009046 x->skip = 1;
9047 mbmi->skip = 1;
9048 RD_STATS rdc_skip;
9049 av1_init_rd_stats(&rdc_skip);
9050 rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
9051 rdc_skip.dist = rd_stats.sse;
Urvang Joshi70006e42017-06-14 16:08:55 -07009052 rdc_skip.rdcost = RDCOST(x->rdmult, rdc_skip.rate, rdc_skip.dist);
Alex Converse861d7072017-05-15 14:19:53 -07009053 if (rdc_skip.rdcost < best_rd) {
9054 best_rd = rdc_skip.rdcost;
9055 best_mbmi = *mbmi;
9056 best_skip = x->skip;
9057 best_rdcost = rdc_skip;
9058 }
Alex Converse3d8adf32017-04-24 12:35:42 -07009059 }
9060 *mbmi = best_mbmi;
9061 *rd_cost = best_rdcost;
9062 x->skip = best_skip;
9063 return best_rd;
Alex Converse28744302017-04-13 14:46:22 -07009064}
9065#endif // CONFIG_INTRABC
9066
Urvang Joshi52648442016-10-13 17:27:51 -07009067void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009068 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07009069 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
9070 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009071 MACROBLOCKD *const xd = &x->e_mbd;
Luc Trudeau14fc5042017-06-16 12:40:29 -04009072 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009073 struct macroblockd_plane *const pd = xd->plane;
9074 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
9075 int y_skip = 0, uv_skip = 0;
9076 int64_t dist_y = 0, dist_uv = 0;
9077 TX_SIZE max_uv_tx_size;
Jingning Han271bb2c2016-12-14 12:34:46 -08009078 const int unify_bsize = CONFIG_CB4X4;
9079
Yaowu Xuc27fc142016-08-22 16:08:15 -07009080 ctx->skip = 0;
Luc Trudeau14fc5042017-06-16 12:40:29 -04009081 mbmi->ref_frame[0] = INTRA_FRAME;
9082 mbmi->ref_frame[1] = NONE_FRAME;
Alex Converse28744302017-04-13 14:46:22 -07009083#if CONFIG_INTRABC
Luc Trudeau14fc5042017-06-16 12:40:29 -04009084 mbmi->use_intrabc = 0;
9085 mbmi->mv[0].as_int = 0;
Alex Converse28744302017-04-13 14:46:22 -07009086#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07009087
Alex Conversed1b6fad2017-04-26 15:39:37 -07009088 const int64_t intra_yrd =
9089 (bsize >= BLOCK_8X8 || unify_bsize)
9090 ? rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
9091 &y_skip, bsize, best_rd)
9092 : rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
9093 &dist_y, &y_skip, best_rd);
9094
9095 if (intra_yrd < best_rd) {
Luc Trudeau14fc5042017-06-16 12:40:29 -04009096#if CONFIG_CFL
9097 // Perform one extra txfm_rd_in_plane() call, this time with the best value
9098 // so we can store reconstructed luma values
9099 RD_STATS this_rd_stats;
9100
9101 x->cfl_store_y = 1;
9102
9103 txfm_rd_in_plane(x, cpi, &this_rd_stats, INT64_MAX, AOM_PLANE_Y,
9104 mbmi->sb_type, mbmi->tx_size,
9105 cpi->sf.use_fast_coef_costing);
9106
9107 x->cfl_store_y = 0;
9108#endif
9109 max_uv_tx_size = uv_txsize_lookup[bsize][mbmi->tx_size][pd[1].subsampling_x]
9110 [pd[1].subsampling_y];
9111 init_sbuv_mode(mbmi);
Jingning Han271bb2c2016-12-14 12:34:46 -08009112#if CONFIG_CB4X4
Alex Conversed1b6fad2017-04-26 15:39:37 -07009113 if (!x->skip_chroma_rd)
9114 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9115 &uv_skip, bsize, max_uv_tx_size);
Jingning Han271bb2c2016-12-14 12:34:46 -08009116#else
Alex Conversed1b6fad2017-04-26 15:39:37 -07009117 rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
9118 &uv_skip, AOMMAX(BLOCK_8X8, bsize), max_uv_tx_size);
Fergus Simpson4063a682017-02-28 16:52:22 -08009119#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07009120
Alex Conversed1b6fad2017-04-26 15:39:37 -07009121 if (y_skip && uv_skip) {
9122 rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
9123 av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
9124 rd_cost->dist = dist_y + dist_uv;
9125 } else {
9126 rd_cost->rate =
9127 rate_y + rate_uv + av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9128 rd_cost->dist = dist_y + dist_uv;
9129 }
Urvang Joshi70006e42017-06-14 16:08:55 -07009130 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Yushin Cho63927c42017-05-23 15:41:05 -07009131#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9132 rd_cost->dist_y = dist_y;
9133#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009134 } else {
Alex Conversed1b6fad2017-04-26 15:39:37 -07009135 rd_cost->rate = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009136 }
9137
Alex Converse28744302017-04-13 14:46:22 -07009138#if CONFIG_INTRABC
Alex Conversed1b6fad2017-04-26 15:39:37 -07009139 if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
9140 best_rd = rd_cost->rdcost;
Alex Converse28744302017-04-13 14:46:22 -07009141 if (rd_pick_intrabc_mode_sb(cpi, x, rd_cost, bsize, best_rd) < best_rd) {
9142 ctx->skip = x->skip; // FIXME where is the proper place to set this?!
Alex Conversed1b6fad2017-04-26 15:39:37 -07009143 assert(rd_cost->rate != INT_MAX);
Urvang Joshi70006e42017-06-14 16:08:55 -07009144 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Alex Converse28744302017-04-13 14:46:22 -07009145 }
9146#endif
Alex Conversed1b6fad2017-04-26 15:39:37 -07009147 if (rd_cost->rate == INT_MAX) return;
Alex Converse28744302017-04-13 14:46:22 -07009148
Yaowu Xuc27fc142016-08-22 16:08:15 -07009149 ctx->mic = *xd->mi[0];
9150 ctx->mbmi_ext = *x->mbmi_ext;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009151}
9152
Yaowu Xuc27fc142016-08-22 16:08:15 -07009153// Do we have an internal image edge (e.g. formatting bars).
Urvang Joshi52648442016-10-13 17:27:51 -07009154int av1_internal_image_edge(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009155 return (cpi->oxcf.pass == 2) &&
9156 ((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
9157 (cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
9158}
9159
9160// Checks to see if a super block is on a horizontal image edge.
9161// In most cases this is the "real" edge unless there are formatting
9162// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009163int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009164 int top_edge = 0;
9165 int bottom_edge = cpi->common.mi_rows;
9166 int is_active_h_edge = 0;
9167
9168 // For two pass account for any formatting bars detected.
9169 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009170 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009171
9172 // The inactive region is specified in MBs not mi units.
9173 // The image edge is in the following MB row.
9174 top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
9175
9176 bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009177 bottom_edge = AOMMAX(top_edge, bottom_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009178 }
9179
9180 if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
9181 ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
9182 is_active_h_edge = 1;
9183 }
9184 return is_active_h_edge;
9185}
9186
9187// Checks to see if a super block is on a vertical image edge.
9188// In most cases this is the "real" edge unless there are formatting
9189// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009190int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009191 int left_edge = 0;
9192 int right_edge = cpi->common.mi_cols;
9193 int is_active_v_edge = 0;
9194
9195 // For two pass account for any formatting bars detected.
9196 if (cpi->oxcf.pass == 2) {
Urvang Joshi52648442016-10-13 17:27:51 -07009197 const TWO_PASS *const twopass = &cpi->twopass;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009198
9199 // The inactive region is specified in MBs not mi units.
9200 // The image edge is in the following MB row.
9201 left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
9202
9203 right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
Yaowu Xuf883b422016-08-30 14:01:10 -07009204 right_edge = AOMMAX(left_edge, right_edge);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009205 }
9206
9207 if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
9208 ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
9209 is_active_v_edge = 1;
9210 }
9211 return is_active_v_edge;
9212}
9213
9214// Checks to see if a super block is at the edge of the active image.
9215// In most cases this is the "real" edge unless there are formatting
9216// bars embedded in the stream.
Urvang Joshi52648442016-10-13 17:27:51 -07009217int av1_active_edge_sb(const AV1_COMP *cpi, int mi_row, int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -07009218 return av1_active_h_edge(cpi, mi_row, cpi->common.mib_size) ||
9219 av1_active_v_edge(cpi, mi_col, cpi->common.mib_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009220}
9221
Urvang Joshib100db72016-10-12 16:28:56 -07009222#if CONFIG_PALETTE
Urvang Joshi52648442016-10-13 17:27:51 -07009223static void restore_uv_color_map(const AV1_COMP *const cpi, MACROBLOCK *x) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009224 MACROBLOCKD *const xd = &x->e_mbd;
9225 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
9226 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
9227 const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009228 int src_stride = x->plane[1].src.stride;
9229 const uint8_t *const src_u = x->plane[1].src.buf;
9230 const uint8_t *const src_v = x->plane[2].src.buf;
9231 float *const data = x->palette_buffer->kmeans_data_buf;
9232 float centroids[2 * PALETTE_MAX_SIZE];
9233 uint8_t *const color_map = xd->plane[1].color_index_map;
9234 int r, c;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009235#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009236 const uint16_t *const src_u16 = CONVERT_TO_SHORTPTR(src_u);
9237 const uint16_t *const src_v16 = CONVERT_TO_SHORTPTR(src_v);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009238#endif // CONFIG_HIGHBITDEPTH
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009239 int plane_block_width, plane_block_height, rows, cols;
9240 av1_get_block_dimensions(bsize, 1, xd, &plane_block_width,
9241 &plane_block_height, &rows, &cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009242 (void)cpi;
9243
9244 for (r = 0; r < rows; ++r) {
9245 for (c = 0; c < cols; ++c) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009246#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009247 if (cpi->common.use_highbitdepth) {
9248 data[(r * cols + c) * 2] = src_u16[r * src_stride + c];
9249 data[(r * cols + c) * 2 + 1] = src_v16[r * src_stride + c];
9250 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009251#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009252 data[(r * cols + c) * 2] = src_u[r * src_stride + c];
9253 data[(r * cols + c) * 2 + 1] = src_v[r * src_stride + c];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009254#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009255 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009256#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009257 }
9258 }
9259
9260 for (r = 1; r < 3; ++r) {
9261 for (c = 0; c < pmi->palette_size[1]; ++c) {
9262 centroids[c * 2 + r - 1] = pmi->palette_colors[r * PALETTE_MAX_SIZE + c];
9263 }
9264 }
9265
Yaowu Xuf883b422016-08-30 14:01:10 -07009266 av1_calc_indices(data, centroids, color_map, rows * cols,
9267 pmi->palette_size[1], 2);
Urvang Joshi56ba91b2017-01-10 13:22:09 -08009268 extend_palette_color_map(color_map, cols, rows, plane_block_width,
9269 plane_block_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009270}
Urvang Joshib100db72016-10-12 16:28:56 -07009271#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009272
hui su5db97432016-10-14 16:10:14 -07009273#if CONFIG_FILTER_INTRA
9274static void pick_filter_intra_interframe(
9275 const AV1_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
Jingning Han18c53c82017-02-17 14:49:57 -08009276 BLOCK_SIZE bsize, int mi_row, int mi_col, int *rate_uv_intra,
9277 int *rate_uv_tokenonly, int64_t *dist_uv, int *skip_uv,
9278 PREDICTION_MODE *mode_uv, FILTER_INTRA_MODE_INFO *filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -07009279#if CONFIG_EXT_INTRA
9280 int8_t *uv_angle_delta,
9281#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07009282#if CONFIG_PALETTE
9283 PALETTE_MODE_INFO *pmi_uv, int palette_ctx,
9284#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009285 int skip_mask, unsigned int *ref_costs_single, int64_t *best_rd,
9286 int64_t *best_intra_rd, PREDICTION_MODE *best_intra_mode,
9287 int *best_mode_index, int *best_skip2, int *best_mode_skippable,
9288#if CONFIG_SUPERTX
9289 int *returnrate_nocoef,
9290#endif // CONFIG_SUPERTX
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009291 int64_t *best_pred_rd, MB_MODE_INFO *best_mbmode, RD_STATS *rd_cost) {
Urvang Joshi52648442016-10-13 17:27:51 -07009292 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009293 MACROBLOCKD *const xd = &x->e_mbd;
9294 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009295#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009296 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009297#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009298 int rate2 = 0, rate_y = INT_MAX, skippable = 0, rate_uv, rate_dummy, i;
9299 int dc_mode_index;
9300 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
hui su8f4cc0a2017-01-13 15:14:49 -08009301 int64_t distortion2 = 0, distortion_y = 0, this_rd = *best_rd;
9302 int64_t distortion_uv, model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009303 TX_SIZE uv_tx;
9304
9305 for (i = 0; i < MAX_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009306 if (av1_mode_order[i].mode == DC_PRED &&
9307 av1_mode_order[i].ref_frame[0] == INTRA_FRAME)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009308 break;
9309 dc_mode_index = i;
9310 assert(i < MAX_MODES);
9311
9312 // TODO(huisu): use skip_mask for further speedup.
9313 (void)skip_mask;
9314 mbmi->mode = DC_PRED;
9315 mbmi->uv_mode = DC_PRED;
9316 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -05009317 mbmi->ref_frame[1] = NONE_FRAME;
hui su5db97432016-10-14 16:10:14 -07009318 if (!rd_pick_filter_intra_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
9319 &skippable, bsize, intra_mode_cost[mbmi->mode],
hui su8f4cc0a2017-01-13 15:14:49 -08009320 &this_rd, &model_rd, 0)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009321 return;
hui su5db97432016-10-14 16:10:14 -07009322 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009323 if (rate_y == INT_MAX) return;
9324
Debargha Mukherjee2f123402016-08-30 17:43:38 -07009325 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
9326 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009327 if (rate_uv_intra[uv_tx] == INT_MAX) {
9328 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
9329 &rate_uv_tokenonly[uv_tx], &dist_uv[uv_tx],
9330 &skip_uv[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -07009331#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009332 if (cm->allow_screen_content_tools) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009333#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009334 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
9335#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009336 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
hui su5db97432016-10-14 16:10:14 -07009337#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009338 }
9339
9340 rate_uv = rate_uv_tokenonly[uv_tx];
9341 distortion_uv = dist_uv[uv_tx];
9342 skippable = skippable && skip_uv[uv_tx];
9343 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -07009344#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009345 if (cm->allow_screen_content_tools) {
9346 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
9347 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
9348 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
9349 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
9350 }
Urvang Joshib100db72016-10-12 16:28:56 -07009351#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07009352#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009353 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
hui su5db97432016-10-14 16:10:14 -07009354#endif // CONFIG_EXT_INTRA
9355 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
9356 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
9357 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
9358 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
9359 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009360 }
9361
9362 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
9363 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Urvang Joshib100db72016-10-12 16:28:56 -07009364#if CONFIG_PALETTE
Jingning Han4330e1b2017-04-11 21:05:44 -07009365 if (cpi->common.allow_screen_content_tools && mbmi->mode == DC_PRED &&
9366 bsize >= BLOCK_8X8)
Yaowu Xuf883b422016-08-30 14:01:10 -07009367 rate2 += av1_cost_bit(
9368 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
Urvang Joshib100db72016-10-12 16:28:56 -07009369#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009370
9371 if (!xd->lossless[mbmi->segment_id]) {
9372 // super_block_yrd above includes the cost of the tx_size in the
9373 // tokenonly rate, but for intra blocks, tx_size is always coded
9374 // (prediction granularity), so we account for it in the full rate,
9375 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -08009376 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009377 }
9378
hui su5db97432016-10-14 16:10:14 -07009379 rate2 += av1_cost_bit(cm->fc->filter_intra_probs[0],
9380 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
9381 rate2 += write_uniform_cost(
9382 FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
9383#if CONFIG_EXT_INTRA
Joe Young830d4ce2017-05-30 17:48:13 -07009384 if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
9385 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -07009386 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
9387 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009388 }
hui su5db97432016-10-14 16:10:14 -07009389#endif // CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009390 if (mbmi->mode == DC_PRED) {
hui su5db97432016-10-14 16:10:14 -07009391 rate2 +=
9392 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
9393 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
9394 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
9395 rate2 +=
9396 write_uniform_cost(FILTER_INTRA_MODES,
9397 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009398 }
9399 distortion2 = distortion_y + distortion_uv;
Jingning Han18c53c82017-02-17 14:49:57 -08009400 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, bsize, 0, 0, mi_row,
9401 mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009402
9403 rate2 += ref_costs_single[INTRA_FRAME];
9404
9405 if (skippable) {
9406 rate2 -= (rate_y + rate_uv);
9407 rate_y = 0;
9408 rate_uv = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009409 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009410 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07009411 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009412 }
Urvang Joshi70006e42017-06-14 16:08:55 -07009413 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009414
9415 if (this_rd < *best_intra_rd) {
9416 *best_intra_rd = this_rd;
9417 *best_intra_mode = mbmi->mode;
9418 }
9419 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -07009420 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009421
9422 if (this_rd < *best_rd) {
9423 *best_mode_index = dc_mode_index;
9424 mbmi->mv[0].as_int = 0;
9425 rd_cost->rate = rate2;
9426#if CONFIG_SUPERTX
9427 if (x->skip)
9428 *returnrate_nocoef = rate2;
9429 else
9430 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -07009431 *returnrate_nocoef -= av1_cost_bit(av1_get_skip_prob(cm, xd), skippable);
9432 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
9433 mbmi->ref_frame[0] != INTRA_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009434#endif // CONFIG_SUPERTX
9435 rd_cost->dist = distortion2;
9436 rd_cost->rdcost = this_rd;
9437 *best_rd = this_rd;
9438 *best_mbmode = *mbmi;
9439 *best_skip2 = 0;
9440 *best_mode_skippable = skippable;
9441 }
9442}
hui su5db97432016-10-14 16:10:14 -07009443#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009444
Yue Chencb60b182016-10-13 15:18:22 -07009445#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07009446static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
9447 const MACROBLOCKD *xd, int mi_row,
9448 int mi_col, const uint8_t *above,
9449 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -07009450 int left_stride);
Yue Chencb60b182016-10-13 15:18:22 -07009451#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009452
Urvang Joshi52648442016-10-13 17:27:51 -07009453void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
Yaowu Xuf883b422016-08-30 14:01:10 -07009454 MACROBLOCK *x, int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -07009455 RD_STATS *rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009456#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009457 int *returnrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009458#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07009459 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
9460 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -07009461 const AV1_COMMON *const cm = &cpi->common;
9462 const RD_OPT *const rd_opt = &cpi->rd;
9463 const SPEED_FEATURES *const sf = &cpi->sf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009464 MACROBLOCKD *const xd = &x->e_mbd;
9465 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Urvang Joshib100db72016-10-12 16:28:56 -07009466#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -07009467 const int try_palette =
9468 cpi->common.allow_screen_content_tools && bsize >= BLOCK_8X8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009469 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
Urvang Joshib100db72016-10-12 16:28:56 -07009470#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009471 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
9472 const struct segmentation *const seg = &cm->seg;
9473 PREDICTION_MODE this_mode;
9474 MV_REFERENCE_FRAME ref_frame, second_ref_frame;
9475 unsigned char segment_id = mbmi->segment_id;
9476 int comp_pred, i, k;
9477 int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Zoe Liu85b66462017-04-20 14:28:19 -07009478#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
9479 int_mv frame_comp_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
9480#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009481 struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009482 int_mv single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -07009483#if CONFIG_EXT_INTER
9484 int single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
9485 int64_t modelled_rd[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009486#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009487 static const int flag_list[TOTAL_REFS_PER_FRAME] = {
9488 0,
Yaowu Xuf883b422016-08-30 14:01:10 -07009489 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009490#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009491 AOM_LAST2_FLAG,
9492 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009493#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009494 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009495#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009496 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009497#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009498 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07009499 };
9500 int64_t best_rd = best_rd_so_far;
9501 int best_rate_y = INT_MAX, best_rate_uv = INT_MAX;
9502 int64_t best_pred_diff[REFERENCE_MODES];
9503 int64_t best_pred_rd[REFERENCE_MODES];
9504 MB_MODE_INFO best_mbmode;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009505 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
9506 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009507 int best_mode_skippable = 0;
9508 int midx, best_mode_index = -1;
9509 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -07009510#if CONFIG_EXT_COMP_REFS
9511 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME][TOTAL_REFS_PER_FRAME];
9512#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07009513 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -07009514#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07009515 aom_prob comp_mode_p;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009516 int64_t best_intra_rd = INT64_MAX;
9517 unsigned int best_pred_sse = UINT_MAX;
9518 PREDICTION_MODE best_intra_mode = DC_PRED;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009519 int rate_uv_intra[TX_SIZES_ALL], rate_uv_tokenonly[TX_SIZES_ALL];
9520 int64_t dist_uvs[TX_SIZES_ALL];
9521 int skip_uvs[TX_SIZES_ALL];
9522 PREDICTION_MODE mode_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009523#if CONFIG_PALETTE
Urvang Joshifeb925f2016-12-05 10:37:29 -08009524 PALETTE_MODE_INFO pmi_uv[TX_SIZES_ALL];
Urvang Joshib100db72016-10-12 16:28:56 -07009525#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009526#if CONFIG_EXT_INTRA
Urvang Joshifeb925f2016-12-05 10:37:29 -08009527 int8_t uv_angle_delta[TX_SIZES_ALL];
Yaowu Xuc27fc142016-08-22 16:08:15 -07009528 int is_directional_mode, angle_stats_ready = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009529 uint8_t directional_mode_skip_mask[INTRA_MODES];
9530#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07009531#if CONFIG_FILTER_INTRA
9532 int8_t dc_skipped = 1;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009533 FILTER_INTRA_MODE_INFO filter_intra_mode_info_uv[TX_SIZES_ALL];
hui su5db97432016-10-14 16:10:14 -07009534#endif // CONFIG_FILTER_INTRA
Yaowu Xuf883b422016-08-30 14:01:10 -07009535 const int intra_cost_penalty = av1_get_intra_cost_penalty(
Yaowu Xuc27fc142016-08-22 16:08:15 -07009536 cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
9537 const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
9538 int best_skip2 = 0;
9539 uint8_t ref_frame_skip_mask[2] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009540 uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
Yue Chen4d26acb2017-05-01 12:28:34 -07009541#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009542 MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
9543 int64_t best_single_inter_rd = INT64_MAX;
Yue Chen4d26acb2017-05-01 12:28:34 -07009544#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07009545 int mode_skip_start = sf->mode_skip_start + 1;
9546 const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
9547 const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
9548 int64_t mode_threshold[MAX_MODES];
9549 int *mode_map = tile_data->mode_map[bsize];
9550 const int mode_search_skip_flags = sf->mode_search_skip_flags;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009551#if CONFIG_PVQ
9552 od_rollback_buffer pre_buf;
Fergus Simpson4063a682017-02-28 16:52:22 -08009553#endif // CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07009554
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009555 HandleInterModeArgs args = {
Fergus Simpson073c6f32017-02-17 12:13:48 -08009556#if CONFIG_MOTION_VAR
9557 { NULL },
9558 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9559 { NULL },
9560 { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
9561#endif // CONFIG_MOTION_VAR
9562#if CONFIG_EXT_INTER
9563 NULL,
9564 NULL,
9565 NULL,
Fergus Simpson073c6f32017-02-17 12:13:48 -08009566#else // CONFIG_EXT_INTER
9567 NULL,
9568#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -08009569 { { 0 } },
Fergus Simpson073c6f32017-02-17 12:13:48 -08009570 };
9571
Urvang Joshib100db72016-10-12 16:28:56 -07009572#if CONFIG_PALETTE || CONFIG_EXT_INTRA
Jingning Hanae5cfde2016-11-30 12:01:44 -08009573 const int rows = block_size_high[bsize];
9574 const int cols = block_size_wide[bsize];
Urvang Joshib100db72016-10-12 16:28:56 -07009575#endif // CONFIG_PALETTE || CONFIG_EXT_INTRA
9576#if CONFIG_PALETTE
9577 int palette_ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009578 const MODE_INFO *above_mi = xd->above_mi;
9579 const MODE_INFO *left_mi = xd->left_mi;
Urvang Joshib100db72016-10-12 16:28:56 -07009580#endif // CONFIG_PALETTE
Yue Chencb60b182016-10-13 15:18:22 -07009581#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009582 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9583 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9584 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
9585 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
Yaowu Xuc27fc142016-08-22 16:08:15 -07009586
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009587#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009588 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
9589 int len = sizeof(uint16_t);
Jingning Hand064cf02017-06-01 10:00:39 -07009590 args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(x->above_pred_buf);
9591 args.above_pred_buf[1] =
9592 CONVERT_TO_BYTEPTR(x->above_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009593 args.above_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07009594 CONVERT_TO_BYTEPTR(x->above_pred_buf + 2 * MAX_SB_SQUARE * len);
9595 args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(x->left_pred_buf);
9596 args.left_pred_buf[1] =
9597 CONVERT_TO_BYTEPTR(x->left_pred_buf + MAX_SB_SQUARE * len);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009598 args.left_pred_buf[2] =
Jingning Hand064cf02017-06-01 10:00:39 -07009599 CONVERT_TO_BYTEPTR(x->left_pred_buf + 2 * MAX_SB_SQUARE * len);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009600 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009601#endif // CONFIG_HIGHBITDEPTH
Jingning Hand064cf02017-06-01 10:00:39 -07009602 args.above_pred_buf[0] = x->above_pred_buf;
9603 args.above_pred_buf[1] = x->above_pred_buf + MAX_SB_SQUARE;
9604 args.above_pred_buf[2] = x->above_pred_buf + 2 * MAX_SB_SQUARE;
9605 args.left_pred_buf[0] = x->left_pred_buf;
9606 args.left_pred_buf[1] = x->left_pred_buf + MAX_SB_SQUARE;
9607 args.left_pred_buf[2] = x->left_pred_buf + 2 * MAX_SB_SQUARE;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009608#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07009609 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02009610#endif // CONFIG_HIGHBITDEPTH
Yue Chencb60b182016-10-13 15:18:22 -07009611#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009612
Yaowu Xuf883b422016-08-30 14:01:10 -07009613 av1_zero(best_mbmode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07009614
Urvang Joshib100db72016-10-12 16:28:56 -07009615#if CONFIG_PALETTE
9616 av1_zero(pmi_uv);
hui su9bc1d8d2017-03-24 12:36:03 -07009617 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07009618 if (above_mi)
9619 palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9620 if (left_mi)
9621 palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
9622 }
Urvang Joshib100db72016-10-12 16:28:56 -07009623#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07009624
Yaowu Xuc27fc142016-08-22 16:08:15 -07009625 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
9626 &comp_mode_p);
9627
9628 for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
Urvang Joshifeb925f2016-12-05 10:37:29 -08009629 for (i = 0; i < TX_SIZES_ALL; i++) rate_uv_intra[i] = INT_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009630 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
9631 for (i = 0; i < MB_MODE_COUNT; ++i) {
9632 for (k = 0; k < TOTAL_REFS_PER_FRAME; ++k) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009633 args.single_filter[i][k] = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009634 }
9635 }
9636
9637 rd_cost->rate = INT_MAX;
9638#if CONFIG_SUPERTX
9639 *returnrate_nocoef = INT_MAX;
9640#endif // CONFIG_SUPERTX
9641
Zoe Liud1ac0322017-06-05 13:59:12 -07009642#if CONFIG_SPEED_REFS
9643 memset(x->mbmi_ext->ref_mvs, 0, sizeof(x->mbmi_ext->ref_mvs));
9644#endif // CONFIG_SPEED_REFS
9645
Yaowu Xuc27fc142016-08-22 16:08:15 -07009646 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9647 x->pred_mv_sad[ref_frame] = INT_MAX;
9648 x->mbmi_ext->mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009649#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009650 x->mbmi_ext->compound_mode_context[ref_frame] = 0;
Sebastien Alaiwane140c502017-04-27 09:52:34 +02009651#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009652 if (cpi->ref_frame_flags & flag_list[ref_frame]) {
9653 assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
9654 setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
9655 frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
9656 }
9657 frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
Sarah Parkere5299862016-08-16 14:57:37 -07009658#if CONFIG_GLOBAL_MOTION
9659 frame_mv[ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009660 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009661 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9662 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009663 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009664#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009665 frame_mv[ZEROMV][ref_frame].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -07009666#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009667#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07009668 frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
Zoe Liu85b66462017-04-20 14:28:19 -07009669#if CONFIG_COMPOUND_SINGLEREF
9670 frame_mv[SR_NEW_NEWMV][ref_frame].as_int = INVALID_MV;
9671 frame_comp_mv[SR_NEW_NEWMV][ref_frame].as_int = INVALID_MV;
9672#endif // CONFIG_COMPOUND_SINGLEREF
Sarah Parkerc2d38712017-01-24 15:15:41 -08009673#if CONFIG_GLOBAL_MOTION
9674 frame_mv[ZERO_ZEROMV][ref_frame].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -08009675 gm_get_motion_vector(&cm->global_motion[ref_frame],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009676 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
9677 0)
Sarah Parkerc2d38712017-01-24 15:15:41 -08009678 .as_int;
9679#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009680 frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
Sarah Parkerc2d38712017-01-24 15:15:41 -08009681#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07009682#endif // CONFIG_EXT_INTER
9683 }
9684
Yaowu Xuc27fc142016-08-22 16:08:15 -07009685 for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
9686 MODE_INFO *const mi = xd->mi[0];
9687 int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
9688 x->mbmi_ext->mode_context[ref_frame] = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07009689 av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
9690 mbmi_ext->ref_mv_stack[ref_frame],
Yaowu Xuc27fc142016-08-22 16:08:15 -07009691#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009692 mbmi_ext->compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -07009693#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07009694 candidates, mi_row, mi_col, NULL, NULL,
9695 mbmi_ext->mode_context);
Jingning Han731af492016-11-17 11:53:23 -08009696 if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
9697 MV_REFERENCE_FRAME rf[2];
9698 av1_set_ref_frame(rf, ref_frame);
David Barkercdcac6d2016-12-01 17:04:16 +00009699 if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
9700 frame_mv[ZEROMV][rf[0]].as_int ||
9701 mbmi_ext->ref_mvs[rf[0]][1].as_int !=
9702 frame_mv[ZEROMV][rf[0]].as_int ||
9703 mbmi_ext->ref_mvs[rf[1]][0].as_int !=
9704 frame_mv[ZEROMV][rf[1]].as_int ||
9705 mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
Jingning Han731af492016-11-17 11:53:23 -08009706 mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
9707 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009708 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07009709
Yue Chencb60b182016-10-13 15:18:22 -07009710#if CONFIG_MOTION_VAR
Yue Chen5329a2b2017-02-28 17:33:00 +08009711 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
Jingning Hanad586b92017-05-23 10:24:57 -07009712
Yue Chenf7ba6472017-04-19 11:08:58 -07009713 if (check_num_overlappable_neighbors(mbmi) &&
9714 is_motion_variation_allowed_bsize(bsize)) {
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009715 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
9716 args.above_pred_buf, dst_width1,
9717 dst_height1, args.above_pred_stride);
Yue Chen5329a2b2017-02-28 17:33:00 +08009718 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col,
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009719 args.left_pred_buf, dst_width2,
9720 dst_height2, args.left_pred_stride);
Jingning Han91d9a792017-04-18 12:01:52 -07009721 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
9722 mi_col);
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -08009723 calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
9724 args.above_pred_stride[0], args.left_pred_buf[0],
9725 args.left_pred_stride[0]);
Yue Chen5329a2b2017-02-28 17:33:00 +08009726 }
Yue Chencb60b182016-10-13 15:18:22 -07009727#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07009728
9729 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
9730 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) {
9731// Skip checking missing references in both single and compound reference
9732// modes. Note that a mode will be skipped iff both reference frames
9733// are masked out.
Zoe Liuc082bbc2017-05-17 13:31:37 -07009734#if CONFIG_EXT_COMP_REFS
9735 ref_frame_skip_mask[0] |= (1 << ref_frame);
9736 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9737#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07009738#if CONFIG_EXT_REFS
9739 if (ref_frame == BWDREF_FRAME || ref_frame == ALTREF_FRAME) {
9740 ref_frame_skip_mask[0] |= (1 << ref_frame);
9741 ref_frame_skip_mask[1] |= ((1 << ref_frame) | 0x01);
9742 } else {
9743#endif // CONFIG_EXT_REFS
9744 ref_frame_skip_mask[0] |= (1 << ref_frame);
9745 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9746#if CONFIG_EXT_REFS
9747 }
9748#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -07009749#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07009750 } else {
9751 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
9752 // Skip fixed mv modes for poor references
9753 if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
9754 mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
9755 break;
9756 }
9757 }
9758 }
9759 // If the segment reference frame feature is enabled....
9760 // then do nothing if the current ref frame is not allowed..
9761 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
9762 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
9763 ref_frame_skip_mask[0] |= (1 << ref_frame);
9764 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9765 }
9766 }
9767
9768 // Disable this drop out case if the ref frame
9769 // segment level feature is enabled for this segment. This is to
9770 // prevent the possibility that we end up unable to pick any mode.
9771 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
9772 // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
9773 // unless ARNR filtering is enabled in which case we want
9774 // an unfiltered alternative. We allow near/nearest as well
9775 // because they may result in zero-zero MVs but be cheaper.
9776 if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
Sarah Parkere5299862016-08-16 14:57:37 -07009777 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009778 ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
9779#if CONFIG_EXT_REFS
9780 (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
9781 (1 << BWDREF_FRAME) |
9782#endif // CONFIG_EXT_REFS
9783 (1 << GOLDEN_FRAME);
9784 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9785 // TODO(zoeliu): To further explore whether following needs to be done for
9786 // BWDREF_FRAME as well.
9787 mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
Sarah Parkere5299862016-08-16 14:57:37 -07009788#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +00009789 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
Sarah Parkerae7c4582017-02-28 16:30:30 -08009790 cm->allow_high_precision_mv, bsize,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -08009791 mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +00009792 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -07009793#else
9794 zeromv.as_int = 0;
9795#endif // CONFIG_GLOBAL_MOTION
9796 if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009797 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009798 if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009799 mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
9800#if CONFIG_EXT_INTER
Sarah Parkere5299862016-08-16 14:57:37 -07009801 if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009802 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
Sarah Parkere5299862016-08-16 14:57:37 -07009803 if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -07009804 mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
Zoe Liu85b66462017-04-20 14:28:19 -07009805#if CONFIG_COMPOUND_SINGLEREF
9806 if (frame_mv[SR_NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int ||
9807 frame_comp_mv[SR_NEAREST_NEARMV][ALTREF_FRAME].as_int !=
9808 zeromv.as_int)
9809 mode_skip_mask[ALTREF_FRAME] |= (1 << SR_NEAREST_NEARMV);
9810#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009811#endif // CONFIG_EXT_INTER
9812 }
9813 }
9814
9815 if (cpi->rc.is_src_frame_alt_ref) {
9816 if (sf->alt_ref_search_fp) {
9817 assert(cpi->ref_frame_flags & flag_list[ALTREF_FRAME]);
9818 mode_skip_mask[ALTREF_FRAME] = 0;
9819 ref_frame_skip_mask[0] = ~(1 << ALTREF_FRAME);
9820 ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK;
9821 }
9822 }
9823
9824 if (sf->alt_ref_search_fp)
9825 if (!cm->show_frame && x->pred_mv_sad[GOLDEN_FRAME] < INT_MAX)
9826 if (x->pred_mv_sad[ALTREF_FRAME] > (x->pred_mv_sad[GOLDEN_FRAME] << 1))
9827 mode_skip_mask[ALTREF_FRAME] |= INTER_ALL;
9828
9829 if (sf->adaptive_mode_search) {
9830 if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
9831 cpi->rc.frames_since_golden >= 3)
Yaowu Xu36bad472017-05-16 18:29:53 -07009832 if ((x->pred_mv_sad[GOLDEN_FRAME] >> 1) > x->pred_mv_sad[LAST_FRAME])
Yaowu Xuc27fc142016-08-22 16:08:15 -07009833 mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
9834 }
9835
9836 if (bsize > sf->max_intra_bsize) {
9837 ref_frame_skip_mask[0] |= (1 << INTRA_FRAME);
9838 ref_frame_skip_mask[1] |= (1 << INTRA_FRAME);
9839 }
9840
9841 mode_skip_mask[INTRA_FRAME] |=
9842 ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]);
9843
9844 for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) mode_threshold[i] = 0;
9845 for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i)
9846 mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5;
9847
9848 midx = sf->schedule_mode_search ? mode_skip_start : 0;
9849 while (midx > 4) {
9850 uint8_t end_pos = 0;
9851 for (i = 5; i < midx; ++i) {
9852 if (mode_threshold[mode_map[i - 1]] > mode_threshold[mode_map[i]]) {
9853 uint8_t tmp = mode_map[i];
9854 mode_map[i] = mode_map[i - 1];
9855 mode_map[i - 1] = tmp;
9856 end_pos = i;
9857 }
9858 }
9859 midx = end_pos;
9860 }
9861
9862 if (cpi->sf.tx_type_search.fast_intra_tx_type_search)
9863 x->use_default_intra_tx_type = 1;
9864 else
9865 x->use_default_intra_tx_type = 0;
9866
9867 if (cpi->sf.tx_type_search.fast_inter_tx_type_search)
9868 x->use_default_inter_tx_type = 1;
9869 else
9870 x->use_default_inter_tx_type = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009871#if CONFIG_PVQ
9872 od_encode_checkpoint(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009873#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009874#if CONFIG_EXT_INTER
9875 for (i = 0; i < MB_MODE_COUNT; ++i)
9876 for (ref_frame = 0; ref_frame < TOTAL_REFS_PER_FRAME; ++ref_frame)
9877 modelled_rd[i][ref_frame] = INT64_MAX;
9878#endif // CONFIG_EXT_INTER
9879
9880 for (midx = 0; midx < MAX_MODES; ++midx) {
9881 int mode_index;
9882 int mode_excluded = 0;
9883 int64_t this_rd = INT64_MAX;
9884 int disable_skip = 0;
9885 int compmode_cost = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009886 int rate2 = 0, rate_y = 0, rate_uv = 0;
9887 int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -07009888#if CONFIG_DAALA_DIST && CONFIG_CB4X4
9889 int64_t distortion2_y = 0;
9890 int64_t total_sse_y = INT64_MAX;
9891#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07009892 int skippable = 0;
9893 int this_skip2 = 0;
9894 int64_t total_sse = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009895 uint8_t ref_frame_type;
Yushin Cho77bba8d2016-11-04 16:36:56 -07009896#if CONFIG_PVQ
9897 od_encode_rollback(&x->daala_enc, &pre_buf);
Fergus Simpson4063a682017-02-28 16:52:22 -08009898#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07009899 mode_index = mode_map[midx];
Yaowu Xuf883b422016-08-30 14:01:10 -07009900 this_mode = av1_mode_order[mode_index].mode;
9901 ref_frame = av1_mode_order[mode_index].ref_frame[0];
9902 second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
Yaowu Xu4306b6e2016-09-27 12:55:32 -07009903 mbmi->ref_mv_idx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009904
9905#if CONFIG_EXT_INTER
9906 if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
9907 // Mode must by compatible
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -08009908 if (!is_interintra_allowed_mode(this_mode)) continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -07009909 if (!is_interintra_allowed_bsize(bsize)) continue;
9910 }
9911
9912 if (is_inter_compound_mode(this_mode)) {
9913 frame_mv[this_mode][ref_frame].as_int =
9914 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9915 frame_mv[this_mode][second_ref_frame].as_int =
9916 frame_mv[compound_ref1_mode(this_mode)][second_ref_frame].as_int;
Zoe Liu85b66462017-04-20 14:28:19 -07009917#if CONFIG_COMPOUND_SINGLEREF
9918 } else if (is_inter_singleref_comp_mode(this_mode)) {
9919 frame_mv[this_mode][ref_frame].as_int =
9920 frame_mv[compound_ref0_mode(this_mode)][ref_frame].as_int;
9921 frame_comp_mv[this_mode][ref_frame].as_int =
9922 frame_mv[compound_ref1_mode(this_mode)][ref_frame].as_int;
9923#endif // CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -07009924 }
9925#endif // CONFIG_EXT_INTER
9926
9927 // Look at the reference frame of the best mode so far and set the
9928 // skip mask to look at a subset of the remaining modes.
9929 if (midx == mode_skip_start && best_mode_index >= 0) {
9930 switch (best_mbmode.ref_frame[0]) {
9931 case INTRA_FRAME: break;
9932 case LAST_FRAME:
9933 ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK;
9934 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9935 break;
9936#if CONFIG_EXT_REFS
9937 case LAST2_FRAME:
9938 ref_frame_skip_mask[0] |= LAST2_FRAME_MODE_MASK;
9939 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9940 break;
9941 case LAST3_FRAME:
9942 ref_frame_skip_mask[0] |= LAST3_FRAME_MODE_MASK;
9943 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9944 break;
9945#endif // CONFIG_EXT_REFS
9946 case GOLDEN_FRAME:
9947 ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK;
9948 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9949 break;
9950#if CONFIG_EXT_REFS
9951 case BWDREF_FRAME:
9952 ref_frame_skip_mask[0] |= BWDREF_FRAME_MODE_MASK;
9953 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9954 break;
9955#endif // CONFIG_EXT_REFS
9956 case ALTREF_FRAME: ref_frame_skip_mask[0] |= ALTREF_FRAME_MODE_MASK;
9957#if CONFIG_EXT_REFS
9958 ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
9959#endif // CONFIG_EXT_REFS
9960 break;
Emil Keyder01770b32017-01-20 18:03:11 -05009961 case NONE_FRAME:
Yaowu Xuc27fc142016-08-22 16:08:15 -07009962 case TOTAL_REFS_PER_FRAME:
9963 assert(0 && "Invalid Reference frame");
9964 break;
9965 }
9966 }
9967
9968 if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07009969 (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
Yaowu Xuc27fc142016-08-22 16:08:15 -07009970 continue;
9971
Zoe Liuc082bbc2017-05-17 13:31:37 -07009972#if CONFIG_EXT_COMP_REFS
9973// TODO(zoeliu): Following toggle between #if 0/1 and the bug will manifest
9974// itself.
9975#if 0
9976 if (!(cpi->ref_frame_flags & flag_list[ref_frame]) ||
9977 (second_ref_frame > INTRA_FRAME &&
9978 (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))))
9979 printf("Frame=%d, bsize=%d, (mi_row,mi_col)=(%d,%d), ref_frame=%d, "
9980 "second_ref_frame=%d\n", cm->current_video_frame, bsize, mi_row,
9981 mi_col, ref_frame, second_ref_frame);
9982
9983 if (!(cpi->ref_frame_flags & flag_list[ref_frame])) continue;
9984 if (second_ref_frame > INTRA_FRAME &&
9985 (!(cpi->ref_frame_flags & flag_list[second_ref_frame])))
9986 continue;
9987#endif // 0
9988
9989#if !USE_UNI_COMP_REFS
9990 // NOTE(zoeliu): Temporarily disable uni-directional comp refs
9991 if (second_ref_frame > INTRA_FRAME) {
9992 if (!((ref_frame < BWDREF_FRAME) ^ (second_ref_frame < BWDREF_FRAME)))
9993 continue;
9994 }
9995 assert(second_ref_frame <= INTRA_FRAME ||
9996 ((ref_frame < BWDREF_FRAME) ^ (second_ref_frame < BWDREF_FRAME)));
9997#endif // !USE_UNI_COMP_REFS
9998#endif // CONFIG_EXT_COMP_REFS
9999
Yaowu Xuc27fc142016-08-22 16:08:15 -070010000 if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue;
10001
10002 // Test best rd so far against threshold for trying this mode.
10003 if (best_mode_skippable && sf->schedule_mode_search)
10004 mode_threshold[mode_index] <<= 1;
10005
10006 if (best_rd < mode_threshold[mode_index]) continue;
10007
Yunqing Wangff4fa062017-04-21 10:56:08 -070010008 // This is only used in motion vector unit test.
10009 if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
10010
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +020010011#if CONFIG_ONE_SIDED_COMPOUND // Changes LL bitstream
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +020010012#if CONFIG_EXT_REFS
10013 if (cpi->oxcf.pass == 0) {
10014 // Complexity-compression trade-offs
10015 // if (ref_frame == ALTREF_FRAME) continue;
10016 // if (ref_frame == BWDREF_FRAME) continue;
10017 if (second_ref_frame == ALTREF_FRAME) continue;
10018 // if (second_ref_frame == BWDREF_FRAME) continue;
10019 }
10020#endif
10021#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010022 comp_pred = second_ref_frame > INTRA_FRAME;
10023 if (comp_pred) {
10024 if (!cpi->allow_comp_inter_inter) continue;
10025
10026 // Skip compound inter modes if ARF is not available.
10027 if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
10028
10029 // Do not allow compound prediction if the segment level reference frame
10030 // feature is in use as in this case there can only be one reference.
10031 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
10032
10033 if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
10034 best_mode_index >= 0 && best_mbmode.ref_frame[0] == INTRA_FRAME)
10035 continue;
10036
10037 mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
10038 } else {
10039 if (ref_frame != INTRA_FRAME)
10040 mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
10041 }
10042
10043 if (ref_frame == INTRA_FRAME) {
10044 if (sf->adaptive_mode_search)
10045 if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_pred_sse)
10046 continue;
10047
10048 if (this_mode != DC_PRED) {
10049 // Disable intra modes other than DC_PRED for blocks with low variance
10050 // Threshold for intra skipping based on source variance
10051 // TODO(debargha): Specialize the threshold for super block sizes
10052 const unsigned int skip_intra_var_thresh = 64;
10053 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
10054 x->source_variance < skip_intra_var_thresh)
10055 continue;
10056 // Only search the oblique modes if the best so far is
10057 // one of the neighboring directional modes
10058 if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
10059 (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
10060 if (best_mode_index >= 0 && best_mbmode.ref_frame[0] > INTRA_FRAME)
10061 continue;
10062 }
10063 if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
10064 if (conditional_skipintra(this_mode, best_intra_mode)) continue;
10065 }
10066 }
Sarah Parkere5299862016-08-16 14:57:37 -070010067#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +000010068 } else if (cm->global_motion[ref_frame].wmtype == IDENTITY &&
Sarah Parkere5299862016-08-16 14:57:37 -070010069 (!comp_pred ||
David Barkercf3d0b02016-11-10 10:14:49 +000010070 cm->global_motion[second_ref_frame].wmtype == IDENTITY)) {
Sarah Parkere5299862016-08-16 14:57:37 -070010071#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010072 } else {
Sarah Parkere5299862016-08-16 14:57:37 -070010073#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010074 const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
10075 if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010076#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010077 mbmi_ext->compound_mode_context,
Sebastien Alaiwane140c502017-04-27 09:52:34 +020010078#endif // CONFIG_EXT_INTER
David Barker45390c12017-02-20 14:44:40 +000010079 frame_mv, this_mode, ref_frames, bsize, -1,
10080 mi_row, mi_col))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010081 continue;
10082 }
10083
10084 mbmi->mode = this_mode;
10085 mbmi->uv_mode = DC_PRED;
10086 mbmi->ref_frame[0] = ref_frame;
10087 mbmi->ref_frame[1] = second_ref_frame;
Urvang Joshib100db72016-10-12 16:28:56 -070010088#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010089 pmi->palette_size[0] = 0;
10090 pmi->palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070010091#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -070010092#if CONFIG_FILTER_INTRA
10093 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10094 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10095#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010096 // Evaluate all sub-pel filters irrespective of whether we can use
10097 // them for this frame.
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070010098
10099 set_default_interp_filters(mbmi, cm->interp_filter);
10100
Yaowu Xuc27fc142016-08-22 16:08:15 -070010101 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
Yue Chencb60b182016-10-13 15:18:22 -070010102 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010103
10104 x->skip = 0;
10105 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
10106
10107 // Select prediction reference frames.
10108 for (i = 0; i < MAX_MB_PLANE; i++) {
10109 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
10110 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
10111 }
10112
Zoe Liu85b66462017-04-20 14:28:19 -070010113#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10114 // Single ref compound mode
10115 if (!comp_pred && is_inter_singleref_comp_mode(mbmi->mode)) {
10116 xd->block_refs[1] = xd->block_refs[0];
10117 for (i = 0; i < MAX_MB_PLANE; i++)
10118 xd->plane[i].pre[1] = xd->plane[i].pre[0];
10119 }
10120#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10121
Yue Chen4d26acb2017-05-01 12:28:34 -070010122#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010123 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
Yue Chen4d26acb2017-05-01 12:28:34 -070010124#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010125
10126 if (ref_frame == INTRA_FRAME) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010127 RD_STATS rd_stats_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010128 TX_SIZE uv_tx;
10129 struct macroblockd_plane *const pd = &xd->plane[1];
10130#if CONFIG_EXT_INTRA
hui su45dc5972016-12-08 17:42:50 -080010131 is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
Joe Young830d4ce2017-05-30 17:48:13 -070010132 if (is_directional_mode && av1_use_angle_delta(bsize)) {
hui su45dc5972016-12-08 17:42:50 -080010133 int rate_dummy;
hui su9a416f52017-01-13 11:37:53 -080010134 int64_t model_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010135 if (!angle_stats_ready) {
10136 const int src_stride = x->plane[0].src.stride;
10137 const uint8_t *src = x->plane[0].src.buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010138#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070010139 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
hui su9cc10652017-04-27 17:22:07 -070010140 highbd_angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010141 directional_mode_skip_mask);
10142 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020010143#endif // CONFIG_HIGHBITDEPTH
hui su9cc10652017-04-27 17:22:07 -070010144 angle_estimation(src, src_stride, rows, cols, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010145 directional_mode_skip_mask);
10146 angle_stats_ready = 1;
10147 }
10148 if (directional_mode_skip_mask[mbmi->mode]) continue;
hui su45dc5972016-12-08 17:42:50 -080010149 rd_stats_y.rate = INT_MAX;
Yue Chenb0f808b2017-04-26 11:55:14 -070010150 rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rd_stats_y, bsize,
10151 intra_mode_cost[mbmi->mode], best_rd,
10152 &model_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010153 } else {
10154 mbmi->angle_delta[0] = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010155 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010156 }
10157#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010158 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
hui su45dc5972016-12-08 17:42:50 -080010159#endif // CONFIG_EXT_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010160 rate_y = rd_stats_y.rate;
10161 distortion_y = rd_stats_y.dist;
10162 skippable = rd_stats_y.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010163
10164 if (rate_y == INT_MAX) continue;
10165
hui su5db97432016-10-14 16:10:14 -070010166#if CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010167 if (mbmi->mode == DC_PRED) dc_skipped = 0;
hui su5db97432016-10-14 16:10:14 -070010168#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010169
Debargha Mukherjee2f123402016-08-30 17:43:38 -070010170 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][pd->subsampling_x]
10171 [pd->subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010172 if (rate_uv_intra[uv_tx] == INT_MAX) {
10173 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070010174 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
10175 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Urvang Joshib100db72016-10-12 16:28:56 -070010176#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010177 if (try_palette) pmi_uv[uv_tx] = *pmi;
Urvang Joshib100db72016-10-12 16:28:56 -070010178#endif // CONFIG_PALETTE
10179
Yaowu Xuc27fc142016-08-22 16:08:15 -070010180#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010181 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
10182#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010183#if CONFIG_FILTER_INTRA
10184 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
10185#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010186 }
10187
10188 rate_uv = rate_uv_tokenonly[uv_tx];
Urvang Joshi368fbc92016-10-17 16:31:34 -070010189 distortion_uv = dist_uvs[uv_tx];
10190 skippable = skippable && skip_uvs[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010191 mbmi->uv_mode = mode_uv[uv_tx];
Urvang Joshib100db72016-10-12 16:28:56 -070010192#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010193 if (try_palette) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010194 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
10195 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
10196 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
10197 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
10198 }
Urvang Joshib100db72016-10-12 16:28:56 -070010199#endif // CONFIG_PALETTE
10200
Yaowu Xuc27fc142016-08-22 16:08:15 -070010201#if CONFIG_EXT_INTRA
10202 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010203#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010204#if CONFIG_FILTER_INTRA
10205 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
10206 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
10207 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
10208 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
10209 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
10210 }
10211#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010212
Jingning Han36fe3202017-02-20 22:31:49 -080010213#if CONFIG_CB4X4
10214 rate2 = rate_y + intra_mode_cost[mbmi->mode];
10215 if (!x->skip_chroma_rd)
10216 rate2 += rate_uv + cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
10217#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010218 rate2 = rate_y + intra_mode_cost[mbmi->mode] + rate_uv +
10219 cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode];
Fergus Simpson4063a682017-02-28 16:52:22 -080010220#endif // CONFIG_CB4X4
Jingning Han36fe3202017-02-20 22:31:49 -080010221
Urvang Joshib100db72016-10-12 16:28:56 -070010222#if CONFIG_PALETTE
hui su9bc1d8d2017-03-24 12:36:03 -070010223 if (try_palette && mbmi->mode == DC_PRED) {
Yaowu Xuf883b422016-08-30 14:01:10 -070010224 rate2 += av1_cost_bit(
10225 av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx], 0);
hui su9bc1d8d2017-03-24 12:36:03 -070010226 }
Urvang Joshib100db72016-10-12 16:28:56 -070010227#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070010228
Jingning Hanbf9c6b72016-12-14 14:50:45 -080010229 if (!xd->lossless[mbmi->segment_id] && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010230 // super_block_yrd above includes the cost of the tx_size in the
10231 // tokenonly rate, but for intra blocks, tx_size is always coded
10232 // (prediction granularity), so we account for it in the full rate,
10233 // not the tokenonly rate.
Urvang Joshifeb925f2016-12-05 10:37:29 -080010234 rate_y -= tx_size_cost(cpi, x, bsize, mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010235 }
10236#if CONFIG_EXT_INTRA
10237 if (is_directional_mode) {
hui sueda3d762016-12-06 16:58:23 -080010238#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -070010239 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su0a6731f2017-04-26 15:23:47 -070010240 const int p_angle =
10241 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -070010242 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -070010243 rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
hui sueda3d762016-12-06 16:58:23 -080010244#endif // CONFIG_INTRA_INTERP
Joe Young830d4ce2017-05-30 17:48:13 -070010245 if (av1_use_angle_delta(bsize)) {
10246 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10247 MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
10248 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010249 }
Joe Young830d4ce2017-05-30 17:48:13 -070010250 if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
10251 av1_use_angle_delta(bsize)) {
hui su0a6731f2017-04-26 15:23:47 -070010252 rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
10253 MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010254 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010255#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010256#if CONFIG_FILTER_INTRA
10257 if (mbmi->mode == DC_PRED) {
10258 rate2 +=
10259 av1_cost_bit(cm->fc->filter_intra_probs[0],
10260 mbmi->filter_intra_mode_info.use_filter_intra_mode[0]);
10261 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[0]) {
10262 rate2 += write_uniform_cost(
10263 FILTER_INTRA_MODES,
10264 mbmi->filter_intra_mode_info.filter_intra_mode[0]);
10265 }
10266 }
10267 if (mbmi->uv_mode == DC_PRED) {
10268 rate2 +=
10269 av1_cost_bit(cpi->common.fc->filter_intra_probs[1],
10270 mbmi->filter_intra_mode_info.use_filter_intra_mode[1]);
10271 if (mbmi->filter_intra_mode_info.use_filter_intra_mode[1])
10272 rate2 += write_uniform_cost(
10273 FILTER_INTRA_MODES,
10274 mbmi->filter_intra_mode_info.filter_intra_mode[1]);
10275 }
10276#endif // CONFIG_FILTER_INTRA
Zoe Liu1157d502017-04-30 07:57:14 -070010277 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
Yaowu Xuc27fc142016-08-22 16:08:15 -070010278 rate2 += intra_cost_penalty;
10279 distortion2 = distortion_y + distortion_uv;
Yushin Cho63927c42017-05-23 15:41:05 -070010280#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10281 if (bsize < BLOCK_8X8) distortion2_y = distortion_y;
10282#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010283 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010284 int_mv backup_ref_mv[2];
10285
Jingning Hanc41a5492017-02-24 11:18:52 -080010286#if !SUB8X8_COMP_REF
Jingning Han69d21012017-05-14 16:51:27 -070010287 if (bsize == BLOCK_4X4 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
Fergus Simpson4063a682017-02-28 16:52:22 -080010288#endif // !SUB8X8_COMP_REF
Jingning Hanc41a5492017-02-24 11:18:52 -080010289
Yaowu Xuc27fc142016-08-22 16:08:15 -070010290 backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
10291 if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
Yue Chen4d26acb2017-05-01 12:28:34 -070010292#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010293 if (second_ref_frame == INTRA_FRAME) {
10294 if (best_single_inter_ref != ref_frame) continue;
Debargha Mukherjeecb603792016-10-04 13:10:23 -070010295 mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
hui su5db97432016-10-14 16:10:14 -070010296// TODO(debargha|geza.lore):
10297// Should we use ext_intra modes for interintra?
Yaowu Xuc27fc142016-08-22 16:08:15 -070010298#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010299 mbmi->angle_delta[0] = 0;
10300 mbmi->angle_delta[1] = 0;
hui sueda3d762016-12-06 16:58:23 -080010301#if CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010302 mbmi->intra_filter = INTRA_FILTER_LINEAR;
hui sueda3d762016-12-06 16:58:23 -080010303#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -070010304#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070010305#if CONFIG_FILTER_INTRA
10306 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
10307 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
10308#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010309 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010310#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010311 mbmi->ref_mv_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010312 ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010313
David Barker404b2e82017-03-27 13:07:47 +010010314#if CONFIG_EXT_INTER
10315 if (comp_pred) {
10316 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker3dfba992017-04-03 16:10:09 +010010317 int ref_mv_idx = 0;
10318 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10319 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10320 // mbmi->ref_mv_idx (like NEWMV)
10321 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10322 ref_mv_idx = 1;
10323
10324 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10325 int_mv this_mv =
10326 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
David Barker404b2e82017-03-27 13:07:47 +010010327 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10328 xd->n8_h << MI_SIZE_LOG2, xd);
10329 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10330 }
David Barker3dfba992017-04-03 16:10:09 +010010331 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10332 int_mv this_mv =
10333 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
David Barker404b2e82017-03-27 13:07:47 +010010334 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10335 xd->n8_h << MI_SIZE_LOG2, xd);
10336 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10337 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010338 }
Zoe Liu85b66462017-04-20 14:28:19 -070010339#if CONFIG_COMPOUND_SINGLEREF
10340 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
10341 if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
10342 // TODO(zoeliu): To further investigate which ref_mv_idx should be
10343 // chosen for the mode of SR_NEAR_NEWMV.
10344 int ref_mv_idx = 0;
10345 // Special case: SR_NEAR_NEWMV mode use
10346 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10347 // mbmi->ref_mv_idx (like NEWMV)
10348 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx = 1;
10349
10350 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
10351 compound_ref1_mode(mbmi->mode) == NEWMV) {
10352 int_mv this_mv =
10353 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10354 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10355 xd->n8_h << MI_SIZE_LOG2, xd);
10356 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10357 }
10358 }
10359#endif // CONFIG_COMPOUND_SINGLEREF
David Barker404b2e82017-03-27 13:07:47 +010010360 } else {
10361#endif // CONFIG_EXT_INTER
Zoe Liu1157d502017-04-30 07:57:14 -070010362 if (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
David Barker404b2e82017-03-27 13:07:47 +010010363 int ref;
10364 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10365 int_mv this_mv =
10366 (ref == 0) ? mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv
10367 : mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10368 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10369 xd->n8_h << MI_SIZE_LOG2, xd);
10370 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10371 }
10372 }
10373#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010374 }
David Barker404b2e82017-03-27 13:07:47 +010010375#endif // CONFIG_EXT_INTER
Angie Chiang76159122016-11-09 12:13:22 -080010376 {
10377 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
10378 av1_init_rd_stats(&rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010379#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10380 // While av1 master uses rd_stats_y.rate through out the codebase,
10381 // which is set when handle_inter_moden is called, the daala-dist code
10382 // in rd_pick_partition() for cb4x4 and sub8x8 blocks need to know
10383 // .dist_y which comes from rd_stats_y.dist and rd_stats_y.sse.
10384 // The problem is rd_stats_y.dist and rd_stats_y.sse are sometimes not
10385 // initialized when rd_stats.skip = 1,
10386 // then instead rd_stats.dist and rd_stats.sse have the
10387 // combined luma and chroma dist and sse.
10388 // This can be seen inside motion_mode_rd(), which is called by
10389 // handle_inter_mode().
10390 if (bsize < BLOCK_8X8) av1_init_rd_stats(&rd_stats_y);
10391#endif
Angie Chiang76159122016-11-09 12:13:22 -080010392 rd_stats.rate = rate2;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010393
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010394 // Point to variables that are maintained between loop iterations
10395 args.single_newmv = single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010396#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010397 args.single_newmv_rate = single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010398 args.modelled_rd = modelled_rd;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010399#endif // CONFIG_EXT_INTER
Fergus Simpson3424c2d2017-03-09 11:48:15 -080010400 this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
10401 &rd_stats_uv, &disable_skip, frame_mv,
Zoe Liu85b66462017-04-20 14:28:19 -070010402#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10403 frame_comp_mv,
10404#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010405 mi_row, mi_col, &args, best_rd);
Angie Chiang76159122016-11-09 12:13:22 -080010406
10407 rate2 = rd_stats.rate;
10408 skippable = rd_stats.skip;
10409 distortion2 = rd_stats.dist;
10410 total_sse = rd_stats.sse;
10411 rate_y = rd_stats_y.rate;
10412 rate_uv = rd_stats_uv.rate;
Yushin Cho63927c42017-05-23 15:41:05 -070010413#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010414 if (bsize < BLOCK_8X8) {
10415 if (rd_stats_y.rate != INT_MAX) {
10416 assert(rd_stats_y.sse < INT64_MAX);
10417 assert(rd_stats_y.dist < INT64_MAX);
10418 }
10419 total_sse_y = rd_stats_y.sse;
10420 distortion2_y = rd_stats_y.dist;
10421 }
Yushin Cho63927c42017-05-23 15:41:05 -070010422#endif
Angie Chiang76159122016-11-09 12:13:22 -080010423 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070010424
David Barker404b2e82017-03-27 13:07:47 +010010425// TODO(jingning): This needs some refactoring to improve code quality
10426// and reduce redundant steps.
10427#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070010428#if CONFIG_COMPOUND_SINGLEREF
10429 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
10430 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10431 ((mbmi->mode == NEWMV || mbmi->mode == SR_NEW_NEWMV ||
10432 mbmi->mode == NEW_NEWMV) &&
10433 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
10434#else // !CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010010435 if ((have_nearmv_in_inter_mode(mbmi->mode) &&
David Barker404b2e82017-03-27 13:07:47 +010010436 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10437 ((mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) &&
10438 mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Zoe Liu85b66462017-04-20 14:28:19 -070010439#endif // CONFIG_COMPOUND_SINGLEREF
10440#else // !CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010441 if ((mbmi->mode == NEARMV &&
10442 mbmi_ext->ref_mv_count[ref_frame_type] > 2) ||
10443 (mbmi->mode == NEWMV && mbmi_ext->ref_mv_count[ref_frame_type] > 1)) {
Zoe Liu85b66462017-04-20 14:28:19 -070010444#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010445 int_mv backup_mv = frame_mv[NEARMV][ref_frame];
10446 MB_MODE_INFO backup_mbmi = *mbmi;
10447 int backup_skip = x->skip;
10448 int64_t tmp_ref_rd = this_rd;
10449 int ref_idx;
10450
Yue Chen6e601e92016-12-05 18:19:00 -080010451// TODO(jingning): This should be deprecated shortly.
10452#if CONFIG_EXT_INTER
David Barker3dfba992017-04-03 16:10:09 +010010453 int idx_offset = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
Yue Chen6e601e92016-12-05 18:19:00 -080010454#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070010455 int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
Fergus Simpson4063a682017-02-28 16:52:22 -080010456#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010457 int ref_set =
Yaowu Xuf883b422016-08-30 14:01:10 -070010458 AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010459
10460 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010461 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx_offset);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010462 // Dummy
10463 int_mv backup_fmv[2];
10464 backup_fmv[0] = frame_mv[NEWMV][ref_frame];
10465 if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame];
10466
Debargha Mukherjee1ae9f2c2016-10-04 14:30:16 -070010467 rate2 += (rate2 < INT_MAX ? cpi->drl_mode_cost0[drl_ctx][0] : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010468
10469 if (this_rd < INT64_MAX) {
Urvang Joshi70006e42017-06-14 16:08:55 -070010470 if (RDCOST(x->rdmult, rate_y + rate_uv, distortion2) <
10471 RDCOST(x->rdmult, 0, total_sse))
10472 tmp_ref_rd = RDCOST(
10473 x->rdmult, rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10474 distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010475 else
Urvang Joshi70006e42017-06-14 16:08:55 -070010476 tmp_ref_rd = RDCOST(
10477 x->rdmult, rate2 + av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10478 rate_y - rate_uv,
10479 total_sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010480 }
10481#if CONFIG_VAR_TX
10482 for (i = 0; i < MAX_MB_PLANE; ++i)
10483 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10484 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010485#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010486
10487 for (ref_idx = 0; ref_idx < ref_set; ++ref_idx) {
10488 int64_t tmp_alt_rd = INT64_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010489 int dummy_disable_skip = 0;
10490 int ref;
10491 int_mv cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010492 RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010493
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010494 av1_invalid_rd_stats(&tmp_rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010495
Jingning Han52617b22017-04-11 12:50:08 -070010496 x->skip = 0;
Yaowu Xu5bfbfdf2016-11-22 16:43:34 -080010497
Yaowu Xuc27fc142016-08-22 16:08:15 -070010498 mbmi->ref_mv_idx = 1 + ref_idx;
10499
David Barker3dfba992017-04-03 16:10:09 +010010500#if CONFIG_EXT_INTER
10501 if (comp_pred) {
10502 int ref_mv_idx = mbmi->ref_mv_idx;
10503 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
10504 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10505 // mbmi->ref_mv_idx (like NEWMV)
10506 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV)
10507 ref_mv_idx = 1 + mbmi->ref_mv_idx;
10508
10509 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
10510 int_mv this_mv =
10511 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10512 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10513 xd->n8_h << MI_SIZE_LOG2, xd);
10514 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10515 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV) {
10516 int_mv this_mv =
10517 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10518 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10519 xd->n8_h << MI_SIZE_LOG2, xd);
10520 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10521 }
10522
10523 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
10524 int_mv this_mv =
10525 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
10526 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10527 xd->n8_h << MI_SIZE_LOG2, xd);
10528 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10529 } else if (compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10530 int_mv this_mv =
10531 mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
10532 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10533 xd->n8_h << MI_SIZE_LOG2, xd);
10534 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
10535 }
Zoe Liu85b66462017-04-20 14:28:19 -070010536#if CONFIG_COMPOUND_SINGLEREF
10537 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
10538 int ref_mv_idx = mbmi->ref_mv_idx;
10539 // Special case: SR_NEAR_NEWMV mode use
10540 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
10541 // mbmi->ref_mv_idx (like NEWMV)
10542 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx = 1 + mbmi->ref_mv_idx;
10543
10544 // TODO(zoeliu): For the mode of SR_NEAREST_NEWMV, as it only runs
10545 // the "if", not the "else if",
10546 // mbmi_ext->ref_mvs[mbmi->ref_frame[0]] takes the
10547 // value for "NEWMV", instead of "NEARESTMV".
10548 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
10549 compound_ref1_mode(mbmi->mode) == NEWMV) {
10550 int_mv this_mv =
10551 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
10552 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10553 xd->n8_h << MI_SIZE_LOG2, xd);
10554 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10555 } else if (compound_ref0_mode(mbmi->mode) == NEARESTMV ||
10556 compound_ref1_mode(mbmi->mode) == NEARESTMV) {
10557 int_mv this_mv =
10558 mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
10559 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10560 xd->n8_h << MI_SIZE_LOG2, xd);
10561 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
10562 }
10563#endif // CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010010564 } else {
10565#endif // CONFIG_EXT_INTER
10566 for (ref = 0; ref < 1 + comp_pred; ++ref) {
10567 int_mv this_mv =
10568 (ref == 0)
10569 ? mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10570 .this_mv
10571 : mbmi_ext->ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
10572 .comp_mv;
10573 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
10574 xd->n8_h << MI_SIZE_LOG2, xd);
10575 mbmi_ext->ref_mvs[mbmi->ref_frame[ref]][0] = this_mv;
10576 }
10577#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010578 }
David Barker3dfba992017-04-03 16:10:09 +010010579#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010580
10581 cur_mv =
10582 mbmi_ext->ref_mv_stack[ref_frame][mbmi->ref_mv_idx + idx_offset]
10583 .this_mv;
10584 clamp_mv2(&cur_mv.as_mv, xd);
10585
Alex Converse0fa0f422017-04-24 12:51:14 -070010586 if (!mv_check_bounds(&x->mv_limits, &cur_mv.as_mv)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010587 int_mv dummy_single_newmv[TOTAL_REFS_PER_FRAME] = { { 0 } };
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010588#if CONFIG_EXT_INTER
10589 int dummy_single_newmv_rate[TOTAL_REFS_PER_FRAME] = { 0 };
Fergus Simpson4063a682017-02-28 16:52:22 -080010590#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010591
10592 frame_mv[NEARMV][ref_frame] = cur_mv;
Angie Chiang76159122016-11-09 12:13:22 -080010593 av1_init_rd_stats(&tmp_rd_stats);
Yushin Choc0f6bf22017-06-09 16:08:02 -070010594#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10595 // With the same reason as 'rd_stats_y' passed to above
10596 // handle_inter_mode(), tmp_rd_stats_y.dist and
10597 // tmp_rd_stats_y.sse are sometimes not initialized, esp. when
10598 // tmp_rd_stats.skip = 1 and tmp_rd_stats.dist and .sse
10599 // represent combined luma and chroma .dist and .sse,
10600 // we should initialized tmp_rd_stats_y.
10601 if (bsize < BLOCK_8X8) av1_init_rd_stats(&tmp_rd_stats_y);
10602#endif
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010603 // Point to variables that are not maintained between iterations
10604 args.single_newmv = dummy_single_newmv;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010605#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010606 args.single_newmv_rate = dummy_single_newmv_rate;
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010607 args.modelled_rd = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010608#endif // CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070010609 tmp_alt_rd = handle_inter_mode(cpi, x, bsize, &tmp_rd_stats,
10610 &tmp_rd_stats_y, &tmp_rd_stats_uv,
10611 &dummy_disable_skip, frame_mv,
10612#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10613 frame_comp_mv,
10614#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10615 mi_row, mi_col, &args, best_rd);
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010616 // Prevent pointers from escaping local scope
10617 args.single_newmv = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010618#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070010619 args.single_newmv_rate = NULL;
Fergus Simpson073c6f32017-02-17 12:13:48 -080010620#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070010621 }
10622
10623 for (i = 0; i < mbmi->ref_mv_idx; ++i) {
10624 uint8_t drl1_ctx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -070010625 drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10626 i + idx_offset);
Angie Chiang76159122016-11-09 12:13:22 -080010627 tmp_rd_stats.rate +=
10628 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][1]
10629 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010630 }
10631
10632 if (mbmi_ext->ref_mv_count[ref_frame_type] >
10633 mbmi->ref_mv_idx + idx_offset + 1 &&
10634 ref_idx < ref_set - 1) {
10635 uint8_t drl1_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -070010636 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
10637 mbmi->ref_mv_idx + idx_offset);
Yaowu Xu83ed6fe2016-11-22 11:15:29 -080010638 tmp_rd_stats.rate +=
10639 (tmp_rd_stats.rate < INT_MAX ? cpi->drl_mode_cost0[drl1_ctx][0]
10640 : 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010641 }
10642
10643 if (tmp_alt_rd < INT64_MAX) {
Yue Chen69f18e12016-09-08 14:48:15 -070010644#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Urvang Joshi70006e42017-06-14 16:08:55 -070010645 tmp_alt_rd =
10646 RDCOST(x->rdmult, tmp_rd_stats.rate, tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010647#else
Urvang Joshi70006e42017-06-14 16:08:55 -070010648 if (RDCOST(x->rdmult, tmp_rd_stats_y.rate + tmp_rd_stats_uv.rate,
Angie Chiang76159122016-11-09 12:13:22 -080010649 tmp_rd_stats.dist) <
Urvang Joshi70006e42017-06-14 16:08:55 -070010650 RDCOST(x->rdmult, 0, tmp_rd_stats.sse))
10651 tmp_alt_rd = RDCOST(
10652 x->rdmult, tmp_rd_stats.rate +
10653 av1_cost_bit(av1_get_skip_prob(cm, xd), 0),
10654 tmp_rd_stats.dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010655 else
Urvang Joshi70006e42017-06-14 16:08:55 -070010656 tmp_alt_rd = RDCOST(
10657 x->rdmult, tmp_rd_stats.rate +
10658 av1_cost_bit(av1_get_skip_prob(cm, xd), 1) -
10659 tmp_rd_stats_y.rate - tmp_rd_stats_uv.rate,
10660 tmp_rd_stats.sse);
Yue Chen69f18e12016-09-08 14:48:15 -070010661#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010662 }
10663
10664 if (tmp_ref_rd > tmp_alt_rd) {
Angie Chiang76159122016-11-09 12:13:22 -080010665 rate2 = tmp_rd_stats.rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010666 disable_skip = dummy_disable_skip;
Angie Chiang76159122016-11-09 12:13:22 -080010667 distortion2 = tmp_rd_stats.dist;
10668 skippable = tmp_rd_stats.skip;
10669 rate_y = tmp_rd_stats_y.rate;
10670 rate_uv = tmp_rd_stats_uv.rate;
10671 total_sse = tmp_rd_stats.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010672 this_rd = tmp_alt_rd;
10673 tmp_ref_rd = tmp_alt_rd;
10674 backup_mbmi = *mbmi;
10675 backup_skip = x->skip;
Yushin Cho63927c42017-05-23 15:41:05 -070010676#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10677 if (bsize < BLOCK_8X8) {
Yushin Choc0f6bf22017-06-09 16:08:02 -070010678 if (tmp_rd_stats_y.rate != INT_MAX) {
10679 assert(tmp_rd_stats_y.sse < INT64_MAX);
10680 assert(tmp_rd_stats_y.dist < INT64_MAX);
10681 }
Yushin Cho63927c42017-05-23 15:41:05 -070010682 total_sse_y = tmp_rd_stats_y.sse;
10683 distortion2_y = tmp_rd_stats_y.dist;
10684 }
10685#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010686#if CONFIG_VAR_TX
10687 for (i = 0; i < MAX_MB_PLANE; ++i)
10688 memcpy(x->blk_skip_drl[i], x->blk_skip[i],
10689 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010690#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010691 } else {
10692 *mbmi = backup_mbmi;
10693 x->skip = backup_skip;
10694 }
10695 }
10696
10697 frame_mv[NEARMV][ref_frame] = backup_mv;
10698 frame_mv[NEWMV][ref_frame] = backup_fmv[0];
10699 if (comp_pred) frame_mv[NEWMV][second_ref_frame] = backup_fmv[1];
10700#if CONFIG_VAR_TX
10701 for (i = 0; i < MAX_MB_PLANE; ++i)
10702 memcpy(x->blk_skip[i], x->blk_skip_drl[i],
10703 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010704#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010705 }
10706 mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
10707 if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070010708
10709 if (this_rd == INT64_MAX) continue;
10710
Jingning Hanc41a5492017-02-24 11:18:52 -080010711#if SUB8X8_COMP_REF
Yaowu Xuf883b422016-08-30 14:01:10 -070010712 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Jingning Hanc41a5492017-02-24 11:18:52 -080010713#else
Jingning Han69d21012017-05-14 16:51:27 -070010714 if (mbmi->sb_type != BLOCK_4X4)
Jingning Hanc41a5492017-02-24 11:18:52 -080010715 compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
Fergus Simpson4063a682017-02-28 16:52:22 -080010716#endif // SUB8X8_COMP_REF
Yaowu Xuc27fc142016-08-22 16:08:15 -070010717
10718 if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
10719 }
10720
Yaowu Xuc27fc142016-08-22 16:08:15 -070010721 // Estimate the reference frame signaling cost and add it
10722 // to the rolling cost variable.
10723 if (comp_pred) {
Zoe Liuc082bbc2017-05-17 13:31:37 -070010724#if CONFIG_EXT_COMP_REFS
10725 rate2 += ref_costs_comp[ref_frame][second_ref_frame];
10726#else // !CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -070010727 rate2 += ref_costs_comp[ref_frame];
10728#if CONFIG_EXT_REFS
10729 rate2 += ref_costs_comp[second_ref_frame];
10730#endif // CONFIG_EXT_REFS
Zoe Liuc082bbc2017-05-17 13:31:37 -070010731#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -070010732 } else {
10733 rate2 += ref_costs_single[ref_frame];
10734 }
10735
Zoe Liu85b66462017-04-20 14:28:19 -070010736#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10737 // Add the cost to signal single/comp mode in single ref.
10738 if (!comp_pred && cm->reference_mode != COMPOUND_REFERENCE) {
10739 aom_prob singleref_comp_mode_p = av1_get_inter_mode_prob(cm, xd);
10740 rate2 += av1_cost_bit(singleref_comp_mode_p,
10741 is_inter_singleref_comp_mode(mbmi->mode));
10742 }
10743#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10744
Yue Chen69f18e12016-09-08 14:48:15 -070010745#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010746 if (ref_frame == INTRA_FRAME) {
10747#else
10748 if (!disable_skip) {
Yue Chen69f18e12016-09-08 14:48:15 -070010749#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010750 if (skippable) {
10751 // Back out the coefficient coding costs
10752 rate2 -= (rate_y + rate_uv);
10753 rate_y = 0;
10754 rate_uv = 0;
10755 // Cost the skip mb case
Yaowu Xuf883b422016-08-30 14:01:10 -070010756 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010757 } else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
Urvang Joshi70006e42017-06-14 16:08:55 -070010758 if (RDCOST(x->rdmult, rate_y + rate_uv + rate_skip0, distortion2) <
10759 RDCOST(x->rdmult, rate_skip1, total_sse)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010760 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010761 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010762 } else {
10763 // FIXME(rbultje) make this work for splitmv also
Yaowu Xuf883b422016-08-30 14:01:10 -070010764 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010765 distortion2 = total_sse;
10766 assert(total_sse >= 0);
10767 rate2 -= (rate_y + rate_uv);
10768 this_skip2 = 1;
10769 rate_y = 0;
10770 rate_uv = 0;
Yushin Cho63927c42017-05-23 15:41:05 -070010771#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010772 if (bsize < BLOCK_8X8) {
10773 assert(total_sse_y < INT64_MAX);
10774 distortion2_y = total_sse_y;
10775 }
Yushin Cho63927c42017-05-23 15:41:05 -070010776#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010777 }
10778 } else {
10779 // Add in the cost of the no skip flag.
Yaowu Xuf883b422016-08-30 14:01:10 -070010780 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010781 }
10782
10783 // Calculate the final RD estimate for this mode.
Urvang Joshi70006e42017-06-14 16:08:55 -070010784 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yue Chen69f18e12016-09-08 14:48:15 -070010785#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010786 } else {
10787 this_skip2 = mbmi->skip;
Urvang Joshi70006e42017-06-14 16:08:55 -070010788 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010789 if (this_skip2) {
10790 rate_y = 0;
10791 rate_uv = 0;
10792 }
Yue Chen69f18e12016-09-08 14:48:15 -070010793#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010794 }
10795
Yushin Choc0f6bf22017-06-09 16:08:02 -070010796#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10797 if ((bsize < BLOCK_8X8) && (rate2 != INT_MAX)) {
10798 assert(distortion2_y < INT64_MAX);
10799 }
10800#endif
10801
Yaowu Xuc27fc142016-08-22 16:08:15 -070010802 if (ref_frame == INTRA_FRAME) {
10803 // Keep record of best intra rd
10804 if (this_rd < best_intra_rd) {
10805 best_intra_rd = this_rd;
10806 best_intra_mode = mbmi->mode;
10807 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010808#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Emil Keyder01770b32017-01-20 18:03:11 -050010809 } else if (second_ref_frame == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010810 if (this_rd < best_single_inter_rd) {
10811 best_single_inter_rd = this_rd;
10812 best_single_inter_ref = mbmi->ref_frame[0];
10813 }
Yue Chen4d26acb2017-05-01 12:28:34 -070010814#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070010815 }
10816
10817 if (!disable_skip && ref_frame == INTRA_FRAME) {
10818 for (i = 0; i < REFERENCE_MODES; ++i)
Yaowu Xuf883b422016-08-30 14:01:10 -070010819 best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010820 }
10821
10822 // Did this mode help.. i.e. is it the new best mode
10823 if (this_rd < best_rd || x->skip) {
10824 if (!mode_excluded) {
10825 // Note index of best mode so far
10826 best_mode_index = mode_index;
10827
10828 if (ref_frame == INTRA_FRAME) {
10829 /* required for left and above block mv */
10830 mbmi->mv[0].as_int = 0;
10831 } else {
10832 best_pred_sse = x->pred_sse[ref_frame];
10833 }
10834
10835 rd_cost->rate = rate2;
10836#if CONFIG_SUPERTX
10837 if (x->skip)
10838 *returnrate_nocoef = rate2;
10839 else
10840 *returnrate_nocoef = rate2 - rate_y - rate_uv;
Yaowu Xuf883b422016-08-30 14:01:10 -070010841 *returnrate_nocoef -= av1_cost_bit(
10842 av1_get_skip_prob(cm, xd), disable_skip || skippable || this_skip2);
10843 *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
10844 mbmi->ref_frame[0] != INTRA_FRAME);
Yue Chencb60b182016-10-13 15:18:22 -070010845#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xu41a36de2017-03-23 15:55:03 -070010846#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
10847 MODE_INFO *const mi = xd->mi[0];
Sarah Parker19234cc2017-03-10 16:43:25 -080010848 const MOTION_MODE motion_allowed = motion_mode_allowed(
10849#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10850 0, xd->global_motion,
10851#endif // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
10852 mi);
Sarah Parker19234cc2017-03-10 16:43:25 -080010853 if (motion_allowed == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -070010854 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Sarah Parker19234cc2017-03-10 16:43:25 -080010855 else if (motion_allowed == OBMC_CAUSAL)
Yue Chen69f18e12016-09-08 14:48:15 -070010856 *returnrate_nocoef -=
10857 cpi->motion_mode_cost1[bsize][mbmi->motion_mode];
Yaowu Xu41a36de2017-03-23 15:55:03 -070010858#else
10859 *returnrate_nocoef -= cpi->motion_mode_cost[bsize][mbmi->motion_mode];
Yue Chen69f18e12016-09-08 14:48:15 -070010860#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -070010861#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070010862#endif // CONFIG_SUPERTX
10863 rd_cost->dist = distortion2;
10864 rd_cost->rdcost = this_rd;
10865 best_rd = this_rd;
10866 best_mbmode = *mbmi;
10867 best_skip2 = this_skip2;
10868 best_mode_skippable = skippable;
Yaowu Xuf883b422016-08-30 14:01:10 -070010869 best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
10870 this_skip2 || skippable);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010871 best_rate_uv = rate_uv;
Yushin Cho63927c42017-05-23 15:41:05 -070010872#if CONFIG_DAALA_DIST && CONFIG_CB4X4
Yushin Choc0f6bf22017-06-09 16:08:02 -070010873 if (bsize < BLOCK_8X8) {
10874 assert(distortion2_y < INT64_MAX);
10875 rd_cost->dist_y = distortion2_y;
10876 }
Yushin Cho63927c42017-05-23 15:41:05 -070010877#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010878#if CONFIG_VAR_TX
10879 for (i = 0; i < MAX_MB_PLANE; ++i)
10880 memcpy(ctx->blk_skip[i], x->blk_skip[i],
10881 sizeof(uint8_t) * ctx->num_4x4_blk);
Fergus Simpson4063a682017-02-28 16:52:22 -080010882#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070010883 }
10884 }
Yushin Choc0f6bf22017-06-09 16:08:02 -070010885#if CONFIG_DAALA_DIST && CONFIG_CB4X4
10886 if ((bsize < BLOCK_8X8) && (rd_cost->rate != INT_MAX)) {
10887 assert(rd_cost->dist_y < INT64_MAX);
10888 }
10889#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070010890 /* keep record of best compound/single-only prediction */
10891 if (!disable_skip && ref_frame != INTRA_FRAME) {
10892 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
10893
10894 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
10895 single_rate = rate2 - compmode_cost;
10896 hybrid_rate = rate2;
10897 } else {
10898 single_rate = rate2;
10899 hybrid_rate = rate2 + compmode_cost;
10900 }
10901
Urvang Joshi70006e42017-06-14 16:08:55 -070010902 single_rd = RDCOST(x->rdmult, single_rate, distortion2);
10903 hybrid_rd = RDCOST(x->rdmult, hybrid_rate, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010904
10905 if (!comp_pred) {
10906 if (single_rd < best_pred_rd[SINGLE_REFERENCE])
10907 best_pred_rd[SINGLE_REFERENCE] = single_rd;
10908 } else {
10909 if (single_rd < best_pred_rd[COMPOUND_REFERENCE])
10910 best_pred_rd[COMPOUND_REFERENCE] = single_rd;
10911 }
10912 if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
10913 best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
10914 }
10915
Yaowu Xuc27fc142016-08-22 16:08:15 -070010916 if (x->skip && !comp_pred) break;
10917 }
10918
10919 if (xd->lossless[mbmi->segment_id] == 0 && best_mode_index >= 0 &&
10920 ((sf->tx_type_search.fast_inter_tx_type_search == 1 &&
10921 is_inter_mode(best_mbmode.mode)) ||
10922 (sf->tx_type_search.fast_intra_tx_type_search == 1 &&
10923 !is_inter_mode(best_mbmode.mode)))) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010924 int skip_blk = 0;
10925 RD_STATS rd_stats_y, rd_stats_uv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010926
10927 x->use_default_inter_tx_type = 0;
10928 x->use_default_intra_tx_type = 0;
10929
10930 *mbmi = best_mbmode;
10931
10932 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
10933
10934 // Select prediction reference frames.
10935 for (i = 0; i < MAX_MB_PLANE; i++) {
10936 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
10937 if (has_second_ref(mbmi))
10938 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
10939 }
10940
Zoe Liu85b66462017-04-20 14:28:19 -070010941#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10942 // Single ref compound mode
10943 if (!has_second_ref(mbmi) && is_inter_singleref_comp_mode(mbmi->mode)) {
10944 xd->block_refs[1] = xd->block_refs[0];
10945 for (i = 0; i < MAX_MB_PLANE; i++)
10946 xd->plane[i].pre[1] = xd->plane[i].pre[0];
10947 }
10948#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
10949
Yaowu Xuc27fc142016-08-22 16:08:15 -070010950 if (is_inter_mode(mbmi->mode)) {
Jingning Hanc44009c2017-05-06 11:36:49 -070010951 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chencb60b182016-10-13 15:18:22 -070010952#if CONFIG_MOTION_VAR
Sarah Parker19234cc2017-03-10 16:43:25 -080010953 if (mbmi->motion_mode == OBMC_CAUSAL) {
Fergus Simpson073c6f32017-02-17 12:13:48 -080010954 av1_build_obmc_inter_prediction(
Fergus Simpson9f7ca0b2017-03-10 10:46:46 -080010955 cm, xd, mi_row, mi_col, args.above_pred_buf, args.above_pred_stride,
10956 args.left_pred_buf, args.left_pred_stride);
Sarah Parker19234cc2017-03-10 16:43:25 -080010957 }
Yue Chencb60b182016-10-13 15:18:22 -070010958#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070010959 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010960#if CONFIG_VAR_TX
10961 if (cm->tx_mode == TX_MODE_SELECT || xd->lossless[mbmi->segment_id]) {
Angie Chiangb5dda482016-11-02 16:19:58 -070010962 select_tx_type_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010963 } else {
10964 int idx, idy;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010965 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010966 for (idy = 0; idy < xd->n8_h; ++idy)
10967 for (idx = 0; idx < xd->n8_w; ++idx)
10968 mbmi->inter_tx_size[idy][idx] = mbmi->tx_size;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010969 memset(x->blk_skip[0], rd_stats_y.skip,
Yaowu Xuc27fc142016-08-22 16:08:15 -070010970 sizeof(uint8_t) * xd->n8_h * xd->n8_w * 4);
10971 }
10972
Angie Chiangb5dda482016-11-02 16:19:58 -070010973 inter_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010974#else
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010975 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010976 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010977#endif // CONFIG_VAR_TX
10978 } else {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010979 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
Angie Chiang284d7772016-11-08 11:06:45 -080010980 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010981 }
10982
Urvang Joshi70006e42017-06-14 16:08:55 -070010983 if (RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate,
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010984 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070010985 RDCOST(x->rdmult, 0, (rd_stats_y.sse + rd_stats_uv.sse))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010986 skip_blk = 1;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010987 rd_stats_y.rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
10988 rd_stats_uv.rate = 0;
10989 rd_stats_y.dist = rd_stats_y.sse;
10990 rd_stats_uv.dist = rd_stats_uv.sse;
Yaowu Xuc27fc142016-08-22 16:08:15 -070010991 } else {
10992 skip_blk = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010993 rd_stats_y.rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070010994 }
10995
Urvang Joshi70006e42017-06-14 16:08:55 -070010996 if (RDCOST(x->rdmult, best_rate_y + best_rate_uv, rd_cost->dist) >
10997 RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate,
Angie Chiang0e9a2e92016-11-08 09:45:40 -080010998 (rd_stats_y.dist + rd_stats_uv.dist))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070010999#if CONFIG_VAR_TX
11000 int idx, idy;
Fergus Simpson4063a682017-02-28 16:52:22 -080011001#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011002 best_mbmode.tx_type = mbmi->tx_type;
11003 best_mbmode.tx_size = mbmi->tx_size;
11004#if CONFIG_VAR_TX
11005 for (idy = 0; idy < xd->n8_h; ++idy)
11006 for (idx = 0; idx < xd->n8_w; ++idx)
11007 best_mbmode.inter_tx_size[idy][idx] = mbmi->inter_tx_size[idy][idx];
11008
11009 for (i = 0; i < MAX_MB_PLANE; ++i)
11010 memcpy(ctx->blk_skip[i], x->blk_skip[i],
11011 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -070011012
11013 best_mbmode.min_tx_size = mbmi->min_tx_size;
Fergus Simpson4063a682017-02-28 16:52:22 -080011014#endif // CONFIG_VAR_TX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011015 rd_cost->rate +=
11016 (rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
11017 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
Urvang Joshi70006e42017-06-14 16:08:55 -070011018 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011019 best_skip2 = skip_blk;
Yushin Choc0f6bf22017-06-09 16:08:02 -070011020#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11021 if (bsize < BLOCK_8X8) {
11022 assert(rd_cost->rate != INT_MAX);
11023 assert(rd_cost->dist_y < INT64_MAX);
11024 rd_cost->dist_y = rd_stats_y.dist;
11025 }
11026#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011027 }
11028 }
11029
Yushin Choc0f6bf22017-06-09 16:08:02 -070011030#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11031 if ((bsize < BLOCK_8X8) && (rd_cost->rate != INT_MAX)) {
11032 assert(rd_cost->dist_y < INT64_MAX);
11033 }
11034#endif
11035
Urvang Joshib100db72016-10-12 16:28:56 -070011036#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011037 // Only try palette mode when the best mode so far is an intra mode.
hui su9bc1d8d2017-03-24 12:36:03 -070011038 if (try_palette && !is_inter_mode(best_mbmode.mode)) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011039 int rate2 = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011040#if CONFIG_SUPERTX
11041 int best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011042#endif // CONFIG_SUPERTX
Urvang Joshi451e0f22017-01-31 11:18:31 -080011043 int64_t distortion2 = 0, best_rd_palette = best_rd, this_rd,
11044 best_model_rd_palette = INT64_MAX;
Urvang Joshi626591d2016-10-24 14:13:55 -070011045 int skippable = 0, rate_overhead_palette = 0;
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011046 RD_STATS rd_stats_y;
hui sude0c70a2017-01-09 17:12:17 -080011047 TX_SIZE uv_tx;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011048 uint8_t *const best_palette_color_map =
11049 x->palette_buffer->best_palette_color_map;
11050 uint8_t *const color_map = xd->plane[0].color_index_map;
Urvang Joshi451e0f22017-01-31 11:18:31 -080011051 MB_MODE_INFO best_mbmi_palette = best_mbmode;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011052
11053 mbmi->mode = DC_PRED;
11054 mbmi->uv_mode = DC_PRED;
11055 mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011056 mbmi->ref_frame[1] = NONE_FRAME;
Urvang Joshi626591d2016-10-24 14:13:55 -070011057 rate_overhead_palette = rd_pick_palette_intra_sby(
Urvang Joshi451e0f22017-01-31 11:18:31 -080011058 cpi, x, bsize, palette_ctx, intra_mode_cost[DC_PRED],
11059 &best_mbmi_palette, best_palette_color_map, &best_rd_palette,
11060 &best_model_rd_palette, NULL, NULL, NULL, NULL);
hui sude0c70a2017-01-09 17:12:17 -080011061 if (pmi->palette_size[0] == 0) goto PALETTE_EXIT;
11062 memcpy(color_map, best_palette_color_map,
11063 rows * cols * sizeof(best_palette_color_map[0]));
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011064 super_block_yrd(cpi, x, &rd_stats_y, bsize, best_rd);
11065 if (rd_stats_y.rate == INT_MAX) goto PALETTE_EXIT;
Debargha Mukherjee2f123402016-08-30 17:43:38 -070011066 uv_tx = uv_txsize_lookup[bsize][mbmi->tx_size][xd->plane[1].subsampling_x]
11067 [xd->plane[1].subsampling_y];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011068 if (rate_uv_intra[uv_tx] == INT_MAX) {
11069 choose_intra_uv_mode(cpi, x, ctx, bsize, uv_tx, &rate_uv_intra[uv_tx],
Urvang Joshi368fbc92016-10-17 16:31:34 -070011070 &rate_uv_tokenonly[uv_tx], &dist_uvs[uv_tx],
11071 &skip_uvs[uv_tx], &mode_uv[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011072 pmi_uv[uv_tx] = *pmi;
11073#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011074 uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
11075#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011076#if CONFIG_FILTER_INTRA
11077 filter_intra_mode_info_uv[uv_tx] = mbmi->filter_intra_mode_info;
11078#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011079 }
11080 mbmi->uv_mode = mode_uv[uv_tx];
11081 pmi->palette_size[1] = pmi_uv[uv_tx].palette_size[1];
hui sude0c70a2017-01-09 17:12:17 -080011082 if (pmi->palette_size[1] > 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011083 memcpy(pmi->palette_colors + PALETTE_MAX_SIZE,
11084 pmi_uv[uv_tx].palette_colors + PALETTE_MAX_SIZE,
11085 2 * PALETTE_MAX_SIZE * sizeof(pmi->palette_colors[0]));
hui sude0c70a2017-01-09 17:12:17 -080011086 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011087#if CONFIG_EXT_INTRA
11088 mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011089#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -070011090#if CONFIG_FILTER_INTRA
11091 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] =
11092 filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1];
11093 if (filter_intra_mode_info_uv[uv_tx].use_filter_intra_mode[1]) {
11094 mbmi->filter_intra_mode_info.filter_intra_mode[1] =
11095 filter_intra_mode_info_uv[uv_tx].filter_intra_mode[1];
11096 }
11097#endif // CONFIG_FILTER_INTRA
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011098 skippable = rd_stats_y.skip && skip_uvs[uv_tx];
11099 distortion2 = rd_stats_y.dist + dist_uvs[uv_tx];
11100 rate2 = rd_stats_y.rate + rate_overhead_palette + rate_uv_intra[uv_tx];
Yaowu Xuc27fc142016-08-22 16:08:15 -070011101 rate2 += ref_costs_single[INTRA_FRAME];
11102
11103 if (skippable) {
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011104 rate2 -= (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011105#if CONFIG_SUPERTX
11106 best_rate_nocoef = rate2;
Fergus Simpson4063a682017-02-28 16:52:22 -080011107#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011108 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011109 } else {
11110#if CONFIG_SUPERTX
Angie Chiang0e9a2e92016-11-08 09:45:40 -080011111 best_rate_nocoef = rate2 - (rd_stats_y.rate + rate_uv_tokenonly[uv_tx]);
Fergus Simpson4063a682017-02-28 16:52:22 -080011112#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -070011113 rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011114 }
Urvang Joshi70006e42017-06-14 16:08:55 -070011115 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011116 if (this_rd < best_rd) {
11117 best_mode_index = 3;
11118 mbmi->mv[0].as_int = 0;
11119 rd_cost->rate = rate2;
11120#if CONFIG_SUPERTX
11121 *returnrate_nocoef = best_rate_nocoef;
Fergus Simpson4063a682017-02-28 16:52:22 -080011122#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -070011123 rd_cost->dist = distortion2;
11124 rd_cost->rdcost = this_rd;
11125 best_rd = this_rd;
11126 best_mbmode = *mbmi;
11127 best_skip2 = 0;
11128 best_mode_skippable = skippable;
11129 }
11130 }
11131PALETTE_EXIT:
Urvang Joshib100db72016-10-12 16:28:56 -070011132#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011133
hui su5db97432016-10-14 16:10:14 -070011134#if CONFIG_FILTER_INTRA
11135 // TODO(huisu): filter-intra is turned off in lossless mode for now to
Yaowu Xuc27fc142016-08-22 16:08:15 -070011136 // avoid a unit test failure
hui su5db97432016-10-14 16:10:14 -070011137 if (!xd->lossless[mbmi->segment_id] &&
Urvang Joshib100db72016-10-12 16:28:56 -070011138#if CONFIG_PALETTE
hui sude0c70a2017-01-09 17:12:17 -080011139 pmi->palette_size[0] == 0 &&
Urvang Joshib100db72016-10-12 16:28:56 -070011140#endif // CONFIG_PALETTE
11141 !dc_skipped && best_mode_index >= 0 &&
11142 best_intra_rd < (best_rd + (best_rd >> 3))) {
hui su5db97432016-10-14 16:10:14 -070011143 pick_filter_intra_interframe(
Jingning Han18c53c82017-02-17 14:49:57 -080011144 cpi, x, ctx, bsize, mi_row, mi_col, rate_uv_intra, rate_uv_tokenonly,
11145 dist_uvs, skip_uvs, mode_uv, filter_intra_mode_info_uv,
hui su5db97432016-10-14 16:10:14 -070011146#if CONFIG_EXT_INTRA
11147 uv_angle_delta,
11148#endif // CONFIG_EXT_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -070011149#if CONFIG_PALETTE
11150 pmi_uv, palette_ctx,
11151#endif // CONFIG_PALETTE
11152 0, ref_costs_single, &best_rd, &best_intra_rd, &best_intra_mode,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011153 &best_mode_index, &best_skip2, &best_mode_skippable,
11154#if CONFIG_SUPERTX
11155 returnrate_nocoef,
11156#endif // CONFIG_SUPERTX
11157 best_pred_rd, &best_mbmode, rd_cost);
11158 }
hui su5db97432016-10-14 16:10:14 -070011159#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011160
Zoe Liu85b66462017-04-20 14:28:19 -070011161// The inter modes' rate costs are not calculated precisely in some cases.
11162// Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
11163// ZEROMV. Here, checks are added for those cases, and the mode decisions
11164// are corrected.
11165#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
11166// NOTE: For SR_NEW_NEWMV, no need to check as the two mvs from the same ref
11167// are surely different from each other.
11168#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
Yaowu Xuc27fc142016-08-22 16:08:15 -070011169 if (best_mbmode.mode == NEWMV
11170#if CONFIG_EXT_INTER
Zoe Liu7f24e1b2017-03-17 17:42:05 -070011171 || best_mbmode.mode == NEW_NEWMV
Yaowu Xuc27fc142016-08-22 16:08:15 -070011172#endif // CONFIG_EXT_INTER
11173 ) {
11174 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11175 best_mbmode.ref_frame[1] };
11176 int comp_pred_mode = refs[1] > INTRA_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011177 int_mv zeromv[2];
Yaowu Xuf883b422016-08-30 14:01:10 -070011178 const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
Sarah Parkere5299862016-08-16 14:57:37 -070011179#if CONFIG_GLOBAL_MOTION
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011180 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
11181 cm->allow_high_precision_mv, bsize,
11182 mi_col, mi_row, 0)
11183 .as_int;
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011184 zeromv[1].as_int = comp_pred_mode
11185 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11186 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011187 bsize, mi_col, mi_row, 0)
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -080011188 .as_int
11189 : 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011190#else
11191 zeromv[0].as_int = 0;
11192 zeromv[1].as_int = 0;
11193#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011194 if (!comp_pred_mode) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011195 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011196 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011197 : INT_MAX;
11198
11199 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11200 int_mv cur_mv = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11201 if (cur_mv.as_int == best_mbmode.mv[0].as_int) {
11202 best_mbmode.mode = NEARMV;
11203 best_mbmode.ref_mv_idx = i;
11204 }
11205 }
11206
11207 if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
11208 best_mbmode.mode = NEARESTMV;
Sarah Parkere5299862016-08-16 14:57:37 -070011209 else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011210 best_mbmode.mode = ZEROMV;
11211 } else {
11212 int_mv nearestmv[2];
11213 int_mv nearmv[2];
11214
11215#if CONFIG_EXT_INTER
11216 if (mbmi_ext->ref_mv_count[rf_type] > 1) {
11217 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][1].this_mv;
11218 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][1].comp_mv;
11219 } else {
11220 nearmv[0] = frame_mv[NEARMV][refs[0]];
11221 nearmv[1] = frame_mv[NEARMV][refs[1]];
11222 }
11223#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011224 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
Yaowu Xuf883b422016-08-30 14:01:10 -070011225 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011226 : INT_MAX;
11227
11228 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11229 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11230 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11231
11232 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
11233 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11234 best_mbmode.mode = NEARMV;
11235 best_mbmode.ref_mv_idx = i;
11236 }
11237 }
Fergus Simpson4063a682017-02-28 16:52:22 -080011238#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011239 if (mbmi_ext->ref_mv_count[rf_type] >= 1) {
11240 nearestmv[0] = mbmi_ext->ref_mv_stack[rf_type][0].this_mv;
11241 nearestmv[1] = mbmi_ext->ref_mv_stack[rf_type][0].comp_mv;
11242 } else {
11243 nearestmv[0] = frame_mv[NEARESTMV][refs[0]];
11244 nearestmv[1] = frame_mv[NEARESTMV][refs[1]];
11245 }
11246
11247 if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011248 nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011249#if CONFIG_EXT_INTER
11250 best_mbmode.mode = NEAREST_NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011251 } else {
11252 int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
11253 ? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
11254 : INT_MAX;
11255
11256 for (i = 0; i <= ref_set && ref_set != INT_MAX; ++i) {
11257 nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
11258 nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
11259
Debargha Mukherjeebb6e1342017-04-17 16:05:04 -070011260 // Try switching to the NEAR_NEARMV mode
11261 if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
David Barker404b2e82017-03-27 13:07:47 +010011262 nearmv[1].as_int == best_mbmode.mv[1].as_int) {
11263 best_mbmode.mode = NEAR_NEARMV;
11264 best_mbmode.ref_mv_idx = i;
11265 }
11266 }
11267
David Barker3dfba992017-04-03 16:10:09 +010011268 if (best_mbmode.mode == NEW_NEWMV &&
David Barker404b2e82017-03-27 13:07:47 +010011269 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11270 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11271 best_mbmode.mode = ZERO_ZEROMV;
11272 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011273#else
11274 best_mbmode.mode = NEARESTMV;
David Barker404b2e82017-03-27 13:07:47 +010011275 } else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11276 best_mbmode.mv[1].as_int == zeromv[1].as_int) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011277 best_mbmode.mode = ZEROMV;
David Barker404b2e82017-03-27 13:07:47 +010011278 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011279#endif // CONFIG_EXT_INTER
11280 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011281 }
11282
David Barker9620bcd2017-03-22 14:46:42 +000011283 // Make sure that the ref_mv_idx is only nonzero when we're
11284 // using a mode which can support ref_mv_idx
11285 if (best_mbmode.ref_mv_idx != 0 &&
David Barker404b2e82017-03-27 13:07:47 +010011286#if CONFIG_EXT_INTER
Zoe Liu85b66462017-04-20 14:28:19 -070011287#if CONFIG_COMPOUND_SINGLEREF
11288 !(best_mbmode.mode == NEWMV || best_mbmode.mode == SR_NEW_NEWMV ||
11289 best_mbmode.mode == NEW_NEWMV ||
11290 have_nearmv_in_inter_mode(best_mbmode.mode))) {
11291#else // !CONFIG_COMPOUND_SINGLEREF
David Barker3dfba992017-04-03 16:10:09 +010011292 !(best_mbmode.mode == NEWMV || best_mbmode.mode == NEW_NEWMV ||
11293 have_nearmv_in_inter_mode(best_mbmode.mode))) {
Zoe Liu85b66462017-04-20 14:28:19 -070011294#endif // CONFIG_COMPOUND_SINGLEREF
11295#else // !CONFIG_EXT_INTER
David Barker9620bcd2017-03-22 14:46:42 +000011296 !(best_mbmode.mode == NEARMV || best_mbmode.mode == NEWMV)) {
Zoe Liu85b66462017-04-20 14:28:19 -070011297#endif // CONFIG_EXT_INTER
David Barker9620bcd2017-03-22 14:46:42 +000011298 best_mbmode.ref_mv_idx = 0;
11299 }
11300
David Barkercdcac6d2016-12-01 17:04:16 +000011301 {
Jingning Han731af492016-11-17 11:53:23 -080011302 int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
11303 int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
David Barker68e6e862016-11-24 15:10:15 +000011304 if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
David Barkercdcac6d2016-12-01 17:04:16 +000011305 int_mv zeromv[2];
David Barker68e6e862016-11-24 15:10:15 +000011306#if CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +000011307 const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
11308 best_mbmode.ref_frame[1] };
11309 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
David Barker45390c12017-02-20 14:44:40 +000011310 cm->allow_high_precision_mv,
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011311 bsize, mi_col, mi_row, 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011312 .as_int;
Debargha Mukherjeef2e7b932017-05-02 21:45:39 -070011313 zeromv[1].as_int = (refs[1] != NONE_FRAME)
11314 ? gm_get_motion_vector(&cm->global_motion[refs[1]],
11315 cm->allow_high_precision_mv,
11316 bsize, mi_col, mi_row, 0)
11317 .as_int
11318 : 0;
David Barkercdcac6d2016-12-01 17:04:16 +000011319 lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
11320 lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
11321#else
11322 zeromv[0].as_int = zeromv[1].as_int = 0;
11323#endif // CONFIG_GLOBAL_MOTION
11324 if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
11325 best_mbmode.mv[0].as_int == zeromv[0].as_int &&
11326#if CONFIG_EXT_INTER
11327 (best_mbmode.ref_frame[1] <= INTRA_FRAME)
11328#else
Emil Keyder01770b32017-01-20 18:03:11 -050011329 (best_mbmode.ref_frame[1] == NONE_FRAME ||
David Barkercdcac6d2016-12-01 17:04:16 +000011330 best_mbmode.mv[1].as_int == zeromv[1].as_int)
11331#endif // CONFIG_EXT_INTER
11332 ) {
11333 best_mbmode.mode = ZEROMV;
11334 }
David Barker68e6e862016-11-24 15:10:15 +000011335 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011336 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011337
11338 if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
11339 rd_cost->rate = INT_MAX;
11340 rd_cost->rdcost = INT64_MAX;
11341 return;
11342 }
11343
Yaowu Xuc27fc142016-08-22 16:08:15 -070011344#if CONFIG_DUAL_FILTER
11345 assert((cm->interp_filter == SWITCHABLE) ||
11346 (cm->interp_filter == best_mbmode.interp_filter[0]) ||
11347 !is_inter_block(&best_mbmode));
11348 assert((cm->interp_filter == SWITCHABLE) ||
11349 (cm->interp_filter == best_mbmode.interp_filter[1]) ||
11350 !is_inter_block(&best_mbmode));
11351 if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
11352 assert((cm->interp_filter == SWITCHABLE) ||
11353 (cm->interp_filter == best_mbmode.interp_filter[2]) ||
11354 !is_inter_block(&best_mbmode));
11355 assert((cm->interp_filter == SWITCHABLE) ||
11356 (cm->interp_filter == best_mbmode.interp_filter[3]) ||
11357 !is_inter_block(&best_mbmode));
11358 }
11359#else
11360 assert((cm->interp_filter == SWITCHABLE) ||
11361 (cm->interp_filter == best_mbmode.interp_filter) ||
11362 !is_inter_block(&best_mbmode));
Fergus Simpson4063a682017-02-28 16:52:22 -080011363#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011364
11365 if (!cpi->rc.is_src_frame_alt_ref)
Yaowu Xuf883b422016-08-30 14:01:10 -070011366 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11367 sf->adaptive_rd_thresh, bsize, best_mode_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011368
11369 // macroblock modes
11370 *mbmi = best_mbmode;
11371 x->skip |= best_skip2;
11372
Yue Chen19e7aa82016-11-30 14:05:39 -080011373// Note: this section is needed since the mode may have been forced to
11374// ZEROMV by the all-zero mode handling of ref-mv.
11375#if CONFIG_GLOBAL_MOTION
11376 if (mbmi->mode == ZEROMV
11377#if CONFIG_EXT_INTER
11378 || mbmi->mode == ZERO_ZEROMV
11379#endif // CONFIG_EXT_INTER
11380 ) {
Sarah Parker19234cc2017-03-10 16:43:25 -080011381#if CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11382 // Correct the motion mode for ZEROMV
11383 const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
11384#if SEPARATE_GLOBAL_MOTION
11385 0, xd->global_motion,
11386#endif // SEPARATE_GLOBAL_MOTION
11387 xd->mi[0]);
11388 if (mbmi->motion_mode > last_motion_mode_allowed)
11389 mbmi->motion_mode = last_motion_mode_allowed;
11390#endif // CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR
11391
11392 // Correct the interpolation filter for ZEROMV
Yue Chen19e7aa82016-11-30 14:05:39 -080011393 if (is_nontrans_global_motion(xd)) {
11394#if CONFIG_DUAL_FILTER
11395 mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
11396 ? EIGHTTAP_REGULAR
11397 : cm->interp_filter;
11398 mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
11399 ? EIGHTTAP_REGULAR
11400 : cm->interp_filter;
11401#else
11402 mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
11403 : cm->interp_filter;
11404#endif // CONFIG_DUAL_FILTER
11405 }
11406 }
11407#endif // CONFIG_GLOBAL_MOTION
11408
Yaowu Xuc27fc142016-08-22 16:08:15 -070011409 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
11410 if (mbmi->mode != NEWMV)
11411 mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
11412 else
11413 mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
11414 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070011415
11416 for (i = 0; i < REFERENCE_MODES; ++i) {
11417 if (best_pred_rd[i] == INT64_MAX)
11418 best_pred_diff[i] = INT_MIN;
11419 else
11420 best_pred_diff[i] = best_rd - best_pred_rd[i];
11421 }
11422
11423 x->skip |= best_mode_skippable;
11424
11425 assert(best_mode_index >= 0);
11426
11427 store_coding_context(x, ctx, best_mode_index, best_pred_diff,
11428 best_mode_skippable);
11429
Urvang Joshib100db72016-10-12 16:28:56 -070011430#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011431 if (cm->allow_screen_content_tools && pmi->palette_size[1] > 0) {
11432 restore_uv_color_map(cpi, x);
11433 }
Urvang Joshib100db72016-10-12 16:28:56 -070011434#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011435}
11436
Urvang Joshi52648442016-10-13 17:27:51 -070011437void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
11438 TileDataEnc *tile_data, MACROBLOCK *x,
David Barker45390c12017-02-20 14:44:40 +000011439 int mi_row, int mi_col,
Angie Chiang2a2a7dd2017-04-25 16:08:47 -070011440 RD_STATS *rd_cost, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -070011441 PICK_MODE_CONTEXT *ctx,
11442 int64_t best_rd_so_far) {
Urvang Joshi52648442016-10-13 17:27:51 -070011443 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011444 MACROBLOCKD *const xd = &x->e_mbd;
11445 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11446 unsigned char segment_id = mbmi->segment_id;
11447 const int comp_pred = 0;
11448 int i;
11449 int64_t best_pred_diff[REFERENCE_MODES];
11450 unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -070011451#if CONFIG_EXT_COMP_REFS
11452 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME][TOTAL_REFS_PER_FRAME];
11453#else
Yaowu Xuc27fc142016-08-22 16:08:15 -070011454 unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
Zoe Liuc082bbc2017-05-17 13:31:37 -070011455#endif // CONFIG_EXT_COMP_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -070011456 aom_prob comp_mode_p;
James Zern7b9407a2016-05-18 23:48:05 -070011457 InterpFilter best_filter = SWITCHABLE;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011458 int64_t this_rd = INT64_MAX;
11459 int rate2 = 0;
11460 const int64_t distortion2 = 0;
David Barker45390c12017-02-20 14:44:40 +000011461 (void)mi_row;
11462 (void)mi_col;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011463
11464 estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
11465 &comp_mode_p);
11466
11467 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) x->pred_sse[i] = INT_MAX;
11468 for (i = LAST_FRAME; i < TOTAL_REFS_PER_FRAME; ++i)
11469 x->pred_mv_sad[i] = INT_MAX;
11470
11471 rd_cost->rate = INT_MAX;
11472
11473 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
11474
Urvang Joshib100db72016-10-12 16:28:56 -070011475#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -070011476 mbmi->palette_mode_info.palette_size[0] = 0;
11477 mbmi->palette_mode_info.palette_size[1] = 0;
Urvang Joshib100db72016-10-12 16:28:56 -070011478#endif // CONFIG_PALETTE
11479
hui su5db97432016-10-14 16:10:14 -070011480#if CONFIG_FILTER_INTRA
11481 mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
11482 mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
11483#endif // CONFIG_FILTER_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -070011484 mbmi->mode = ZEROMV;
Yue Chencb60b182016-10-13 15:18:22 -070011485 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011486 mbmi->uv_mode = DC_PRED;
11487 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -050011488 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parkere5299862016-08-16 14:57:37 -070011489#if CONFIG_GLOBAL_MOTION
11490 mbmi->mv[0].as_int =
Sarah Parkerae7c4582017-02-28 16:30:30 -080011491 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
Debargha Mukherjeefebb59c2017-03-02 12:23:45 -080011492 cm->allow_high_precision_mv, bsize, mi_col, mi_row,
11493 0)
David Barkercdcac6d2016-12-01 17:04:16 +000011494 .as_int;
Sarah Parkere5299862016-08-16 14:57:37 -070011495#else // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070011496 mbmi->mv[0].as_int = 0;
Sarah Parkere5299862016-08-16 14:57:37 -070011497#endif // CONFIG_GLOBAL_MOTION
Jingning Han64088952016-07-11 11:24:24 -070011498 mbmi->tx_size = max_txsize_lookup[bsize];
Yaowu Xuee775b12016-10-18 10:00:21 -070011499 x->skip = 1;
Sarah Parkere5299862016-08-16 14:57:37 -070011500
Yaowu Xuc27fc142016-08-22 16:08:15 -070011501 mbmi->ref_mv_idx = 0;
11502 mbmi->pred_mv[0].as_int = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011503
Yue Chendead17d2017-04-20 16:19:39 -070011504 mbmi->motion_mode = SIMPLE_TRANSLATION;
11505#if CONFIG_MOTION_VAR
11506 av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
11507#endif
Yue Chenf3e1ead2017-04-21 14:05:51 -070011508#if CONFIG_WARPED_MOTION
11509 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
11510 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
11511 mbmi->num_proj_ref[0] = findSamples(cm, xd, mi_row, mi_col, pts, pts_inref);
11512 }
11513#endif
Yue Chendead17d2017-04-20 16:19:39 -070011514
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011515 set_default_interp_filters(mbmi, cm->interp_filter);
11516
11517 if (cm->interp_filter != SWITCHABLE) {
11518 best_filter = cm->interp_filter;
11519 } else {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011520 best_filter = EIGHTTAP_REGULAR;
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011521 if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd) &&
Yaowu Xuc27fc142016-08-22 16:08:15 -070011522 x->source_variance >= cpi->sf.disable_filter_search_var_thresh) {
11523 int rs;
11524 int best_rs = INT_MAX;
11525 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
11526#if CONFIG_DUAL_FILTER
11527 int k;
11528 for (k = 0; k < 4; ++k) mbmi->interp_filter[k] = i;
11529#else
11530 mbmi->interp_filter = i;
Fergus Simpson4063a682017-02-28 16:52:22 -080011531#endif // CONFIG_DUAL_FILTER
Yaowu Xuf883b422016-08-30 14:01:10 -070011532 rs = av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011533 if (rs < best_rs) {
11534 best_rs = rs;
11535#if CONFIG_DUAL_FILTER
11536 best_filter = mbmi->interp_filter[0];
11537#else
11538 best_filter = mbmi->interp_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011539#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011540 }
11541 }
11542 }
11543 }
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011544// Set the appropriate filter
Yaowu Xuc27fc142016-08-22 16:08:15 -070011545#if CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011546 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = best_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011547#else
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011548 mbmi->interp_filter = best_filter;
Fergus Simpson4063a682017-02-28 16:52:22 -080011549#endif // CONFIG_DUAL_FILTER
Debargha Mukherjee0df711f2017-05-02 16:00:20 -070011550 rate2 += av1_get_switchable_rate(cpi, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011551
11552 if (cm->reference_mode == REFERENCE_MODE_SELECT)
Yaowu Xuf883b422016-08-30 14:01:10 -070011553 rate2 += av1_cost_bit(comp_mode_p, comp_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011554
11555 // Estimate the reference frame signaling cost and add it
11556 // to the rolling cost variable.
11557 rate2 += ref_costs_single[LAST_FRAME];
Urvang Joshi70006e42017-06-14 16:08:55 -070011558 this_rd = RDCOST(x->rdmult, rate2, distortion2);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011559
11560 rd_cost->rate = rate2;
11561 rd_cost->dist = distortion2;
11562 rd_cost->rdcost = this_rd;
Yushin Cho63927c42017-05-23 15:41:05 -070011563#if CONFIG_DAALA_DIST && CONFIG_CB4X4
11564 if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2;
11565#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070011566 if (this_rd >= best_rd_so_far) {
11567 rd_cost->rate = INT_MAX;
11568 rd_cost->rdcost = INT64_MAX;
11569 return;
11570 }
11571
11572#if CONFIG_DUAL_FILTER
11573 assert((cm->interp_filter == SWITCHABLE) ||
11574 (cm->interp_filter == mbmi->interp_filter[0]));
11575#else
11576 assert((cm->interp_filter == SWITCHABLE) ||
11577 (cm->interp_filter == mbmi->interp_filter));
Fergus Simpson4063a682017-02-28 16:52:22 -080011578#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -070011579
Yaowu Xuf883b422016-08-30 14:01:10 -070011580 av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
11581 cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011582
Yaowu Xuf883b422016-08-30 14:01:10 -070011583 av1_zero(best_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011584
11585 store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
11586}
11587
Yue Chencb60b182016-10-13 15:18:22 -070011588#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -070011589// This function has a structure similar to av1_build_obmc_inter_prediction
Yaowu Xuc27fc142016-08-22 16:08:15 -070011590//
11591// The OBMC predictor is computed as:
11592//
11593// PObmc(x,y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011594// AOM_BLEND_A64(Mh(x),
11595// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
Yaowu Xuc27fc142016-08-22 16:08:15 -070011596// PLeft(x, y))
11597//
Yaowu Xuf883b422016-08-30 14:01:10 -070011598// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
Yaowu Xuc27fc142016-08-22 16:08:15 -070011599// rounding, this can be written as:
11600//
Yaowu Xuf883b422016-08-30 14:01:10 -070011601// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011602// Mh(x) * Mv(y) * P(x,y) +
11603// Mh(x) * Cv(y) * Pabove(x,y) +
Yaowu Xuf883b422016-08-30 14:01:10 -070011604// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011605//
11606// Where :
11607//
Yaowu Xuf883b422016-08-30 14:01:10 -070011608// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
11609// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011610//
11611// This function computes 'wsrc' and 'mask' as:
11612//
11613// wsrc(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011614// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
Yaowu Xuc27fc142016-08-22 16:08:15 -070011615// 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// mask(x, y) = Mh(x) * Mv(y)
11619//
11620// These can then be used to efficiently approximate the error for any
11621// predictor P in the context of the provided neighbouring predictors by
11622// computing:
11623//
11624// error(x, y) =
Yaowu Xuf883b422016-08-30 14:01:10 -070011625// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
Yaowu Xuc27fc142016-08-22 16:08:15 -070011626//
Yaowu Xuf883b422016-08-30 14:01:10 -070011627static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
Yaowu Xuc27fc142016-08-22 16:08:15 -070011628 const MACROBLOCKD *xd, int mi_row,
11629 int mi_col, const uint8_t *above,
11630 int above_stride, const uint8_t *left,
Yue Chene9638cc2016-10-10 12:37:54 -070011631 int left_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070011632 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
11633 int row, col, i;
Jingning Hanff6ee6a2016-12-07 09:55:21 -080011634 const int bw = xd->n8_w << MI_SIZE_LOG2;
11635 const int bh = xd->n8_h << MI_SIZE_LOG2;
Yue Chene9638cc2016-10-10 12:37:54 -070011636 int32_t *mask_buf = x->mask_buf;
11637 int32_t *wsrc_buf = x->wsrc_buf;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011638 const int wsrc_stride = bw;
11639 const int mask_stride = bw;
Yaowu Xuf883b422016-08-30 14:01:10 -070011640 const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011641#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011642 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
11643#else
11644 const int is_hbd = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011645#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011646
11647 // plane 0 should not be subsampled
11648 assert(xd->plane[0].subsampling_x == 0);
11649 assert(xd->plane[0].subsampling_y == 0);
11650
Yaowu Xuf883b422016-08-30 14:01:10 -070011651 av1_zero_array(wsrc_buf, bw * bh);
11652 for (i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011653
11654 // handle above row
11655 if (xd->up_available) {
11656 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011657 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011658 const int mi_row_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011659 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070011660 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
11661 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011662
11663 assert(miw > 0);
11664
11665 i = 0;
11666 do { // for each mi in the above row
11667 const int mi_col_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070011668 const MB_MODE_INFO *above_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011669 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070011670#if CONFIG_CHROMA_SUB8X8
11671 if (above_mbmi->sb_type < BLOCK_8X8)
11672 above_mbmi =
11673 &xd->mi[mi_col_offset + 1 + mi_row_offset * xd->mi_stride]->mbmi;
11674#endif
Jingning Han680b09e2017-05-22 16:42:36 -070011675 const BLOCK_SIZE a_bsize = AOMMAX(above_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070011676 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011677 const int neighbor_bw = mi_step * MI_SIZE;
11678
11679 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070011680 if (!CONFIG_CB4X4 && (a_bsize == BLOCK_4X4 || a_bsize == BLOCK_4X8))
11681 neighbor_count += 2;
11682 else
11683 neighbor_count++;
11684 if (neighbor_count > neighbor_limit) break;
11685
Yaowu Xuc27fc142016-08-22 16:08:15 -070011686 const int tmp_stride = above_stride;
11687 int32_t *wsrc = wsrc_buf + (i * MI_SIZE);
11688 int32_t *mask = mask_buf + (i * MI_SIZE);
11689
11690 if (!is_hbd) {
11691 const uint8_t *tmp = above;
11692
11693 for (row = 0; row < overlap; ++row) {
11694 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011695 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011696 for (col = 0; col < neighbor_bw; ++col) {
11697 wsrc[col] = m1 * tmp[col];
11698 mask[col] = m0;
11699 }
11700 wsrc += wsrc_stride;
11701 mask += mask_stride;
11702 tmp += tmp_stride;
11703 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011704#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011705 } else {
11706 const uint16_t *tmp = CONVERT_TO_SHORTPTR(above);
11707
11708 for (row = 0; row < overlap; ++row) {
11709 const uint8_t m0 = mask1d[row];
Yaowu Xuf883b422016-08-30 14:01:10 -070011710 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011711 for (col = 0; col < neighbor_bw; ++col) {
11712 wsrc[col] = m1 * tmp[col];
11713 mask[col] = m0;
11714 }
11715 wsrc += wsrc_stride;
11716 mask += mask_stride;
11717 tmp += tmp_stride;
11718 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011719#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011720 }
11721 }
11722
11723 above += neighbor_bw;
11724 i += mi_step;
11725 } while (i < miw);
11726 }
11727
11728 for (i = 0; i < bw * bh; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -070011729 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
11730 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011731 }
11732
11733 // handle left column
11734 if (xd->left_available) {
11735 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -070011736 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011737 const int mi_col_offset = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -070011738 const uint8_t *const mask1d = av1_get_obmc_mask(overlap);
Yue Chen1bd42be2017-03-15 18:07:04 -070011739 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
11740 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011741
11742 assert(mih > 0);
11743
11744 i = 0;
11745 do { // for each mi in the left column
11746 const int mi_row_offset = i;
Jingning Hanad586b92017-05-23 10:24:57 -070011747 MB_MODE_INFO *left_mbmi =
Yaowu Xuc27fc142016-08-22 16:08:15 -070011748 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Hanad586b92017-05-23 10:24:57 -070011749
11750#if CONFIG_CHROMA_SUB8X8
11751 if (left_mbmi->sb_type < BLOCK_8X8)
11752 left_mbmi =
11753 &xd->mi[mi_col_offset + (mi_row_offset + 1) * xd->mi_stride]->mbmi;
11754#endif
Jingning Han680b09e2017-05-22 16:42:36 -070011755 const BLOCK_SIZE l_bsize = AOMMAX(left_mbmi->sb_type, BLOCK_8X8);
Jingning Han47433992017-05-02 09:03:57 -070011756 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070011757 const int neighbor_bh = mi_step * MI_SIZE;
11758
11759 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen1bd42be2017-03-15 18:07:04 -070011760 if (!CONFIG_CB4X4 && (l_bsize == BLOCK_4X4 || l_bsize == BLOCK_8X4))
11761 neighbor_count += 2;
11762 else
11763 neighbor_count++;
11764 if (neighbor_count > neighbor_limit) break;
11765
Yaowu Xuc27fc142016-08-22 16:08:15 -070011766 const int tmp_stride = left_stride;
11767 int32_t *wsrc = wsrc_buf + (i * MI_SIZE * wsrc_stride);
11768 int32_t *mask = mask_buf + (i * MI_SIZE * mask_stride);
11769
11770 if (!is_hbd) {
11771 const uint8_t *tmp = left;
11772
11773 for (row = 0; row < neighbor_bh; ++row) {
11774 for (col = 0; col < overlap; ++col) {
11775 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011776 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11777 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11778 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11779 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011780 }
11781 wsrc += wsrc_stride;
11782 mask += mask_stride;
11783 tmp += tmp_stride;
11784 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011785#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011786 } else {
11787 const uint16_t *tmp = CONVERT_TO_SHORTPTR(left);
11788
11789 for (row = 0; row < neighbor_bh; ++row) {
11790 for (col = 0; col < overlap; ++col) {
11791 const uint8_t m0 = mask1d[col];
Yaowu Xuf883b422016-08-30 14:01:10 -070011792 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
11793 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
11794 (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
11795 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
Yaowu Xuc27fc142016-08-22 16:08:15 -070011796 }
11797 wsrc += wsrc_stride;
11798 mask += mask_stride;
11799 tmp += tmp_stride;
11800 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011801#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011802 }
11803 }
11804
11805 left += neighbor_bh * left_stride;
11806 i += mi_step;
11807 } while (i < mih);
11808 }
11809
11810 if (!is_hbd) {
11811 const uint8_t *src = x->plane[0].src.buf;
11812
11813 for (row = 0; row < bh; ++row) {
11814 for (col = 0; col < bw; ++col) {
11815 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11816 }
11817 wsrc_buf += wsrc_stride;
11818 src += x->plane[0].src.stride;
11819 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011820#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011821 } else {
11822 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
11823
11824 for (row = 0; row < bh; ++row) {
11825 for (col = 0; col < bw; ++col) {
11826 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
11827 }
11828 wsrc_buf += wsrc_stride;
11829 src += x->plane[0].src.stride;
11830 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020011831#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070011832 }
11833}
Yue Chenf27b1602017-01-13 11:11:43 -080011834
11835#if CONFIG_NCOBMC
11836void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
11837 int mi_row, int mi_col) {
11838 const AV1_COMMON *const cm = &cpi->common;
11839 MACROBLOCKD *const xd = &x->e_mbd;
11840 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
11841 MB_MODE_INFO backup_mbmi;
11842 BLOCK_SIZE bsize = mbmi->sb_type;
11843 int ref, skip_blk, backup_skip = x->skip;
11844 int64_t rd_causal;
11845 RD_STATS rd_stats_y, rd_stats_uv;
11846 int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
11847 int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
11848
11849 // Recompute the best causal predictor and rd
11850 mbmi->motion_mode = SIMPLE_TRANSLATION;
11851 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
11852 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
11853 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
11854 assert(cfg != NULL);
11855 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
11856 &xd->block_refs[ref]->sf);
11857 }
Jingning Han91d9a792017-04-18 12:01:52 -070011858 av1_setup_dst_planes(x->e_mbd.plane, bsize,
11859 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
Yue Chenf27b1602017-01-13 11:11:43 -080011860
Jingning Hanc44009c2017-05-06 11:36:49 -070011861 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
Yue Chenf27b1602017-01-13 11:11:43 -080011862
11863 av1_subtract_plane(x, bsize, 0);
11864 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
11865 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
11866 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
11867 if (rd_stats_y.skip && rd_stats_uv.skip) {
11868 rd_stats_y.rate = rate_skip1;
11869 rd_stats_uv.rate = 0;
11870 rd_stats_y.dist = rd_stats_y.sse;
11871 rd_stats_uv.dist = rd_stats_uv.sse;
11872 skip_blk = 0;
Urvang Joshi70006e42017-06-14 16:08:55 -070011873 } else if (RDCOST(x->rdmult,
Yue Chenf27b1602017-01-13 11:11:43 -080011874 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
11875 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070011876 RDCOST(x->rdmult, rate_skip1,
Yue Chenf27b1602017-01-13 11:11:43 -080011877 (rd_stats_y.sse + rd_stats_uv.sse))) {
11878 rd_stats_y.rate = rate_skip1;
11879 rd_stats_uv.rate = 0;
11880 rd_stats_y.dist = rd_stats_y.sse;
11881 rd_stats_uv.dist = rd_stats_uv.sse;
11882 skip_blk = 1;
11883 } else {
11884 rd_stats_y.rate += rate_skip0;
11885 skip_blk = 0;
11886 }
11887 backup_skip = skip_blk;
11888 backup_mbmi = *mbmi;
Urvang Joshi70006e42017-06-14 16:08:55 -070011889 rd_causal = RDCOST(x->rdmult, (rd_stats_y.rate + rd_stats_uv.rate),
Yue Chenf27b1602017-01-13 11:11:43 -080011890 (rd_stats_y.dist + rd_stats_uv.dist));
Urvang Joshi70006e42017-06-14 16:08:55 -070011891 rd_causal +=
11892 RDCOST(x->rdmult, av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 0), 0);
Yue Chenf27b1602017-01-13 11:11:43 -080011893
11894 // Check non-causal mode
11895 mbmi->motion_mode = OBMC_CAUSAL;
11896 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
11897
11898 av1_subtract_plane(x, bsize, 0);
11899 super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);
11900 super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
11901 assert(rd_stats_y.rate != INT_MAX && rd_stats_uv.rate != INT_MAX);
11902 if (rd_stats_y.skip && rd_stats_uv.skip) {
11903 rd_stats_y.rate = rate_skip1;
11904 rd_stats_uv.rate = 0;
11905 rd_stats_y.dist = rd_stats_y.sse;
11906 rd_stats_uv.dist = rd_stats_uv.sse;
11907 skip_blk = 0;
Urvang Joshi70006e42017-06-14 16:08:55 -070011908 } else if (RDCOST(x->rdmult,
Yue Chenf27b1602017-01-13 11:11:43 -080011909 (rd_stats_y.rate + rd_stats_uv.rate + rate_skip0),
11910 (rd_stats_y.dist + rd_stats_uv.dist)) >
Urvang Joshi70006e42017-06-14 16:08:55 -070011911 RDCOST(x->rdmult, rate_skip1,
Yue Chenf27b1602017-01-13 11:11:43 -080011912 (rd_stats_y.sse + rd_stats_uv.sse))) {
11913 rd_stats_y.rate = rate_skip1;
11914 rd_stats_uv.rate = 0;
11915 rd_stats_y.dist = rd_stats_y.sse;
11916 rd_stats_uv.dist = rd_stats_uv.sse;
11917 skip_blk = 1;
11918 } else {
11919 rd_stats_y.rate += rate_skip0;
11920 skip_blk = 0;
11921 }
11922
11923 if (rd_causal >
Urvang Joshi70006e42017-06-14 16:08:55 -070011924 RDCOST(x->rdmult, rd_stats_y.rate + rd_stats_uv.rate +
11925 av1_cost_bit(cm->fc->motion_mode_prob[bsize][0], 1),
Yue Chenf27b1602017-01-13 11:11:43 -080011926 (rd_stats_y.dist + rd_stats_uv.dist))) {
11927 x->skip = skip_blk;
11928 } else {
11929 *mbmi = backup_mbmi;
11930 x->skip = backup_skip;
11931 }
11932}
Fergus Simpson4063a682017-02-28 16:52:22 -080011933#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -070011934#endif // CONFIG_MOTION_VAR