1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * 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.
10 */
11
12 #include <limits.h>
13 #include <math.h>
14 #include <stdio.h>
15
16 #include "./av1_rtcd.h"
17 #include "./aom_dsp_rtcd.h"
18 #include "./aom_config.h"
19
20 #include "aom_dsp/aom_dsp_common.h"
21 #include "aom_dsp/binary_codes_writer.h"
22 #include "aom_ports/mem.h"
23 #include "aom_ports/aom_timer.h"
24 #include "aom_ports/system_state.h"
25
26 #include "av1/common/common.h"
27 #include "av1/common/entropy.h"
28 #include "av1/common/entropymode.h"
29 #include "av1/common/idct.h"
30 #include "av1/common/mv.h"
31 #include "av1/common/mvref_common.h"
32 #include "av1/common/pred_common.h"
33 #include "av1/common/quant_common.h"
34 #include "av1/common/reconintra.h"
35 #include "av1/common/reconinter.h"
36 #include "av1/common/seg_common.h"
37 #include "av1/common/tile_common.h"
38
39 #include "av1/encoder/aq_complexity.h"
40 #include "av1/encoder/aq_cyclicrefresh.h"
41 #include "av1/encoder/aq_variance.h"
42 #if CONFIG_SUPERTX
43 #include "av1/encoder/cost.h"
44 #endif
45 #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
46 #include "av1/common/warped_motion.h"
47 #endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
48 #if CONFIG_GLOBAL_MOTION
49 #include "av1/encoder/global_motion.h"
50 #endif // CONFIG_GLOBAL_MOTION
51 #include "av1/encoder/encodeframe.h"
52 #include "av1/encoder/encodemb.h"
53 #include "av1/encoder/encodemv.h"
54 #if CONFIG_LV_MAP
55 #include "av1/encoder/encodetxb.h"
56 #endif
57 #include "av1/encoder/ethread.h"
58 #include "av1/encoder/extend.h"
59 #include "av1/encoder/rd.h"
60 #include "av1/encoder/rdopt.h"
61 #include "av1/encoder/segmentation.h"
62 #include "av1/encoder/tokenize.h"
63 #if CONFIG_PVQ
64 #include "av1/common/pvq.h"
65 #include "av1/encoder/pvq_encoder.h"
66 #endif
67 #if CONFIG_HIGHBITDEPTH
68 #define IF_HBD(...) __VA_ARGS__
69 #else
70 #define IF_HBD(...)
71 #endif // CONFIG_HIGHBITDEPTH
72
73 static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
74 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
75 int mi_col, BLOCK_SIZE bsize, int *rate);
76
77 #if CONFIG_SUPERTX
78 static int check_intra_b(PICK_MODE_CONTEXT *ctx);
79
80 static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
81 int mi_row, int mi_col, BLOCK_SIZE bsize,
82 PC_TREE *pc_tree);
83 static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
84 int mi_row_ori, int mi_col_ori, int mi_row_pred,
85 int mi_col_pred, int plane,
86 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
87 static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
88 PC_TREE *pc_tree);
89 static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
90 const TileInfo *const tile, int mi_row,
91 int mi_col, int mi_row_ori, int mi_col_ori,
92 RUN_TYPE dry_run, BLOCK_SIZE bsize,
93 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
94 int dst_stride[3], PC_TREE *pc_tree);
95 static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
96 const TileInfo *const tile, int mi_row,
97 int mi_col, BLOCK_SIZE bsize,
98 RUN_TYPE dry_run, PC_TREE *pc_tree);
99 static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
100 const TileInfo *const tile, int mi_row, int mi_col,
101 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
102 TX_TYPE *best_tx, PC_TREE *pc_tree);
103 #endif // CONFIG_SUPERTX
104
105 // This is used as a reference when computing the source variance for the
106 // purposes of activity masking.
107 // Eventually this should be replaced by custom no-reference routines,
108 // which will be faster.
109 static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
110 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
111 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
113 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
114 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115 #if CONFIG_EXT_PARTITION
116 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
117 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
118 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
119 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
120 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
121 #endif // CONFIG_EXT_PARTITION
122 };
123
124 #if CONFIG_HIGHBITDEPTH
125 static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
126 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
127 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
129 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
130 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
131 #if CONFIG_EXT_PARTITION
132 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
133 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
134 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
135 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
136 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
137 #endif // CONFIG_EXT_PARTITION
138 };
139
140 static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
141 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
142 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
143 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
144 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
145 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
146 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
147 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
148 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
149 #if CONFIG_EXT_PARTITION
150 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
151 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
152 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
153 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
154 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
155 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
156 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
157 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
158 #endif // CONFIG_EXT_PARTITION
159 };
160
161 static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
162 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
163 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
164 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
165 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
166 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
167 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
168 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
169 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
170 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
171 128 * 16,
172 #if CONFIG_EXT_PARTITION
173 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
174 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
175 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
176 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
177 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
178 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
179 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
180 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
181 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
182 128 * 16
183 #endif // CONFIG_EXT_PARTITION
184 };
185 #endif // CONFIG_HIGHBITDEPTH
186
av1_get_sby_perpixel_variance(const AV1_COMP * cpi,const struct buf_2d * ref,BLOCK_SIZE bs)187 unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
188 const struct buf_2d *ref,
189 BLOCK_SIZE bs) {
190 unsigned int sse;
191 const unsigned int var =
192 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
193 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
194 }
195
196 #if CONFIG_HIGHBITDEPTH
av1_high_get_sby_perpixel_variance(const AV1_COMP * cpi,const struct buf_2d * ref,BLOCK_SIZE bs,int bd)197 unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
198 const struct buf_2d *ref,
199 BLOCK_SIZE bs, int bd) {
200 unsigned int var, sse;
201 switch (bd) {
202 case 10:
203 var =
204 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
205 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
206 break;
207 case 12:
208 var =
209 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
210 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
211 break;
212 case 8:
213 default:
214 var =
215 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
216 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
217 break;
218 }
219 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
220 }
221 #endif // CONFIG_HIGHBITDEPTH
222
get_sby_perpixel_diff_variance(const AV1_COMP * const cpi,const struct buf_2d * ref,int mi_row,int mi_col,BLOCK_SIZE bs)223 static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
224 const struct buf_2d *ref,
225 int mi_row, int mi_col,
226 BLOCK_SIZE bs) {
227 unsigned int sse, var;
228 uint8_t *last_y;
229 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
230
231 assert(last != NULL);
232 last_y =
233 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
234 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
235 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
236 }
237
get_rd_var_based_fixed_partition(AV1_COMP * cpi,MACROBLOCK * x,int mi_row,int mi_col)238 static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
239 int mi_row, int mi_col) {
240 unsigned int var = get_sby_perpixel_diff_variance(
241 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
242 if (var < 8)
243 return BLOCK_64X64;
244 else if (var < 128)
245 return BLOCK_32X32;
246 else if (var < 2048)
247 return BLOCK_16X16;
248 else
249 return BLOCK_8X8;
250 }
251
252 // Lighter version of set_offsets that only sets the mode info
253 // pointers.
set_mode_info_offsets(const AV1_COMP * const cpi,MACROBLOCK * const x,MACROBLOCKD * const xd,int mi_row,int mi_col)254 static void set_mode_info_offsets(const AV1_COMP *const cpi,
255 MACROBLOCK *const x, MACROBLOCKD *const xd,
256 int mi_row, int mi_col) {
257 const AV1_COMMON *const cm = &cpi->common;
258 const int idx_str = xd->mi_stride * mi_row + mi_col;
259 xd->mi = cm->mi_grid_visible + idx_str;
260 xd->mi[0] = cm->mi + idx_str;
261 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
262 }
263
set_offsets_without_segment_id(const AV1_COMP * const cpi,const TileInfo * const tile,MACROBLOCK * const x,int mi_row,int mi_col,BLOCK_SIZE bsize)264 static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
265 const TileInfo *const tile,
266 MACROBLOCK *const x, int mi_row,
267 int mi_col, BLOCK_SIZE bsize) {
268 const AV1_COMMON *const cm = &cpi->common;
269 MACROBLOCKD *const xd = &x->e_mbd;
270 const int mi_width = mi_size_wide[bsize];
271 const int mi_height = mi_size_high[bsize];
272
273 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
274
275 set_skip_context(xd, mi_row, mi_col);
276 #if CONFIG_VAR_TX
277 xd->above_txfm_context =
278 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
279 xd->left_txfm_context = xd->left_txfm_context_buffer +
280 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
281 xd->max_tx_size = max_txsize_lookup[bsize];
282 #endif
283
284 // Set up destination pointers.
285 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
286 mi_col);
287
288 // Set up limit values for MV components.
289 // Mv beyond the range do not produce new/different prediction block.
290 x->mv_limits.row_min =
291 -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
292 x->mv_limits.col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
293 x->mv_limits.row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
294 x->mv_limits.col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
295
296 set_plane_n4(xd, mi_width, mi_height);
297
298 // Set up distance of MB to edge of frame in 1/8th pel units.
299 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
300 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
301 #if CONFIG_DEPENDENT_HORZTILES
302 cm->dependent_horz_tiles,
303 #endif // CONFIG_DEPENDENT_HORZTILES
304 cm->mi_rows, cm->mi_cols);
305
306 // Set up source buffers.
307 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
308
309 // R/D setup.
310 x->rdmult = cpi->rd.RDMULT;
311
312 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
313 xd->tile = *tile;
314 }
315
set_offsets(const AV1_COMP * const cpi,const TileInfo * const tile,MACROBLOCK * const x,int mi_row,int mi_col,BLOCK_SIZE bsize)316 static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
317 MACROBLOCK *const x, int mi_row, int mi_col,
318 BLOCK_SIZE bsize) {
319 const AV1_COMMON *const cm = &cpi->common;
320 MACROBLOCKD *const xd = &x->e_mbd;
321 MB_MODE_INFO *mbmi;
322 const struct segmentation *const seg = &cm->seg;
323
324 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
325
326 mbmi = &xd->mi[0]->mbmi;
327 #if CONFIG_CFL
328 xd->cfl->mi_row = mi_row;
329 xd->cfl->mi_col = mi_col;
330 #endif
331
332 // Setup segment ID.
333 if (seg->enabled) {
334 if (!cpi->vaq_refresh) {
335 const uint8_t *const map =
336 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
337 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
338 }
339 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
340 } else {
341 mbmi->segment_id = 0;
342 }
343
344 #if CONFIG_SUPERTX
345 mbmi->segment_id_supertx = MAX_SEGMENTS;
346 #endif // CONFIG_SUPERTX
347 }
348
349 #if CONFIG_SUPERTX
set_offsets_supertx(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int mi_row,int mi_col,BLOCK_SIZE bsize)350 static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
351 const TileInfo *const tile, int mi_row,
352 int mi_col, BLOCK_SIZE bsize) {
353 MACROBLOCK *const x = &td->mb;
354 const AV1_COMMON *const cm = &cpi->common;
355 MACROBLOCKD *const xd = &x->e_mbd;
356 const int mi_width = mi_size_wide[bsize];
357 const int mi_height = mi_size_high[bsize];
358 #if CONFIG_DEPENDENT_HORZTILES
359 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col, cm->dependent_horz_tiles);
360 #else
361 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
362 #endif
363
364 // Set up distance of MB to edge of frame in 1/8th pel units.
365 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
366 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width,
367 #if CONFIG_DEPENDENT_HORZTILES
368 cm->dependent_horz_tiles,
369 #endif // CONFIG_DEPENDENT_HORZTILES
370 cm->mi_rows, cm->mi_cols);
371 }
372
set_offsets_extend(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int mi_row_pred,int mi_col_pred,int mi_row_ori,int mi_col_ori,BLOCK_SIZE bsize_pred)373 static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
374 const TileInfo *const tile, int mi_row_pred,
375 int mi_col_pred, int mi_row_ori, int mi_col_ori,
376 BLOCK_SIZE bsize_pred) {
377 // Used in supertx
378 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
379 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
380 MACROBLOCK *const x = &td->mb;
381 const AV1_COMMON *const cm = &cpi->common;
382 MACROBLOCKD *const xd = &x->e_mbd;
383 const int mi_width = mi_size_wide[bsize_pred];
384 const int mi_height = mi_size_high[bsize_pred];
385
386 #if CONFIG_DEPENDENT_HORZTILES
387 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori,
388 cm->dependent_horz_tiles);
389 #else
390 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
391 #endif
392
393 // Set up limit values for MV components.
394 // Mv beyond the range do not produce new/different prediction block.
395 x->mv_limits.row_min =
396 -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
397 x->mv_limits.col_min =
398 -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
399 x->mv_limits.row_max =
400 (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
401 x->mv_limits.col_max =
402 (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
403
404 // Set up distance of MB to edge of frame in 1/8th pel units.
405 #if !CONFIG_CB4X4
406 assert(!(mi_col_pred & (mi_width - mi_size_wide[BLOCK_8X8])) &&
407 !(mi_row_pred & (mi_height - mi_size_high[BLOCK_8X8])));
408 #endif
409 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
410 #if CONFIG_DEPENDENT_HORZTILES
411 cm->dependent_horz_tiles,
412 #endif // CONFIG_DEPENDENT_HORZTILES
413 cm->mi_rows, cm->mi_cols);
414 xd->up_available = (mi_row_ori > tile->mi_row_start);
415 xd->left_available = (mi_col_ori > tile->mi_col_start);
416
417 // R/D setup.
418 x->rdmult = cpi->rd.RDMULT;
419 }
420
set_segment_id_supertx(const AV1_COMP * const cpi,MACROBLOCK * const x,const int mi_row,const int mi_col,const BLOCK_SIZE bsize)421 static void set_segment_id_supertx(const AV1_COMP *const cpi,
422 MACROBLOCK *const x, const int mi_row,
423 const int mi_col, const BLOCK_SIZE bsize) {
424 const AV1_COMMON *cm = &cpi->common;
425 const struct segmentation *seg = &cm->seg;
426 const int miw = AOMMIN(mi_size_wide[bsize], cm->mi_cols - mi_col);
427 const int mih = AOMMIN(mi_size_high[bsize], cm->mi_rows - mi_row);
428 const int mi_offset = mi_row * cm->mi_stride + mi_col;
429 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
430 int r, c;
431 int seg_id_supertx = MAX_SEGMENTS;
432
433 if (!seg->enabled) {
434 seg_id_supertx = 0;
435 } else {
436 // Find the minimum segment_id
437 for (r = 0; r < mih; r++)
438 for (c = 0; c < miw; c++)
439 seg_id_supertx =
440 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
441 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
442
443 // Initialize plane quantisers
444 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
445 }
446
447 // Assign the the segment_id back to segment_id_supertx
448 for (r = 0; r < mih; r++)
449 for (c = 0; c < miw; c++)
450 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
451 }
452 #endif // CONFIG_SUPERTX
453
454 #if CONFIG_DUAL_FILTER
reset_intmv_filter_type(const AV1_COMMON * const cm,MACROBLOCKD * xd,MB_MODE_INFO * mbmi)455 static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
456 MB_MODE_INFO *mbmi) {
457 InterpFilter filters[2];
458 InterpFilter default_filter = av1_unswitchable_filter(cm->interp_filter);
459
460 for (int dir = 0; dir < 2; ++dir) {
461 filters[dir] = ((!has_subpel_mv_component(xd->mi[0], xd, dir) &&
462 (mbmi->ref_frame[1] == NONE_FRAME ||
463 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
464 ? default_filter
465 : av1_extract_interp_filter(mbmi->interp_filters, dir));
466 }
467 mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
468 }
469
update_filter_type_count(FRAME_COUNTS * counts,const MACROBLOCKD * xd,const MB_MODE_INFO * mbmi)470 static void update_filter_type_count(FRAME_COUNTS *counts,
471 const MACROBLOCKD *xd,
472 const MB_MODE_INFO *mbmi) {
473 int dir;
474 for (dir = 0; dir < 2; ++dir) {
475 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
476 (mbmi->ref_frame[1] > INTRA_FRAME &&
477 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
478 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
479 InterpFilter filter =
480 av1_extract_interp_filter(mbmi->interp_filters, dir);
481 ++counts->switchable_interp[ctx][filter];
482 update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
483 SWITCHABLE_FILTERS);
484 }
485 }
486 }
487 #endif
488 #if CONFIG_GLOBAL_MOTION
update_global_motion_used(PREDICTION_MODE mode,BLOCK_SIZE bsize,const MB_MODE_INFO * mbmi,RD_COUNTS * rdc)489 static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
490 const MB_MODE_INFO *mbmi,
491 RD_COUNTS *rdc) {
492 if (mode == ZEROMV || mode == ZERO_ZEROMV) {
493 const int num_4x4s =
494 num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
495 int ref;
496 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
497 rdc->global_motion_used[mbmi->ref_frame[ref]] += num_4x4s;
498 }
499 }
500 }
501 #endif // CONFIG_GLOBAL_MOTION
502
reset_tx_size(MACROBLOCKD * xd,MB_MODE_INFO * mbmi,const TX_MODE tx_mode)503 static void reset_tx_size(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
504 const TX_MODE tx_mode) {
505 if (xd->lossless[mbmi->segment_id]) {
506 mbmi->tx_size = TX_4X4;
507 } else if (tx_mode != TX_MODE_SELECT) {
508 mbmi->tx_size =
509 tx_size_from_tx_mode(mbmi->sb_type, tx_mode, is_inter_block(mbmi));
510 }
511 }
512
set_ref_and_pred_mvs(MACROBLOCK * const x,int_mv * const mi_pred_mv,int8_t rf_type)513 static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
514 int8_t rf_type) {
515 MACROBLOCKD *const xd = &x->e_mbd;
516 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
517
518 const int bw = xd->n8_w << MI_SIZE_LOG2;
519 const int bh = xd->n8_h << MI_SIZE_LOG2;
520 int ref_mv_idx = mbmi->ref_mv_idx;
521 MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
522 CANDIDATE_MV *const curr_ref_mv_stack = mbmi_ext->ref_mv_stack[rf_type];
523
524 if (has_second_ref(mbmi)) {
525 // Special case: NEAR_NEWMV and NEW_NEARMV modes use 1 + mbmi->ref_mv_idx
526 // (like NEARMV) instead
527 if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEW_NEARMV) ref_mv_idx += 1;
528
529 if (compound_ref0_mode(mbmi->mode) == NEWMV) {
530 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
531 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
532 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
533 mbmi->pred_mv[0] = this_mv;
534 mi_pred_mv[0] = this_mv;
535 }
536 if (compound_ref1_mode(mbmi->mode) == NEWMV) {
537 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
538 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
539 mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0] = this_mv;
540 mbmi->pred_mv[1] = this_mv;
541 mi_pred_mv[1] = this_mv;
542 }
543 #if CONFIG_COMPOUND_SINGLEREF
544 } else if (is_inter_singleref_comp_mode(mbmi->mode)) {
545 // Special case: SR_NEAR_NEWMV uses 1 + mbmi->ref_mv_idx
546 // (like NEARMV) instead
547 if (mbmi->mode == SR_NEAR_NEWMV) ref_mv_idx += 1;
548
549 if (compound_ref0_mode(mbmi->mode) == NEWMV ||
550 compound_ref1_mode(mbmi->mode) == NEWMV) {
551 int_mv this_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
552 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
553 mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0] = this_mv;
554 mbmi->pred_mv[0] = this_mv;
555 mi_pred_mv[0] = this_mv;
556 }
557 #endif // CONFIG_COMPOUND_SINGLEREF
558 } else {
559 if (mbmi->mode == NEWMV) {
560 int i;
561 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
562 int_mv this_mv = (i == 0) ? curr_ref_mv_stack[ref_mv_idx].this_mv
563 : curr_ref_mv_stack[ref_mv_idx].comp_mv;
564 clamp_mv_ref(&this_mv.as_mv, bw, bh, xd);
565 mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
566 mbmi->pred_mv[i] = this_mv;
567 mi_pred_mv[i] = this_mv;
568 }
569 }
570 }
571 }
572
update_state(const AV1_COMP * const cpi,ThreadData * td,PICK_MODE_CONTEXT * ctx,int mi_row,int mi_col,BLOCK_SIZE bsize,RUN_TYPE dry_run)573 static void update_state(const AV1_COMP *const cpi, ThreadData *td,
574 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
575 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
576 int i, x_idx, y;
577 const AV1_COMMON *const cm = &cpi->common;
578 RD_COUNTS *const rdc = &td->rd_counts;
579 MACROBLOCK *const x = &td->mb;
580 MACROBLOCKD *const xd = &x->e_mbd;
581 struct macroblock_plane *const p = x->plane;
582 struct macroblockd_plane *const pd = xd->plane;
583 MODE_INFO *mi = &ctx->mic;
584 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
585 MODE_INFO *mi_addr = xd->mi[0];
586 const struct segmentation *const seg = &cm->seg;
587 const int bw = mi_size_wide[mi->mbmi.sb_type];
588 const int bh = mi_size_high[mi->mbmi.sb_type];
589 const int mis = cm->mi_stride;
590 const int mi_width = mi_size_wide[bsize];
591 const int mi_height = mi_size_high[bsize];
592 const int unify_bsize = CONFIG_CB4X4;
593
594 int8_t rf_type;
595
596 #if !CONFIG_SUPERTX
597 assert(mi->mbmi.sb_type == bsize);
598 #endif
599
600 *mi_addr = *mi;
601 *x->mbmi_ext = ctx->mbmi_ext;
602
603 #if CONFIG_DUAL_FILTER
604 reset_intmv_filter_type(cm, xd, mbmi);
605 #endif
606
607 rf_type = av1_ref_frame_type(mbmi->ref_frame);
608 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
609 (mbmi->sb_type >= BLOCK_8X8 || unify_bsize)) {
610 set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
611 }
612
613 // If segmentation in use
614 if (seg->enabled) {
615 // For in frame complexity AQ copy the segment id from the segment map.
616 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
617 const uint8_t *const map =
618 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
619 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
620 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
621 }
622 // Else for cyclic refresh mode update the segment map, set the segment id
623 // and then update the quantizer.
624 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
625 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
626 bsize, ctx->rate, ctx->dist, x->skip);
627 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
628 }
629 }
630
631 for (i = 0; i < MAX_MB_PLANE; ++i) {
632 p[i].coeff = ctx->coeff[i];
633 p[i].qcoeff = ctx->qcoeff[i];
634 pd[i].dqcoeff = ctx->dqcoeff[i];
635 #if CONFIG_PVQ
636 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
637 #endif
638 p[i].eobs = ctx->eobs[i];
639 #if CONFIG_LV_MAP
640 p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
641 #endif // CONFIG_LV_MAP
642 }
643 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
644 #if CONFIG_MRC_TX
645 xd->mrc_mask = ctx->mrc_mask;
646 #endif // CONFIG_MRC_TX
647 // Restore the coding context of the MB to that that was in place
648 // when the mode was picked for it
649 for (y = 0; y < mi_height; y++)
650 for (x_idx = 0; x_idx < mi_width; x_idx++)
651 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
652 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
653 xd->mi[x_idx + y * mis] = mi_addr;
654 }
655
656 #if !CONFIG_EXT_DELTA_Q
657 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
658 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
659 #else
660 if (cpi->oxcf.aq_mode)
661 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
662 #endif
663
664 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8 && !unify_bsize) {
665 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
666 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
667 }
668
669 x->skip = ctx->skip;
670
671 #if CONFIG_VAR_TX
672 for (i = 0; i < 1; ++i)
673 memcpy(x->blk_skip[i], ctx->blk_skip[i],
674 sizeof(uint8_t) * ctx->num_4x4_blk);
675 #endif
676
677 if (dry_run) return;
678
679 #if CONFIG_INTERNAL_STATS
680 {
681 unsigned int *const mode_chosen_counts =
682 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
683 if (frame_is_intra_only(cm)) {
684 static const int kf_mode_index[] = {
685 THR_DC /*DC_PRED*/,
686 THR_V_PRED /*V_PRED*/,
687 THR_H_PRED /*H_PRED*/,
688 THR_D45_PRED /*D45_PRED*/,
689 THR_D135_PRED /*D135_PRED*/,
690 THR_D117_PRED /*D117_PRED*/,
691 THR_D153_PRED /*D153_PRED*/,
692 THR_D207_PRED /*D207_PRED*/,
693 THR_D63_PRED /*D63_PRED*/,
694 THR_SMOOTH, /*SMOOTH_PRED*/
695 #if CONFIG_SMOOTH_HV
696 THR_SMOOTH_V, /*SMOOTH_V_PRED*/
697 THR_SMOOTH_H, /*SMOOTH_H_PRED*/
698 #endif // CONFIG_SMOOTH_HV
699 THR_TM /*TM_PRED*/,
700 };
701 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
702 } else {
703 // Note how often each mode chosen as best
704 ++mode_chosen_counts[ctx->best_mode_index];
705 }
706 }
707 #endif
708 if (!frame_is_intra_only(cm)) {
709 if (is_inter_block(mbmi)) {
710 av1_update_mv_count(td);
711 #if CONFIG_GLOBAL_MOTION
712 if (bsize >= BLOCK_8X8) {
713 // TODO(sarahparker): global motion stats need to be handled per-tile
714 // to be compatible with tile-based threading.
715 update_global_motion_used(mbmi->mode, bsize, mbmi, rdc);
716 } else {
717 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
718 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
719 int idx, idy;
720 for (idy = 0; idy < 2; idy += num_4x4_h) {
721 for (idx = 0; idx < 2; idx += num_4x4_w) {
722 const int j = idy * 2 + idx;
723 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi, rdc);
724 }
725 }
726 }
727 #endif // CONFIG_GLOBAL_MOTION
728 if (cm->interp_filter == SWITCHABLE
729 #if CONFIG_WARPED_MOTION
730 && mbmi->motion_mode != WARPED_CAUSAL
731 #endif // CONFIG_WARPED_MOTION
732 #if CONFIG_GLOBAL_MOTION
733 && !is_nontrans_global_motion(xd)
734 #endif // CONFIG_GLOBAL_MOTION
735 ) {
736 #if CONFIG_DUAL_FILTER
737 update_filter_type_count(td->counts, xd, mbmi);
738 #else
739 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
740 const InterpFilter filter =
741 av1_extract_interp_filter(mbmi->interp_filters, 0);
742 ++td->counts->switchable_interp[switchable_ctx][filter];
743 #endif
744 }
745 }
746
747 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
748 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
749 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
750 }
751
752 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
753 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
754 av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
755 }
756
757 #if CONFIG_SUPERTX
update_state_supertx(const AV1_COMP * const cpi,ThreadData * td,PICK_MODE_CONTEXT * ctx,int mi_row,int mi_col,BLOCK_SIZE bsize,RUN_TYPE dry_run)758 static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
759 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
760 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
761 int y, x_idx;
762 #if CONFIG_VAR_TX
763 int i;
764 #endif
765 const AV1_COMMON *const cm = &cpi->common;
766 RD_COUNTS *const rdc = &td->rd_counts;
767 MACROBLOCK *const x = &td->mb;
768 MACROBLOCKD *const xd = &x->e_mbd;
769 MODE_INFO *mi = &ctx->mic;
770 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
771 MODE_INFO *mi_addr = xd->mi[0];
772 const struct segmentation *const seg = &cm->seg;
773 const int mis = cm->mi_stride;
774 const int mi_width = mi_size_wide[bsize];
775 const int mi_height = mi_size_high[bsize];
776 const int unify_bsize = CONFIG_CB4X4;
777 int8_t rf_type;
778
779 *mi_addr = *mi;
780 *x->mbmi_ext = ctx->mbmi_ext;
781 assert(is_inter_block(mbmi));
782 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
783
784 #if CONFIG_DUAL_FILTER
785 reset_intmv_filter_type(cm, xd, mbmi);
786 #endif
787
788 rf_type = av1_ref_frame_type(mbmi->ref_frame);
789 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
790 (mbmi->sb_type >= BLOCK_8X8 || unify_bsize)) {
791 set_ref_and_pred_mvs(x, mi->mbmi.pred_mv, rf_type);
792 }
793
794 // If segmentation in use
795 if (seg->enabled) {
796 if (cpi->vaq_refresh) {
797 const int energy =
798 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
799 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
800 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
801 // For cyclic refresh mode, now update the segment map
802 // and set the segment id.
803 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
804 bsize, ctx->rate, ctx->dist, 1);
805 } else {
806 // Otherwise just set the segment id based on the current segment map
807 const uint8_t *const map =
808 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
809 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
810 }
811 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
812 }
813 // Restore the coding context of the MB to that that was in place
814 // when the mode was picked for it
815 for (y = 0; y < mi_height; y++)
816 for (x_idx = 0; x_idx < mi_width; x_idx++)
817 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
818 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
819 xd->mi[x_idx + y * mis] = mi_addr;
820 }
821
822 #if !CONFIG_CB4X4
823 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
824 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
825 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
826 }
827 #endif
828
829 x->skip = ctx->skip;
830
831 #if CONFIG_VAR_TX
832 for (i = 0; i < 1; ++i)
833 memcpy(x->blk_skip[i], ctx->blk_skip[i],
834 sizeof(uint8_t) * ctx->num_4x4_blk);
835
836 if (!is_inter_block(mbmi) || mbmi->skip)
837 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
838 #endif // CONFIG_VAR_TX
839
840 #if CONFIG_VAR_TX
841 {
842 const TX_SIZE mtx = mbmi->tx_size;
843 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
844 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
845 int idy, idx;
846 mbmi->inter_tx_size[0][0] = mtx;
847 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
848 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
849 mbmi->inter_tx_size[idy][idx] = mtx;
850 }
851 #endif // CONFIG_VAR_TX
852 // Turn motion variation off for supertx
853 mbmi->motion_mode = SIMPLE_TRANSLATION;
854
855 if (dry_run) return;
856
857 if (!frame_is_intra_only(cm)) {
858 av1_update_mv_count(td);
859
860 #if CONFIG_GLOBAL_MOTION
861 if (is_inter_block(mbmi)) {
862 if (bsize >= BLOCK_8X8) {
863 // TODO(sarahparker): global motion stats need to be handled per-tile
864 // to be compatible with tile-based threading.
865 update_global_motion_used(mbmi->mode, bsize, mbmi, rdc);
866 } else {
867 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
868 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
869 int idx, idy;
870 for (idy = 0; idy < 2; idy += num_4x4_h) {
871 for (idx = 0; idx < 2; idx += num_4x4_w) {
872 const int j = idy * 2 + idx;
873 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi, rdc);
874 }
875 }
876 }
877 }
878 #endif // CONFIG_GLOBAL_MOTION
879
880 if (cm->interp_filter == SWITCHABLE
881 #if CONFIG_GLOBAL_MOTION
882 && !is_nontrans_global_motion(xd)
883 #endif // CONFIG_GLOBAL_MOTION
884 ) {
885 #if CONFIG_DUAL_FILTER
886 update_filter_type_count(td->counts, xd, mbmi);
887 #else
888 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
889 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
890 #endif
891 }
892
893 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
894 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
895 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
896 }
897
898 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
899 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
900 av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
901 }
902
update_state_sb_supertx(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int mi_row,int mi_col,BLOCK_SIZE bsize,RUN_TYPE dry_run,PC_TREE * pc_tree)903 static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
904 const TileInfo *const tile, int mi_row,
905 int mi_col, BLOCK_SIZE bsize,
906 RUN_TYPE dry_run, PC_TREE *pc_tree) {
907 const AV1_COMMON *const cm = &cpi->common;
908 MACROBLOCK *const x = &td->mb;
909 MACROBLOCKD *const xd = &x->e_mbd;
910 struct macroblock_plane *const p = x->plane;
911 struct macroblockd_plane *const pd = xd->plane;
912 int hbs = mi_size_wide[bsize] / 2;
913 #if CONFIG_CB4X4
914 const int unify_bsize = 1;
915 #else
916 const int unify_bsize = 0;
917 #endif
918 PARTITION_TYPE partition = pc_tree->partitioning;
919 BLOCK_SIZE subsize = get_subsize(bsize, partition);
920 int i;
921 #if CONFIG_EXT_PARTITION_TYPES
922 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
923 #endif
924 PICK_MODE_CONTEXT *pmc = NULL;
925
926 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
927
928 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
929 x->mb_energy = av1_block_energy(cpi, x, bsize);
930
931 switch (partition) {
932 case PARTITION_NONE:
933 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
934 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
935 dry_run);
936 break;
937 case PARTITION_VERT:
938 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
939 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
940 subsize, dry_run);
941 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
942 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
943 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
944 mi_col + hbs, subsize, dry_run);
945 }
946 pmc = &pc_tree->vertical_supertx;
947 break;
948 case PARTITION_HORZ:
949 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
950 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
951 subsize, dry_run);
952 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
953 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
954 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
955 mi_col, subsize, dry_run);
956 }
957 pmc = &pc_tree->horizontal_supertx;
958 break;
959 case PARTITION_SPLIT:
960 if (bsize == BLOCK_8X8 && !unify_bsize) {
961 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
962 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
963 subsize, dry_run);
964 } else {
965 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
966 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
967 pc_tree->split[0]);
968 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
969 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
970 dry_run, pc_tree->split[1]);
971 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
972 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
973 dry_run, pc_tree->split[2]);
974 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
975 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
976 subsize, dry_run, pc_tree->split[3]);
977 }
978 pmc = &pc_tree->split_supertx;
979 break;
980 #if CONFIG_EXT_PARTITION_TYPES
981 #if CONFIG_EXT_PARTITION_TYPES_AB
982 #error HORZ/VERT_A/B partitions not yet updated in superres code
983 #endif
984 case PARTITION_HORZ_A:
985 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
986 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
987 bsize2, dry_run);
988 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
989 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
990 mi_col + hbs, bsize2, dry_run);
991 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
992 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
993 mi_col, subsize, dry_run);
994 pmc = &pc_tree->horizontala_supertx;
995 break;
996 case PARTITION_HORZ_B:
997 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
998 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
999 subsize, dry_run);
1000 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1001 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
1002 mi_col, bsize2, dry_run);
1003 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1004 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
1005 mi_col + hbs, bsize2, dry_run);
1006 pmc = &pc_tree->horizontalb_supertx;
1007 break;
1008 case PARTITION_VERT_A:
1009 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1010 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
1011 bsize2, dry_run);
1012 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1013 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
1014 mi_col, bsize2, dry_run);
1015 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1016 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
1017 mi_col + hbs, subsize, dry_run);
1018 pmc = &pc_tree->verticala_supertx;
1019 break;
1020 case PARTITION_VERT_B:
1021 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1022 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
1023 subsize, dry_run);
1024 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1025 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
1026 mi_col + hbs, bsize2, dry_run);
1027 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1028 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
1029 mi_col + hbs, bsize2, dry_run);
1030 pmc = &pc_tree->verticalb_supertx;
1031 break;
1032 #endif // CONFIG_EXT_PARTITION_TYPES
1033 default: assert(0);
1034 }
1035
1036 for (i = 0; i < MAX_MB_PLANE; ++i) {
1037 if (pmc != NULL) {
1038 p[i].coeff = pmc->coeff[i];
1039 p[i].qcoeff = pmc->qcoeff[i];
1040 pd[i].dqcoeff = pmc->dqcoeff[i];
1041 p[i].eobs = pmc->eobs[i];
1042 } else {
1043 // These should never be used
1044 p[i].coeff = NULL;
1045 p[i].qcoeff = NULL;
1046 pd[i].dqcoeff = NULL;
1047 p[i].eobs = NULL;
1048 }
1049 }
1050 }
1051
update_supertx_param(ThreadData * td,PICK_MODE_CONTEXT * ctx,int best_tx,TX_SIZE supertx_size)1052 static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1053 int best_tx, TX_SIZE supertx_size) {
1054 MACROBLOCK *const x = &td->mb;
1055 #if CONFIG_VAR_TX
1056 int i;
1057
1058 for (i = 0; i < 1; ++i)
1059 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1060 sizeof(uint8_t) * ctx->num_4x4_blk);
1061 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
1062 #endif // CONFIG_VAR_TX
1063 ctx->mic.mbmi.tx_size = supertx_size;
1064 ctx->skip = x->skip;
1065 ctx->mic.mbmi.tx_type = best_tx;
1066 }
1067
update_supertx_param_sb(const AV1_COMP * const cpi,ThreadData * td,int mi_row,int mi_col,BLOCK_SIZE bsize,int best_tx,TX_SIZE supertx_size,PC_TREE * pc_tree)1068 static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1069 int mi_row, int mi_col, BLOCK_SIZE bsize,
1070 int best_tx, TX_SIZE supertx_size,
1071 PC_TREE *pc_tree) {
1072 const AV1_COMMON *const cm = &cpi->common;
1073 const int hbs = mi_size_wide[bsize] / 2;
1074 PARTITION_TYPE partition = pc_tree->partitioning;
1075 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1076 #if CONFIG_CB4X4
1077 const int unify_bsize = 1;
1078 #else
1079 const int unify_bsize = 0;
1080 #endif
1081 #if CONFIG_EXT_PARTITION_TYPES
1082 int i;
1083 #endif
1084
1085 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1086
1087 switch (partition) {
1088 case PARTITION_NONE:
1089 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1090 break;
1091 case PARTITION_VERT:
1092 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
1093 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize))
1094 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1095 break;
1096 case PARTITION_HORZ:
1097 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
1098 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize))
1099 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1100 supertx_size);
1101 break;
1102 case PARTITION_SPLIT:
1103 if (bsize == BLOCK_8X8 && !unify_bsize) {
1104 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1105 } else {
1106 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1107 supertx_size, pc_tree->split[0]);
1108 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1109 supertx_size, pc_tree->split[1]);
1110 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1111 supertx_size, pc_tree->split[2]);
1112 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1113 best_tx, supertx_size, pc_tree->split[3]);
1114 }
1115 break;
1116 #if CONFIG_EXT_PARTITION_TYPES
1117 #if CONFIG_EXT_PARTITION_TYPES_AB
1118 #error HORZ/VERT_A/B partitions not yet updated in superres code
1119 #endif
1120 case PARTITION_HORZ_A:
1121 for (i = 0; i < 3; i++)
1122 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1123 supertx_size);
1124 break;
1125 case PARTITION_HORZ_B:
1126 for (i = 0; i < 3; i++)
1127 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1128 supertx_size);
1129 break;
1130 case PARTITION_VERT_A:
1131 for (i = 0; i < 3; i++)
1132 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1133 break;
1134 case PARTITION_VERT_B:
1135 for (i = 0; i < 3; i++)
1136 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1137 break;
1138 #endif // CONFIG_EXT_PARTITION_TYPES
1139 default: assert(0);
1140 }
1141 }
1142 #endif // CONFIG_SUPERTX
1143
1144 #if CONFIG_MOTION_VAR && NC_MODE_INFO
set_mode_info_b(const AV1_COMP * const cpi,const TileInfo * const tile,ThreadData * td,int mi_row,int mi_col,BLOCK_SIZE bsize,PICK_MODE_CONTEXT * ctx)1145 static void set_mode_info_b(const AV1_COMP *const cpi,
1146 const TileInfo *const tile, ThreadData *td,
1147 int mi_row, int mi_col, BLOCK_SIZE bsize,
1148 PICK_MODE_CONTEXT *ctx) {
1149 MACROBLOCK *const x = &td->mb;
1150 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1151 update_state(cpi, td, ctx, mi_row, mi_col, bsize, 1);
1152 }
1153
set_mode_info_sb(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,TOKENEXTRA ** tp,int mi_row,int mi_col,BLOCK_SIZE bsize,PC_TREE * pc_tree)1154 static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
1155 const TileInfo *const tile, TOKENEXTRA **tp,
1156 int mi_row, int mi_col, BLOCK_SIZE bsize,
1157 PC_TREE *pc_tree) {
1158 const AV1_COMMON *const cm = &cpi->common;
1159 const int hbs = mi_size_wide[bsize] / 2;
1160 const PARTITION_TYPE partition = pc_tree->partitioning;
1161 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1162 #if CONFIG_EXT_PARTITION_TYPES
1163 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1164 const int quarter_step = mi_size_wide[bsize] / 4;
1165 #endif
1166 #if CONFIG_CB4X4
1167 const int unify_bsize = 1;
1168 #else
1169 const int unify_bsize = 0;
1170 assert(bsize >= BLOCK_8X8);
1171 #endif
1172
1173 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1174
1175 switch (partition) {
1176 case PARTITION_NONE:
1177 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize, &pc_tree->none);
1178 break;
1179 case PARTITION_VERT:
1180 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1181 &pc_tree->vertical[0]);
1182 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
1183 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1184 &pc_tree->vertical[1]);
1185 }
1186 break;
1187 case PARTITION_HORZ:
1188 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1189 &pc_tree->horizontal[0]);
1190 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
1191 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1192 &pc_tree->horizontal[1]);
1193 }
1194 break;
1195 case PARTITION_SPLIT:
1196 if (bsize == BLOCK_8X8 && !unify_bsize) {
1197 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1198 pc_tree->leaf_split[0]);
1199 } else {
1200 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col, subsize,
1201 pc_tree->split[0]);
1202 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, subsize,
1203 pc_tree->split[1]);
1204 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, subsize,
1205 pc_tree->split[2]);
1206 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, subsize,
1207 pc_tree->split[3]);
1208 }
1209 break;
1210 #if CONFIG_EXT_PARTITION_TYPES
1211 #if CONFIG_EXT_PARTITION_TYPES_AB
1212 #error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
1213 #endif
1214 case PARTITION_HORZ_A:
1215 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1216 &pc_tree->horizontala[0]);
1217 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1218 &pc_tree->horizontala[1]);
1219 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1220 &pc_tree->horizontala[2]);
1221 break;
1222 case PARTITION_HORZ_B:
1223 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1224 &pc_tree->horizontalb[0]);
1225 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1226 &pc_tree->horizontalb[1]);
1227 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1228 &pc_tree->horizontalb[2]);
1229 break;
1230 case PARTITION_VERT_A:
1231 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1232 &pc_tree->verticala[0]);
1233 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1234 &pc_tree->verticala[1]);
1235 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1236 &pc_tree->verticala[2]);
1237 break;
1238 case PARTITION_VERT_B:
1239 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1240 &pc_tree->verticalb[0]);
1241 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1242 &pc_tree->verticalb[1]);
1243 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1244 &pc_tree->verticalb[2]);
1245 break;
1246 case PARTITION_HORZ_4:
1247 for (int i = 0; i < 4; ++i) {
1248 int this_mi_row = mi_row + i * quarter_step;
1249 if (i > 0 && this_mi_row >= cm->mi_rows) break;
1250
1251 set_mode_info_b(cpi, tile, td, this_mi_row, mi_col, subsize,
1252 &pc_tree->horizontal4[i]);
1253 }
1254 break;
1255 case PARTITION_VERT_4:
1256 for (int i = 0; i < 4; ++i) {
1257 int this_mi_col = mi_col + i * quarter_step;
1258 if (i > 0 && this_mi_col >= cm->mi_cols) break;
1259
1260 set_mode_info_b(cpi, tile, td, mi_row, this_mi_col, subsize,
1261 &pc_tree->vertical4[i]);
1262 }
1263 break;
1264 #endif // CONFIG_EXT_PARTITION_TYPES
1265 default: assert(0 && "Invalid partition type."); break;
1266 }
1267 }
1268
1269 #if CONFIG_NCOBMC_ADAPT_WEIGHT
av1_get_ncobmc_mode_rd(const AV1_COMP * const cpi,MACROBLOCK * const x,MACROBLOCKD * const xd,int bsize,const int mi_row,const int mi_col,NCOBMC_MODE * mode)1270 static void av1_get_ncobmc_mode_rd(const AV1_COMP *const cpi,
1271 MACROBLOCK *const x, MACROBLOCKD *const xd,
1272 int bsize, const int mi_row,
1273 const int mi_col, NCOBMC_MODE *mode) {
1274 const AV1_COMMON *const cm = &cpi->common;
1275 const int mi_width = mi_size_wide[bsize];
1276 const int mi_height = mi_size_high[bsize];
1277
1278 assert(bsize >= BLOCK_8X8);
1279
1280 reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
1281 cm->mi_cols);
1282
1283 // set up source buffers before calling the mode searching function
1284 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
1285
1286 *mode = get_ncobmc_mode(cpi, x, xd, mi_row, mi_col, bsize);
1287 }
get_ncobmc_intrpl_pred(const AV1_COMP * const cpi,ThreadData * td,int mi_row,int mi_col,BLOCK_SIZE bsize)1288 static void get_ncobmc_intrpl_pred(const AV1_COMP *const cpi, ThreadData *td,
1289 int mi_row, int mi_col, BLOCK_SIZE bsize) {
1290 MACROBLOCK *const x = &td->mb;
1291 MACROBLOCKD *const xd = &x->e_mbd;
1292 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1293 const int mi_width = mi_size_wide[bsize];
1294 const int mi_height = mi_size_high[bsize];
1295 const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
1296 const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
1297
1298 if (mi_width > mi_height) {
1299 // horizontal partition
1300 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
1301 &mbmi->ncobmc_mode[0]);
1302 xd->mi += hbs;
1303 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col + hbs,
1304 &mbmi->ncobmc_mode[1]);
1305 } else if (mi_height > mi_width) {
1306 // vertical partition
1307 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
1308 &mbmi->ncobmc_mode[0]);
1309 xd->mi += hbs * xd->mi_stride;
1310 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row + hbs, mi_col,
1311 &mbmi->ncobmc_mode[1]);
1312 } else {
1313 av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
1314 &mbmi->ncobmc_mode[0]);
1315 }
1316 // restore the info
1317 av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
1318 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
1319 }
1320 #endif // CONFIG_NCOBMC_ADAPT_WEIGHT
1321 #endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
1322
av1_setup_src_planes(MACROBLOCK * x,const YV12_BUFFER_CONFIG * src,int mi_row,int mi_col)1323 void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1324 int mi_row, int mi_col) {
1325 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1326 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1327 src->uv_crop_width };
1328 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1329 src->uv_crop_height };
1330 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1331 int i;
1332
1333 // Set current frame pointer.
1334 x->e_mbd.cur_buf = src;
1335
1336 for (i = 0; i < MAX_MB_PLANE; i++)
1337 setup_pred_plane(&x->plane[i].src, x->e_mbd.mi[0]->mbmi.sb_type, buffers[i],
1338 widths[i], heights[i], strides[i], mi_row, mi_col, NULL,
1339 x->e_mbd.plane[i].subsampling_x,
1340 x->e_mbd.plane[i].subsampling_y);
1341 }
1342
set_segment_rdmult(const AV1_COMP * const cpi,MACROBLOCK * const x,int8_t segment_id)1343 static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
1344 int8_t segment_id) {
1345 int segment_qindex;
1346 const AV1_COMMON *const cm = &cpi->common;
1347 av1_init_plane_quantizers(cpi, x, segment_id);
1348 aom_clear_system_state();
1349 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1350 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
1351 }
1352
1353 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
dist_8x8_set_sub8x8_dst(MACROBLOCK * const x,uint8_t * dst8x8,BLOCK_SIZE bsize,int bw,int bh,int mi_row,int mi_col)1354 static void dist_8x8_set_sub8x8_dst(MACROBLOCK *const x, uint8_t *dst8x8,
1355 BLOCK_SIZE bsize, int bw, int bh,
1356 int mi_row, int mi_col) {
1357 MACROBLOCKD *const xd = &x->e_mbd;
1358 struct macroblockd_plane *const pd = &xd->plane[0];
1359 const int dst_stride = pd->dst.stride;
1360 uint8_t *dst = pd->dst.buf;
1361
1362 assert(bsize < BLOCK_8X8);
1363
1364 if (bsize < BLOCK_8X8) {
1365 int i, j;
1366 #if CONFIG_HIGHBITDEPTH
1367 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1368 uint16_t *dst8x8_16 = (uint16_t *)dst8x8;
1369 uint16_t *dst_sub8x8 = &dst8x8_16[((mi_row & 1) * 8 + (mi_col & 1)) << 2];
1370
1371 for (j = 0; j < bh; ++j)
1372 for (i = 0; i < bw; ++i)
1373 dst_sub8x8[j * 8 + i] = CONVERT_TO_SHORTPTR(dst)[j * dst_stride + i];
1374 } else {
1375 #endif
1376 uint8_t *dst_sub8x8 = &dst8x8[((mi_row & 1) * 8 + (mi_col & 1)) << 2];
1377
1378 for (j = 0; j < bh; ++j)
1379 for (i = 0; i < bw; ++i)
1380 dst_sub8x8[j * 8 + i] = dst[j * dst_stride + i];
1381 #if CONFIG_HIGHBITDEPTH
1382 }
1383 #endif
1384 }
1385 }
1386 #endif
1387
rd_pick_sb_modes(const AV1_COMP * const cpi,TileDataEnc * tile_data,MACROBLOCK * const x,int mi_row,int mi_col,RD_STATS * rd_cost,int * totalrate_nocoef,PARTITION_TYPE partition,BLOCK_SIZE bsize,PICK_MODE_CONTEXT * ctx,int64_t best_rd)1388 static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
1389 MACROBLOCK *const x, int mi_row, int mi_col,
1390 RD_STATS *rd_cost,
1391 #if CONFIG_SUPERTX
1392 int *totalrate_nocoef,
1393 #endif
1394 #if CONFIG_EXT_PARTITION_TYPES
1395 PARTITION_TYPE partition,
1396 #endif
1397 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1398 int64_t best_rd) {
1399 const AV1_COMMON *const cm = &cpi->common;
1400 TileInfo *const tile_info = &tile_data->tile_info;
1401 MACROBLOCKD *const xd = &x->e_mbd;
1402 MB_MODE_INFO *mbmi;
1403 struct macroblock_plane *const p = x->plane;
1404 struct macroblockd_plane *const pd = xd->plane;
1405 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1406 int i, orig_rdmult;
1407
1408 aom_clear_system_state();
1409
1410 #if CONFIG_PVQ
1411 x->pvq_speed = 1;
1412 x->pvq_coded = 0;
1413 #endif
1414
1415 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1416 mbmi = &xd->mi[0]->mbmi;
1417 mbmi->sb_type = bsize;
1418 #if CONFIG_RD_DEBUG
1419 mbmi->mi_row = mi_row;
1420 mbmi->mi_col = mi_col;
1421 #endif
1422 #if CONFIG_SUPERTX
1423 // We set tx_size here as skip blocks would otherwise not set it.
1424 // tx_size needs to be set at this point as supertx_enable in
1425 // write_modes_sb is computed based on this, and if the garbage in memory
1426 // just happens to be the supertx_size, then the packer will code this
1427 // block as a supertx block, even if rdopt did not pick it as such.
1428 mbmi->tx_size = max_txsize_lookup[bsize];
1429 #endif
1430 #if CONFIG_EXT_PARTITION_TYPES
1431 mbmi->partition = partition;
1432 #endif
1433
1434 for (i = 0; i < MAX_MB_PLANE; ++i) {
1435 p[i].coeff = ctx->coeff[i];
1436 p[i].qcoeff = ctx->qcoeff[i];
1437 pd[i].dqcoeff = ctx->dqcoeff[i];
1438 #if CONFIG_PVQ
1439 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1440 #endif
1441 p[i].eobs = ctx->eobs[i];
1442 #if CONFIG_LV_MAP
1443 p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
1444 #endif
1445 }
1446
1447 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
1448 #if CONFIG_MRC_TX
1449 xd->mrc_mask = ctx->mrc_mask;
1450 #endif // CONFIG_MRC_TX
1451
1452 ctx->skippable = 0;
1453
1454 // Set to zero to make sure we do not use the previous encoded frame stats
1455 mbmi->skip = 0;
1456
1457 #if CONFIG_CB4X4
1458 x->skip_chroma_rd =
1459 !is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
1460 xd->plane[1].subsampling_y);
1461 #endif
1462
1463 #if CONFIG_HIGHBITDEPTH
1464 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1465 x->source_variance = av1_high_get_sby_perpixel_variance(
1466 cpi, &x->plane[0].src, bsize, xd->bd);
1467 } else {
1468 x->source_variance =
1469 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1470 }
1471 #else
1472 x->source_variance =
1473 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1474 #endif // CONFIG_HIGHBITDEPTH
1475
1476 // Save rdmult before it might be changed, so it can be restored later.
1477 orig_rdmult = x->rdmult;
1478
1479 if (aq_mode == VARIANCE_AQ) {
1480 if (cpi->vaq_refresh) {
1481 const int energy =
1482 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1483 mbmi->segment_id = av1_vaq_segment_id(energy);
1484 // Re-initialise quantiser
1485 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
1486 }
1487 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1488 } else if (aq_mode == COMPLEXITY_AQ) {
1489 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1490 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1491 // If segment is boosted, use rdmult for that segment.
1492 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
1493 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
1494 }
1495
1496 // Find best coding mode & reconstruct the MB so it is available
1497 // as a predictor for MBs that follow in the SB
1498 if (frame_is_intra_only(cm)) {
1499 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
1500 #if CONFIG_SUPERTX
1501 *totalrate_nocoef = 0;
1502 #endif // CONFIG_SUPERTX
1503 } else {
1504 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1505 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, mi_row, mi_col,
1506 rd_cost, bsize, ctx, best_rd);
1507 #if CONFIG_SUPERTX
1508 *totalrate_nocoef = rd_cost->rate;
1509 #endif // CONFIG_SUPERTX
1510 } else {
1511 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
1512 #if CONFIG_SUPERTX
1513 totalrate_nocoef,
1514 #endif // CONFIG_SUPERTX
1515 bsize, ctx, best_rd);
1516 #if CONFIG_SUPERTX
1517 assert(*totalrate_nocoef >= 0);
1518 #endif // CONFIG_SUPERTX
1519 }
1520 }
1521
1522 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1523 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1524 (bsize >= BLOCK_16X16) &&
1525 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1526 #if CONFIG_EXT_REFS
1527 cpi->refresh_alt2_ref_frame ||
1528 #endif // CONFIG_EXT_REFS
1529 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
1530 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
1531 }
1532
1533 x->rdmult = orig_rdmult;
1534
1535 // TODO(jingning) The rate-distortion optimization flow needs to be
1536 // refactored to provide proper exit/return handle.
1537 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1538
1539 ctx->rate = rd_cost->rate;
1540 ctx->dist = rd_cost->dist;
1541 }
1542
update_inter_mode_stats(FRAME_COUNTS * counts,PREDICTION_MODE mode,int16_t mode_context)1543 static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1544 int16_t mode_context) {
1545 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1546 if (mode == NEWMV) {
1547 ++counts->newmv_mode[mode_ctx][0];
1548 return;
1549 } else {
1550 ++counts->newmv_mode[mode_ctx][1];
1551
1552 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1553 return;
1554 }
1555
1556 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1557 if (mode == ZEROMV) {
1558 ++counts->zeromv_mode[mode_ctx][0];
1559 return;
1560 } else {
1561 ++counts->zeromv_mode[mode_ctx][1];
1562 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1563
1564 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1565 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1566 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1567
1568 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1569 }
1570 }
1571 }
1572
update_stats(const AV1_COMMON * const cm,ThreadData * td,int mi_row,int mi_col,int supertx_enabled)1573 static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1574 int mi_col
1575 #if CONFIG_SUPERTX
1576 ,
1577 int supertx_enabled
1578 #endif
1579 ) {
1580 MACROBLOCK *x = &td->mb;
1581 MACROBLOCKD *const xd = &x->e_mbd;
1582 const MODE_INFO *const mi = xd->mi[0];
1583 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1584 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1585 const BLOCK_SIZE bsize = mbmi->sb_type;
1586 FRAME_CONTEXT *fc = xd->tile_ctx;
1587
1588 // delta quant applies to both intra and inter
1589 int super_block_upper_left =
1590 ((mi_row & MAX_MIB_MASK) == 0) && ((mi_col & MAX_MIB_MASK) == 0);
1591
1592 if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
1593 super_block_upper_left) {
1594 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1595 const int absdq = abs(dq);
1596 int i;
1597 for (i = 0; i < AOMMIN(absdq, DELTA_Q_SMALL); ++i) {
1598 td->counts->delta_q[i][1]++;
1599 }
1600 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1601 xd->prev_qindex = mbmi->current_q_index;
1602 #if CONFIG_EXT_DELTA_Q
1603 #if CONFIG_LOOPFILTER_LEVEL
1604 if (cm->delta_lf_present_flag) {
1605 if (cm->delta_lf_multi) {
1606 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
1607 const int delta_lf =
1608 (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
1609 cm->delta_lf_res;
1610 const int abs_delta_lf = abs(delta_lf);
1611 for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
1612 td->counts->delta_lf_multi[lf_id][i][1]++;
1613 }
1614 if (abs_delta_lf < DELTA_LF_SMALL)
1615 td->counts->delta_lf_multi[lf_id][abs_delta_lf][0]++;
1616 xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
1617 }
1618 } else {
1619 const int delta_lf =
1620 (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
1621 cm->delta_lf_res;
1622 const int abs_delta_lf = abs(delta_lf);
1623 for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
1624 td->counts->delta_lf[i][1]++;
1625 }
1626 if (abs_delta_lf < DELTA_LF_SMALL)
1627 td->counts->delta_lf[abs_delta_lf][0]++;
1628 xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
1629 }
1630 }
1631 #else
1632 if (cm->delta_lf_present_flag) {
1633 const int dlf =
1634 (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
1635 cm->delta_lf_res;
1636 const int absdlf = abs(dlf);
1637 for (i = 0; i < AOMMIN(absdlf, DELTA_LF_SMALL); ++i) {
1638 td->counts->delta_lf[i][1]++;
1639 }
1640 if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++;
1641 xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
1642 }
1643 #endif // CONFIG_LOOPFILTER_LEVEL
1644 #endif
1645 }
1646 if (!frame_is_intra_only(cm)) {
1647 FRAME_COUNTS *const counts = td->counts;
1648 RD_COUNTS *rdc = &td->rd_counts;
1649 const int inter_block = is_inter_block(mbmi);
1650 const int seg_ref_active =
1651 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1652 if (!seg_ref_active) {
1653 #if CONFIG_SUPERTX
1654 if (!supertx_enabled)
1655 #endif
1656 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
1657 #if CONFIG_NEW_MULTISYMBOL
1658 update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
1659 inter_block, 2);
1660 #endif
1661 // If the segment reference feature is enabled we have only a single
1662 // reference frame allowed for the segment so exclude it from
1663 // the reference frame counts used to work out probabilities.
1664 if (inter_block) {
1665 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1666 #if CONFIG_EXT_REFS
1667 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1668 #endif // CONFIG_EXT_REFS
1669
1670 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
1671 if (has_second_ref(mbmi))
1672 // This flag is also updated for 4x4 blocks
1673 rdc->compound_ref_used_flag = 1;
1674 else
1675 // This flag is also updated for 4x4 blocks
1676 rdc->single_ref_used_flag = 1;
1677 if (is_comp_ref_allowed(mbmi->sb_type)) {
1678 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1679 [has_second_ref(mbmi)]++;
1680 #if CONFIG_NEW_MULTISYMBOL
1681 update_cdf(av1_get_reference_mode_cdf(cm, xd), has_second_ref(mbmi),
1682 2);
1683 #endif // CONFIG_NEW_MULTISYMBOL
1684 }
1685 }
1686
1687 if (has_second_ref(mbmi)) {
1688 #if CONFIG_EXT_COMP_REFS
1689 const COMP_REFERENCE_TYPE comp_ref_type = has_uni_comp_refs(mbmi)
1690 ? UNIDIR_COMP_REFERENCE
1691 : BIDIR_COMP_REFERENCE;
1692 #if !USE_UNI_COMP_REFS
1693 // TODO(zoeliu): Temporarily turn off uni-directional comp refs
1694 assert(comp_ref_type == BIDIR_COMP_REFERENCE);
1695 #endif // !USE_UNI_COMP_REFS
1696 counts->comp_ref_type[av1_get_comp_reference_type_context(xd)]
1697 [comp_ref_type]++;
1698
1699 if (comp_ref_type == UNIDIR_COMP_REFERENCE) {
1700 const int bit = (ref0 == BWDREF_FRAME);
1701 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p(xd)][0]
1702 [bit]++;
1703 if (!bit) {
1704 const int bit1 = (ref1 == LAST3_FRAME || ref1 == GOLDEN_FRAME);
1705 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p1(xd)][1]
1706 [bit1]++;
1707 if (bit1) {
1708 counts->uni_comp_ref[av1_get_pred_context_uni_comp_ref_p2(xd)]
1709 [2][ref1 == GOLDEN_FRAME]++;
1710 }
1711 }
1712 } else {
1713 #endif // CONFIG_EXT_COMP_REFS
1714 #if CONFIG_EXT_REFS
1715 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1716
1717 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
1718 if (!bit) {
1719 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1720 [ref0 == LAST_FRAME]++;
1721 } else {
1722 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1723 [ref0 == GOLDEN_FRAME]++;
1724 }
1725
1726 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1727 [ref1 == ALTREF_FRAME]++;
1728 if (ref1 != ALTREF_FRAME)
1729 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p1(cm, xd)]
1730 [1][ref1 == ALTREF2_FRAME]++;
1731 #else // !CONFIG_EXT_REFS
1732 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1733 [ref0 == GOLDEN_FRAME]++;
1734 #endif // CONFIG_EXT_REFS
1735 #if CONFIG_EXT_COMP_REFS
1736 }
1737 #endif // CONFIG_EXT_COMP_REFS
1738 } else {
1739 #if CONFIG_EXT_REFS
1740 const int bit = (ref0 >= BWDREF_FRAME);
1741
1742 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
1743 if (bit) {
1744 assert(ref0 <= ALTREF_FRAME);
1745 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1746 [ref0 == ALTREF_FRAME]++;
1747 if (ref0 != ALTREF_FRAME)
1748 counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
1749 [ref0 == ALTREF2_FRAME]++;
1750 } else {
1751 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
1752 counts
1753 ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
1754 if (!bit1) {
1755 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1756 [ref0 != LAST_FRAME]++;
1757 } else {
1758 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1759 [ref0 != LAST3_FRAME]++;
1760 }
1761 }
1762 #else // !CONFIG_EXT_REFS
1763 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1764 [ref0 != LAST_FRAME]++;
1765 if (ref0 != LAST_FRAME) {
1766 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1767 [ref0 != GOLDEN_FRAME]++;
1768 }
1769 #endif // CONFIG_EXT_REFS
1770 }
1771
1772 #if CONFIG_COMPOUND_SINGLEREF
1773 if (!has_second_ref(mbmi))
1774 counts->comp_inter_mode[av1_get_inter_mode_context(xd)]
1775 [is_inter_singleref_comp_mode(mbmi->mode)]++;
1776 #endif // CONFIG_COMPOUND_SINGLEREF
1777
1778 #if CONFIG_INTERINTRA
1779 if (cm->reference_mode != COMPOUND_REFERENCE &&
1780 #if CONFIG_SUPERTX
1781 !supertx_enabled &&
1782 #endif
1783 cm->allow_interintra_compound && is_interintra_allowed(mbmi)) {
1784 const int bsize_group = size_group_lookup[bsize];
1785 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1786 counts->interintra[bsize_group][1]++;
1787 #if CONFIG_NEW_MULTISYMBOL
1788 update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
1789 #endif
1790 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1791 update_cdf(fc->interintra_mode_cdf[bsize_group],
1792 mbmi->interintra_mode, INTERINTRA_MODES);
1793 if (is_interintra_wedge_used(bsize)) {
1794 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1795 #if CONFIG_NEW_MULTISYMBOL
1796 update_cdf(fc->wedge_interintra_cdf[bsize],
1797 mbmi->use_wedge_interintra, 2);
1798 #endif
1799 }
1800 } else {
1801 counts->interintra[bsize_group][0]++;
1802 #if CONFIG_NEW_MULTISYMBOL
1803 update_cdf(fc->interintra_cdf[bsize_group], 0, 2);
1804 #endif
1805 }
1806 }
1807 #endif // CONFIG_INTERINTRA
1808
1809 #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1810 #if CONFIG_WARPED_MOTION
1811 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
1812 #endif
1813 const MOTION_MODE motion_allowed = motion_mode_allowed(
1814 #if CONFIG_GLOBAL_MOTION
1815 0, xd->global_motion,
1816 #endif // CONFIG_GLOBAL_MOTION
1817 #if CONFIG_WARPED_MOTION
1818 xd,
1819 #endif
1820 mi);
1821 #if CONFIG_SUPERTX
1822 if (!supertx_enabled)
1823 #endif // CONFIG_SUPERTX
1824 if (mbmi->ref_frame[1] != INTRA_FRAME)
1825 #if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
1826 {
1827 if (motion_allowed == WARPED_CAUSAL) {
1828 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1829 update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
1830 MOTION_MODES);
1831 #if CONFIG_NCOBMC_ADAPT_WEIGHT
1832 } else if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
1833 counts->ncobmc[mbmi->sb_type][mbmi->motion_mode]++;
1834 update_cdf(fc->ncobmc_cdf[mbmi->sb_type], mbmi->motion_mode,
1835 OBMC_FAMILY_MODES);
1836 } else if (motion_allowed == OBMC_CAUSAL) {
1837 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
1838 update_cdf(fc->obmc_cdf[mbmi->sb_type], mbmi->motion_mode, 2);
1839 }
1840 #else
1841 } else if (motion_allowed == OBMC_CAUSAL) {
1842 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
1843 #if CONFIG_NEW_MULTISYMBOL
1844 update_cdf(fc->obmc_cdf[mbmi->sb_type],
1845 mbmi->motion_mode == OBMC_CAUSAL, 2);
1846 #endif
1847 }
1848 #endif // CONFIG_NCOBMC_ADAPT_WEIGHT
1849 }
1850 #else
1851 if (motion_allowed > SIMPLE_TRANSLATION) {
1852 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1853 update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
1854 MOTION_MODES);
1855 }
1856 #endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
1857
1858 #if CONFIG_NCOBMC_ADAPT_WEIGHT
1859 if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT) {
1860 ADAPT_OVERLAP_BLOCK ao_block =
1861 adapt_overlap_block_lookup[mbmi->sb_type];
1862 ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[0]];
1863 update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[0],
1864 MAX_NCOBMC_MODES);
1865 if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
1866 ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[1]];
1867 update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[1],
1868 MAX_NCOBMC_MODES);
1869 }
1870 }
1871 #endif
1872
1873 #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1874
1875 if (
1876 #if CONFIG_COMPOUND_SINGLEREF
1877 is_inter_anyref_comp_mode(mbmi->mode)
1878 #else // !CONFIG_COMPOUND_SINGLEREF
1879 cm->reference_mode != SINGLE_REFERENCE &&
1880 is_inter_compound_mode(mbmi->mode)
1881 #endif // CONFIG_COMPOUND_SINGLEREF
1882 #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1883 && mbmi->motion_mode == SIMPLE_TRANSLATION
1884 #endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1885 ) {
1886 #if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
1887 #if CONFIG_WEDGE && CONFIG_COMPOUND_SEGMENT
1888 if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
1889 #endif
1890 counts
1891 ->compound_interinter[bsize][mbmi->interinter_compound_type]++;
1892 update_cdf(fc->compound_type_cdf[bsize],
1893 mbmi->interinter_compound_type, COMPOUND_TYPES);
1894 #if CONFIG_WEDGE && CONFIG_COMPOUND_SEGMENT
1895 }
1896 #endif
1897 #endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
1898 }
1899 }
1900 }
1901
1902 if (inter_block &&
1903 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1904 int16_t mode_ctx;
1905 const PREDICTION_MODE mode = mbmi->mode;
1906 if (has_second_ref(mbmi)) {
1907 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1908 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
1909 update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
1910 INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
1911 #if CONFIG_COMPOUND_SINGLEREF
1912 } else if (is_inter_singleref_comp_mode(mode)) {
1913 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1914 ++counts->inter_singleref_comp_mode[mode_ctx]
1915 [INTER_SINGLEREF_COMP_OFFSET(mode)];
1916 #endif // CONFIG_COMPOUND_SINGLEREF
1917 } else {
1918 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
1919 mbmi->ref_frame, bsize, -1);
1920 update_inter_mode_stats(counts, mode, mode_ctx);
1921 }
1922
1923 int mode_allowed = (mbmi->mode == NEWMV);
1924 mode_allowed |= (mbmi->mode == NEW_NEWMV);
1925 #if CONFIG_COMPOUND_SINGLEREF
1926 mode_allowed |= (mbmi->mode == SR_NEW_NEWMV);
1927 #endif // CONFIG_COMPOUND_SINGLEREF
1928 if (mode_allowed) {
1929 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
1930 int idx;
1931
1932 for (idx = 0; idx < 2; ++idx) {
1933 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1934 uint8_t drl_ctx =
1935 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
1936 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
1937
1938 if (mbmi->ref_mv_idx == idx) break;
1939 }
1940 }
1941 }
1942
1943 if (have_nearmv_in_inter_mode(mbmi->mode)) {
1944 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
1945 int idx;
1946
1947 for (idx = 1; idx < 3; ++idx) {
1948 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1949 uint8_t drl_ctx =
1950 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
1951 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
1952
1953 if (mbmi->ref_mv_idx == idx - 1) break;
1954 }
1955 }
1956 }
1957 }
1958 #if CONFIG_INTRABC
1959 } else {
1960 if (av1_allow_intrabc(bsize, cm)) {
1961 FRAME_COUNTS *const counts = td->counts;
1962 ++counts->intrabc[mbmi->use_intrabc];
1963 } else {
1964 assert(!mbmi->use_intrabc);
1965 }
1966 #endif
1967 }
1968 }
1969
1970 typedef struct {
1971 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
1972 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
1973 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
1974 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
1975 #if CONFIG_VAR_TX
1976 TXFM_CONTEXT *p_ta;
1977 TXFM_CONTEXT *p_tl;
1978 TXFM_CONTEXT ta[2 * MAX_MIB_SIZE];
1979 TXFM_CONTEXT tl[2 * MAX_MIB_SIZE];
1980 #endif
1981 } RD_SEARCH_MACROBLOCK_CONTEXT;
1982
restore_context(MACROBLOCK * x,const RD_SEARCH_MACROBLOCK_CONTEXT * ctx,int mi_row,int mi_col,od_rollback_buffer * rdo_buf,BLOCK_SIZE bsize)1983 static void restore_context(MACROBLOCK *x,
1984 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
1985 int mi_col,
1986 #if CONFIG_PVQ
1987 od_rollback_buffer *rdo_buf,
1988 #endif
1989 BLOCK_SIZE bsize) {
1990 MACROBLOCKD *xd = &x->e_mbd;
1991 int p;
1992 const int num_4x4_blocks_wide =
1993 block_size_wide[bsize] >> tx_size_wide_log2[0];
1994 const int num_4x4_blocks_high =
1995 block_size_high[bsize] >> tx_size_high_log2[0];
1996 int mi_width = mi_size_wide[bsize];
1997 int mi_height = mi_size_high[bsize];
1998 for (p = 0; p < MAX_MB_PLANE; p++) {
1999 int tx_col;
2000 int tx_row;
2001 tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
2002 tx_row = (mi_row & MAX_MIB_MASK) << (MI_SIZE_LOG2 - tx_size_high_log2[0]);
2003 memcpy(xd->above_context[p] + (tx_col >> xd->plane[p].subsampling_x),
2004 ctx->a + num_4x4_blocks_wide * p,
2005 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2006 xd->plane[p].subsampling_x);
2007 memcpy(xd->left_context[p] + (tx_row >> xd->plane[p].subsampling_y),
2008 ctx->l + num_4x4_blocks_high * p,
2009 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2010 xd->plane[p].subsampling_y);
2011 }
2012 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2013 sizeof(*xd->above_seg_context) * mi_width);
2014 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2015 sizeof(xd->left_seg_context[0]) * mi_height);
2016 #if CONFIG_VAR_TX
2017 xd->above_txfm_context = ctx->p_ta;
2018 xd->left_txfm_context = ctx->p_tl;
2019 memcpy(xd->above_txfm_context, ctx->ta,
2020 sizeof(*xd->above_txfm_context) * (mi_width << TX_UNIT_WIDE_LOG2));
2021 memcpy(xd->left_txfm_context, ctx->tl,
2022 sizeof(*xd->left_txfm_context) * (mi_height << TX_UNIT_HIGH_LOG2));
2023 #endif
2024 #if CONFIG_PVQ
2025 od_encode_rollback(&x->daala_enc, rdo_buf);
2026 #endif
2027 }
2028
save_context(const MACROBLOCK * x,RD_SEARCH_MACROBLOCK_CONTEXT * ctx,int mi_row,int mi_col,od_rollback_buffer * rdo_buf,BLOCK_SIZE bsize)2029 static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
2030 int mi_row, int mi_col,
2031 #if CONFIG_PVQ
2032 od_rollback_buffer *rdo_buf,
2033 #endif
2034 BLOCK_SIZE bsize) {
2035 const MACROBLOCKD *xd = &x->e_mbd;
2036 int p;
2037 const int num_4x4_blocks_wide =
2038 block_size_wide[bsize] >> tx_size_wide_log2[0];
2039 const int num_4x4_blocks_high =
2040 block_size_high[bsize] >> tx_size_high_log2[0];
2041 int mi_width = mi_size_wide[bsize];
2042 int mi_height = mi_size_high[bsize];
2043
2044 // buffer the above/left context information of the block in search.
2045 for (p = 0; p < MAX_MB_PLANE; ++p) {
2046 int tx_col;
2047 int tx_row;
2048 tx_col = mi_col << (MI_SIZE_LOG2 - tx_size_wide_log2[0]);
2049 tx_row = (mi_row & MAX_MIB_MASK) << (MI_SIZE_LOG2 - tx_size_high_log2[0]);
2050 memcpy(ctx->a + num_4x4_blocks_wide * p,
2051 xd->above_context[p] + (tx_col >> xd->plane[p].subsampling_x),
2052 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2053 xd->plane[p].subsampling_x);
2054 memcpy(ctx->l + num_4x4_blocks_high * p,
2055 xd->left_context[p] + (tx_row >> xd->plane[p].subsampling_y),
2056 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2057 xd->plane[p].subsampling_y);
2058 }
2059 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2060 sizeof(*xd->above_seg_context) * mi_width);
2061 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2062 sizeof(xd->left_seg_context[0]) * mi_height);
2063 #if CONFIG_VAR_TX
2064 memcpy(ctx->ta, xd->above_txfm_context,
2065 sizeof(*xd->above_txfm_context) * (mi_width << TX_UNIT_WIDE_LOG2));
2066 memcpy(ctx->tl, xd->left_txfm_context,
2067 sizeof(*xd->left_txfm_context) * (mi_height << TX_UNIT_HIGH_LOG2));
2068 ctx->p_ta = xd->above_txfm_context;
2069 ctx->p_tl = xd->left_txfm_context;
2070 #endif
2071 #if CONFIG_PVQ
2072 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2073 #endif
2074 }
2075
encode_b(const AV1_COMP * const cpi,const TileInfo * const tile,ThreadData * td,TOKENEXTRA ** tp,int mi_row,int mi_col,RUN_TYPE dry_run,BLOCK_SIZE bsize,PARTITION_TYPE partition,PICK_MODE_CONTEXT * ctx,int * rate)2076 static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2077 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2078 RUN_TYPE dry_run, BLOCK_SIZE bsize,
2079 #if CONFIG_EXT_PARTITION_TYPES
2080 PARTITION_TYPE partition,
2081 #endif
2082 PICK_MODE_CONTEXT *ctx, int *rate) {
2083 MACROBLOCK *const x = &td->mb;
2084 #if (CONFIG_MOTION_VAR && CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q | \
2085 CONFIG_NCOBMC_ADAPT_WEIGHT
2086 MACROBLOCKD *xd = &x->e_mbd;
2087 MB_MODE_INFO *mbmi;
2088 #if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2089 int check_ncobmc;
2090 #endif
2091 #endif
2092
2093 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2094 #if CONFIG_EXT_PARTITION_TYPES
2095 x->e_mbd.mi[0]->mbmi.partition = partition;
2096 #endif
2097 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2098 #if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
2099 mbmi = &xd->mi[0]->mbmi;
2100 #if CONFIG_WARPED_MOTION
2101 set_ref_ptrs(&cpi->common, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
2102 #endif
2103 #endif
2104
2105 #if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
2106 const MOTION_MODE motion_allowed = motion_mode_allowed(
2107 #if CONFIG_GLOBAL_MOTION
2108 0, xd->global_motion,
2109 #endif // CONFIG_GLOBAL_MOTION
2110 #if CONFIG_WARPED_MOTION
2111 xd,
2112 #endif
2113 xd->mi[0]);
2114 #endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
2115
2116 #if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2117 check_ncobmc = is_inter_block(mbmi) && motion_allowed >= OBMC_CAUSAL;
2118 if (!dry_run && check_ncobmc) {
2119 av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
2120 av1_setup_dst_planes(x->e_mbd.plane, bsize,
2121 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
2122 }
2123 #endif
2124
2125 #if CONFIG_LV_MAP
2126 av1_set_coeff_buffer(cpi, x, mi_row, mi_col);
2127 #endif
2128
2129 #if CONFIG_NCOBMC_ADAPT_WEIGHT
2130 if (dry_run == OUTPUT_ENABLED && !frame_is_intra_only(&cpi->common)) {
2131 if (motion_allowed >= NCOBMC_ADAPT_WEIGHT && is_inter_block(mbmi)) {
2132 get_ncobmc_intrpl_pred(cpi, td, mi_row, mi_col, bsize);
2133 av1_check_ncobmc_adapt_weight_rd(cpi, x, mi_row, mi_col);
2134 }
2135 av1_setup_dst_planes(x->e_mbd.plane, bsize,
2136 get_frame_new_buffer(&cpi->common), mi_row, mi_col);
2137 }
2138 #endif // CONFIG_NCOBMC_ADAPT_WEIGHT
2139
2140 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, rate);
2141
2142 #if CONFIG_LV_MAP
2143 if (dry_run == 0)
2144 x->cb_offset += block_size_wide[bsize] * block_size_high[bsize];
2145 #endif
2146
2147 if (!dry_run) {
2148 #if CONFIG_EXT_DELTA_Q
2149 mbmi = &xd->mi[0]->mbmi;
2150 if (bsize == cpi->common.sb_size && mbmi->skip == 1 &&
2151 cpi->common.delta_lf_present_flag) {
2152 #if CONFIG_LOOPFILTER_LEVEL
2153 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
2154 mbmi->curr_delta_lf[lf_id] = xd->prev_delta_lf[lf_id];
2155 #endif // CONFIG_LOOPFILTER_LEVEL
2156 mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
2157 }
2158 #endif
2159 #if CONFIG_SUPERTX
2160 update_stats(&cpi->common, td, mi_row, mi_col, 0);
2161 #else
2162 update_stats(&cpi->common, td, mi_row, mi_col);
2163 #endif
2164 }
2165 }
2166
encode_sb(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,TOKENEXTRA ** tp,int mi_row,int mi_col,RUN_TYPE dry_run,BLOCK_SIZE bsize,PC_TREE * pc_tree,int * rate)2167 static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2168 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2169 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2170 PC_TREE *pc_tree, int *rate) {
2171 const AV1_COMMON *const cm = &cpi->common;
2172 MACROBLOCK *const x = &td->mb;
2173 MACROBLOCKD *const xd = &x->e_mbd;
2174 const int hbs = mi_size_wide[bsize] / 2;
2175 #if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
2176 const int qbs = mi_size_wide[bsize] / 4;
2177 #endif
2178 const int is_partition_root = bsize >= BLOCK_8X8;
2179 const int ctx = is_partition_root
2180 ? partition_plane_context(xd, mi_row, mi_col,
2181 #if CONFIG_UNPOISON_PARTITION_CTX
2182 mi_row + hbs < cm->mi_rows,
2183 mi_col + hbs < cm->mi_cols,
2184 #endif
2185 bsize)
2186 : -1;
2187 const PARTITION_TYPE partition = pc_tree->partitioning;
2188 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2189 #if CONFIG_EXT_PARTITION_TYPES
2190 int quarter_step = mi_size_wide[bsize] / 4;
2191 int i;
2192 #if !CONFIG_EXT_PARTITION_TYPES_AB
2193 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2194 #endif
2195 #endif
2196
2197 #if CONFIG_CB4X4
2198 const int unify_bsize = 1;
2199 #else
2200 const int unify_bsize = 0;
2201 assert(bsize >= BLOCK_8X8);
2202 #endif
2203
2204 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2205
2206 if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
2207
2208 #if CONFIG_SUPERTX
2209 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2210 partition != PARTITION_NONE && !xd->lossless[0]) {
2211 int supertx_enabled;
2212 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2213 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2214 if (supertx_enabled) {
2215 const int mi_width = mi_size_wide[bsize];
2216 const int mi_height = mi_size_high[bsize];
2217 int x_idx, y_idx, i;
2218 uint8_t *dst_buf[3];
2219 int dst_stride[3];
2220 set_skip_context(xd, mi_row, mi_col);
2221 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
2222 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2223 pc_tree);
2224
2225 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
2226 mi_col);
2227 for (i = 0; i < MAX_MB_PLANE; i++) {
2228 dst_buf[i] = xd->plane[i].dst.buf;
2229 dst_stride[i] = xd->plane[i].dst.stride;
2230 }
2231 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2232 bsize, bsize, dst_buf, dst_stride, pc_tree);
2233
2234 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2235 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2236
2237 if (!x->skip) {
2238 int this_rate = 0;
2239 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
2240 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, mi_row, mi_col, bsize,
2241 rate);
2242 if (rate) *rate += this_rate;
2243 } else {
2244 xd->mi[0]->mbmi.skip = 1;
2245 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
2246 av1_reset_skip_context(xd, mi_row, mi_col, bsize);
2247 }
2248 if (!dry_run) {
2249 for (y_idx = 0; y_idx < mi_height; y_idx++)
2250 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2251 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2252 x_idx &&
2253 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2254 y_idx) {
2255 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2256 xd->mi[0]->mbmi.skip;
2257 }
2258 }
2259 td->counts->supertx[partition_supertx_context_lookup[partition]]
2260 [supertx_size][1]++;
2261 td->counts->supertx_size[supertx_size]++;
2262 #if CONFIG_ENTROPY_STATS
2263 #if CONFIG_EXT_TX
2264 if (get_ext_tx_types(supertx_size, bsize, 1, cm->reduced_tx_set_used) >
2265 1 &&
2266 !xd->mi[0]->mbmi.skip) {
2267 const int eset =
2268 get_ext_tx_set(supertx_size, bsize, 1, cm->reduced_tx_set_used);
2269 if (eset > 0) {
2270 ++td->counts
2271 ->inter_ext_tx[eset][supertx_size][xd->mi[0]->mbmi.tx_type];
2272 }
2273 }
2274 #else
2275 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2276 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2277 }
2278 #endif // CONFIG_EXT_TX
2279 #endif // CONFIG_ENTROPY_STATS
2280 }
2281 #if CONFIG_EXT_PARTITION_TYPES
2282 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2283 partition);
2284 #else
2285 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2286 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2287 #endif
2288 #if CONFIG_VAR_TX
2289 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2290 xd);
2291 #endif // CONFIG_VAR_TX
2292 return;
2293 } else {
2294 if (!dry_run) {
2295 td->counts->supertx[partition_supertx_context_lookup[partition]]
2296 [supertx_size][0]++;
2297 }
2298 }
2299 }
2300 #endif // CONFIG_SUPERTX
2301
2302 switch (partition) {
2303 case PARTITION_NONE:
2304 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
2305 #if CONFIG_EXT_PARTITION_TYPES
2306 partition,
2307 #endif
2308 &pc_tree->none, rate);
2309 break;
2310 case PARTITION_VERT:
2311 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
2312 #if CONFIG_EXT_PARTITION_TYPES
2313 partition,
2314 #endif
2315 &pc_tree->vertical[0], rate);
2316 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
2317 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2318 #if CONFIG_EXT_PARTITION_TYPES
2319 partition,
2320 #endif
2321 &pc_tree->vertical[1], rate);
2322 }
2323 break;
2324 case PARTITION_HORZ:
2325 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
2326 #if CONFIG_EXT_PARTITION_TYPES
2327 partition,
2328 #endif
2329 &pc_tree->horizontal[0], rate);
2330 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
2331 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2332 #if CONFIG_EXT_PARTITION_TYPES
2333 partition,
2334 #endif
2335 &pc_tree->horizontal[1], rate);
2336 }
2337 break;
2338 case PARTITION_SPLIT:
2339 if (bsize == BLOCK_8X8 && !unify_bsize) {
2340 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
2341 #if CONFIG_EXT_PARTITION_TYPES
2342 partition,
2343 #endif
2344 pc_tree->leaf_split[0], rate);
2345 } else {
2346 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2347 pc_tree->split[0], rate);
2348 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2349 pc_tree->split[1], rate);
2350 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2351 pc_tree->split[2], rate);
2352 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2353 subsize, pc_tree->split[3], rate);
2354 }
2355 break;
2356
2357 #if CONFIG_EXT_PARTITION_TYPES
2358 #if CONFIG_EXT_PARTITION_TYPES_AB
2359 case PARTITION_HORZ_A:
2360 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
2361 get_subsize(bsize, PARTITION_HORZ_4), partition,
2362 &pc_tree->horizontala[0], rate);
2363 encode_b(cpi, tile, td, tp, mi_row + qbs, mi_col, dry_run,
2364 get_subsize(bsize, PARTITION_HORZ_4), partition,
2365 &pc_tree->horizontala[1], rate);
2366 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2367 partition, &pc_tree->horizontala[2], rate);
2368 break;
2369 case PARTITION_HORZ_B:
2370 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2371 &pc_tree->horizontalb[0], rate);
2372 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run,
2373 get_subsize(bsize, PARTITION_HORZ_4), partition,
2374 &pc_tree->horizontalb[1], rate);
2375 if (mi_row + 3 * qbs < cm->mi_rows)
2376 encode_b(cpi, tile, td, tp, mi_row + 3 * qbs, mi_col, dry_run,
2377 get_subsize(bsize, PARTITION_HORZ_4), partition,
2378 &pc_tree->horizontalb[2], rate);
2379 break;
2380 case PARTITION_VERT_A:
2381 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
2382 get_subsize(bsize, PARTITION_VERT_4), partition,
2383 &pc_tree->verticala[0], rate);
2384 encode_b(cpi, tile, td, tp, mi_row, mi_col + qbs, dry_run,
2385 get_subsize(bsize, PARTITION_VERT_4), partition,
2386 &pc_tree->verticala[1], rate);
2387 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2388 partition, &pc_tree->verticala[2], rate);
2389
2390 break;
2391 case PARTITION_VERT_B:
2392 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2393 &pc_tree->verticalb[0], rate);
2394 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run,
2395 get_subsize(bsize, PARTITION_VERT_4), partition,
2396 &pc_tree->verticalb[1], rate);
2397 if (mi_col + 3 * qbs < cm->mi_cols)
2398 encode_b(cpi, tile, td, tp, mi_row, mi_col + 3 * qbs, dry_run,
2399 get_subsize(bsize, PARTITION_VERT_4), partition,
2400 &pc_tree->verticalb[2], rate);
2401 break;
2402 #else
2403 case PARTITION_HORZ_A:
2404 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2405 &pc_tree->horizontala[0], rate);
2406 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2407 partition, &pc_tree->horizontala[1], rate);
2408 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2409 partition, &pc_tree->horizontala[2], rate);
2410 break;
2411 case PARTITION_HORZ_B:
2412 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2413 &pc_tree->horizontalb[0], rate);
2414 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2415 partition, &pc_tree->horizontalb[1], rate);
2416 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2417 partition, &pc_tree->horizontalb[2], rate);
2418 break;
2419 case PARTITION_VERT_A:
2420 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2421 &pc_tree->verticala[0], rate);
2422 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2423 partition, &pc_tree->verticala[1], rate);
2424 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2425 partition, &pc_tree->verticala[2], rate);
2426
2427 break;
2428 case PARTITION_VERT_B:
2429 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2430 &pc_tree->verticalb[0], rate);
2431 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2432 partition, &pc_tree->verticalb[1], rate);
2433 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2434 partition, &pc_tree->verticalb[2], rate);
2435 break;
2436 #endif
2437 case PARTITION_HORZ_4:
2438 for (i = 0; i < 4; ++i) {
2439 int this_mi_row = mi_row + i * quarter_step;
2440 if (i > 0 && this_mi_row >= cm->mi_rows) break;
2441
2442 encode_b(cpi, tile, td, tp, this_mi_row, mi_col, dry_run, subsize,
2443 partition, &pc_tree->horizontal4[i], rate);
2444 }
2445 break;
2446 case PARTITION_VERT_4:
2447 for (i = 0; i < 4; ++i) {
2448 int this_mi_col = mi_col + i * quarter_step;
2449 if (i > 0 && this_mi_col >= cm->mi_cols) break;
2450
2451 encode_b(cpi, tile, td, tp, mi_row, this_mi_col, dry_run, subsize,
2452 partition, &pc_tree->vertical4[i], rate);
2453 }
2454 break;
2455 #endif // CONFIG_EXT_PARTITION_TYPES
2456 default: assert(0 && "Invalid partition type."); break;
2457 }
2458
2459 #if CONFIG_EXT_PARTITION_TYPES
2460 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2461 #else
2462 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2463 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2464 #endif // CONFIG_EXT_PARTITION_TYPES
2465 }
2466
2467 // Check to see if the given partition size is allowed for a specified number
2468 // of mi block rows and columns remaining in the image.
2469 // If not then return the largest allowed partition size
find_partition_size(BLOCK_SIZE bsize,int rows_left,int cols_left,int * bh,int * bw)2470 static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2471 int cols_left, int *bh, int *bw) {
2472 if (rows_left <= 0 || cols_left <= 0) {
2473 return AOMMIN(bsize, BLOCK_8X8);
2474 } else {
2475 for (; bsize > 0; bsize -= 3) {
2476 *bh = mi_size_high[bsize];
2477 *bw = mi_size_wide[bsize];
2478 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2479 break;
2480 }
2481 }
2482 }
2483 return bsize;
2484 }
2485
set_partial_sb_partition(const AV1_COMMON * const cm,MODE_INFO * mi,int bh_in,int bw_in,int mi_rows_remaining,int mi_cols_remaining,BLOCK_SIZE bsize,MODE_INFO ** mib)2486 static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
2487 int bh_in, int bw_in,
2488 int mi_rows_remaining,
2489 int mi_cols_remaining, BLOCK_SIZE bsize,
2490 MODE_INFO **mib) {
2491 int bh = bh_in;
2492 int r, c;
2493 for (r = 0; r < cm->mib_size; r += bh) {
2494 int bw = bw_in;
2495 for (c = 0; c < cm->mib_size; c += bw) {
2496 const int index = r * cm->mi_stride + c;
2497 mib[index] = mi + index;
2498 mib[index]->mbmi.sb_type = find_partition_size(
2499 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2500 }
2501 }
2502 }
2503
2504 // This function attempts to set all mode info entries in a given superblock
2505 // to the same block partition size.
2506 // However, at the bottom and right borders of the image the requested size
2507 // may not be allowed in which case this code attempts to choose the largest
2508 // allowable partition.
set_fixed_partitioning(AV1_COMP * cpi,const TileInfo * const tile,MODE_INFO ** mib,int mi_row,int mi_col,BLOCK_SIZE bsize)2509 static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
2510 MODE_INFO **mib, int mi_row, int mi_col,
2511 BLOCK_SIZE bsize) {
2512 AV1_COMMON *const cm = &cpi->common;
2513 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2514 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2515 int block_row, block_col;
2516 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2517 int bh = mi_size_high[bsize];
2518 int bw = mi_size_wide[bsize];
2519
2520 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2521
2522 // Apply the requested partition size to the SB if it is all "in image"
2523 if ((mi_cols_remaining >= cm->mib_size) &&
2524 (mi_rows_remaining >= cm->mib_size)) {
2525 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2526 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2527 int index = block_row * cm->mi_stride + block_col;
2528 mib[index] = mi_upper_left + index;
2529 mib[index]->mbmi.sb_type = bsize;
2530 }
2531 }
2532 } else {
2533 // Else this is a partial SB.
2534 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2535 mi_cols_remaining, bsize, mib);
2536 }
2537 }
2538
rd_use_partition(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,MODE_INFO ** mib,TOKENEXTRA ** tp,int mi_row,int mi_col,BLOCK_SIZE bsize,int * rate,int64_t * dist,int * rate_nocoef,int do_recon,PC_TREE * pc_tree)2539 static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
2540 TileDataEnc *tile_data, MODE_INFO **mib,
2541 TOKENEXTRA **tp, int mi_row, int mi_col,
2542 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2543 #if CONFIG_SUPERTX
2544 int *rate_nocoef,
2545 #endif
2546 int do_recon, PC_TREE *pc_tree) {
2547 AV1_COMMON *const cm = &cpi->common;
2548 TileInfo *const tile_info = &tile_data->tile_info;
2549 MACROBLOCK *const x = &td->mb;
2550 MACROBLOCKD *const xd = &x->e_mbd;
2551 const int bs = mi_size_wide[bsize];
2552 const int hbs = bs / 2;
2553 int i;
2554 const int pl = (bsize >= BLOCK_8X8)
2555 ? partition_plane_context(xd, mi_row, mi_col,
2556 #if CONFIG_UNPOISON_PARTITION_CTX
2557 mi_row + hbs < cm->mi_rows,
2558 mi_col + hbs < cm->mi_cols,
2559 #endif
2560 bsize)
2561 : 0;
2562 const PARTITION_TYPE partition =
2563 (bsize >= BLOCK_8X8) ? get_partition(cm, mi_row, mi_col, bsize)
2564 : PARTITION_NONE;
2565 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2566 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2567 RD_STATS last_part_rdc, none_rdc, chosen_rdc;
2568 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2569 int splits_below = 0;
2570 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2571 int do_partition_search = 1;
2572 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
2573 const int unify_bsize = CONFIG_CB4X4;
2574 #if CONFIG_SUPERTX
2575 int last_part_rate_nocoef = INT_MAX;
2576 int none_rate_nocoef = INT_MAX;
2577 int chosen_rate_nocoef = INT_MAX;
2578 #endif
2579 #if CONFIG_PVQ
2580 od_rollback_buffer pre_rdo_buf;
2581 #endif
2582 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2583
2584 assert(num_4x4_blocks_wide_lookup[bsize] ==
2585 num_4x4_blocks_high_lookup[bsize]);
2586
2587 av1_invalid_rd_stats(&last_part_rdc);
2588 av1_invalid_rd_stats(&none_rdc);
2589 av1_invalid_rd_stats(&chosen_rdc);
2590
2591 pc_tree->partitioning = partition;
2592
2593 #if CONFIG_VAR_TX
2594 xd->above_txfm_context =
2595 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
2596 xd->left_txfm_context = xd->left_txfm_context_buffer +
2597 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
2598 #endif
2599 #if !CONFIG_PVQ
2600 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2601 #else
2602 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2603 #endif
2604
2605 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2606 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
2607 x->mb_energy = av1_block_energy(cpi, x, bsize);
2608 }
2609
2610 if (do_partition_search &&
2611 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2612 cpi->sf.adjust_partitioning_from_last_frame) {
2613 // Check if any of the sub blocks are further split.
2614 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2615 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2616 splits_below = 1;
2617 for (i = 0; i < 4; i++) {
2618 int jj = i >> 1, ii = i & 0x01;
2619 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2620 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2621 splits_below = 0;
2622 }
2623 }
2624 }
2625
2626 // If partition is not none try none unless each of the 4 splits are split
2627 // even further..
2628 if (partition != PARTITION_NONE && !splits_below &&
2629 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2630 pc_tree->partitioning = PARTITION_NONE;
2631 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2632 #if CONFIG_SUPERTX
2633 &none_rate_nocoef,
2634 #endif
2635 #if CONFIG_EXT_PARTITION_TYPES
2636 PARTITION_NONE,
2637 #endif
2638 bsize, ctx_none, INT64_MAX);
2639
2640 if (none_rdc.rate < INT_MAX) {
2641 none_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
2642 none_rdc.rdcost = RDCOST(x->rdmult, none_rdc.rate, none_rdc.dist);
2643 #if CONFIG_SUPERTX
2644 none_rate_nocoef += x->partition_cost[pl][PARTITION_NONE];
2645 #endif
2646 }
2647
2648 #if !CONFIG_PVQ
2649 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2650 #else
2651 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2652 #endif
2653 mib[0]->mbmi.sb_type = bs_type;
2654 pc_tree->partitioning = partition;
2655 }
2656 }
2657
2658 switch (partition) {
2659 case PARTITION_NONE:
2660 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2661 #if CONFIG_SUPERTX
2662 &last_part_rate_nocoef,
2663 #endif
2664 #if CONFIG_EXT_PARTITION_TYPES
2665 PARTITION_NONE,
2666 #endif
2667 bsize, ctx_none, INT64_MAX);
2668 break;
2669 case PARTITION_HORZ:
2670 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2671 #if CONFIG_SUPERTX
2672 &last_part_rate_nocoef,
2673 #endif
2674 #if CONFIG_EXT_PARTITION_TYPES
2675 PARTITION_HORZ,
2676 #endif
2677 subsize, &pc_tree->horizontal[0], INT64_MAX);
2678 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2679 mi_row + hbs < cm->mi_rows) {
2680 RD_STATS tmp_rdc;
2681 #if CONFIG_SUPERTX
2682 int rt_nocoef = 0;
2683 #endif
2684 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
2685 av1_init_rd_stats(&tmp_rdc);
2686 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
2687 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
2688 NULL);
2689 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2690 #if CONFIG_SUPERTX
2691 &rt_nocoef,
2692 #endif
2693 #if CONFIG_EXT_PARTITION_TYPES
2694 PARTITION_HORZ,
2695 #endif
2696 subsize, &pc_tree->horizontal[1], INT64_MAX);
2697 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
2698 av1_invalid_rd_stats(&last_part_rdc);
2699 #if CONFIG_SUPERTX
2700 last_part_rate_nocoef = INT_MAX;
2701 #endif
2702 break;
2703 }
2704 last_part_rdc.rate += tmp_rdc.rate;
2705 last_part_rdc.dist += tmp_rdc.dist;
2706 last_part_rdc.rdcost += tmp_rdc.rdcost;
2707 #if CONFIG_SUPERTX
2708 last_part_rate_nocoef += rt_nocoef;
2709 #endif
2710 }
2711 break;
2712 case PARTITION_VERT:
2713 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2714 #if CONFIG_SUPERTX
2715 &last_part_rate_nocoef,
2716 #endif
2717 #if CONFIG_EXT_PARTITION_TYPES
2718 PARTITION_VERT,
2719 #endif
2720 subsize, &pc_tree->vertical[0], INT64_MAX);
2721 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2722 mi_col + hbs < cm->mi_cols) {
2723 RD_STATS tmp_rdc;
2724 #if CONFIG_SUPERTX
2725 int rt_nocoef = 0;
2726 #endif
2727 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
2728 av1_init_rd_stats(&tmp_rdc);
2729 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
2730 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
2731 NULL);
2732 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2733 #if CONFIG_SUPERTX
2734 &rt_nocoef,
2735 #endif
2736 #if CONFIG_EXT_PARTITION_TYPES
2737 PARTITION_VERT,
2738 #endif
2739 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2740 INT64_MAX);
2741 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
2742 av1_invalid_rd_stats(&last_part_rdc);
2743 #if CONFIG_SUPERTX
2744 last_part_rate_nocoef = INT_MAX;
2745 #endif
2746 break;
2747 }
2748 last_part_rdc.rate += tmp_rdc.rate;
2749 last_part_rdc.dist += tmp_rdc.dist;
2750 last_part_rdc.rdcost += tmp_rdc.rdcost;
2751 #if CONFIG_SUPERTX
2752 last_part_rate_nocoef += rt_nocoef;
2753 #endif
2754 }
2755 break;
2756 case PARTITION_SPLIT:
2757 if (bsize == BLOCK_8X8 && !unify_bsize) {
2758 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2759 #if CONFIG_SUPERTX
2760 &last_part_rate_nocoef,
2761 #endif
2762 #if CONFIG_EXT_PARTITION_TYPES
2763 PARTITION_SPLIT,
2764 #endif
2765 subsize, pc_tree->leaf_split[0], INT64_MAX);
2766 break;
2767 }
2768 last_part_rdc.rate = 0;
2769 last_part_rdc.dist = 0;
2770 last_part_rdc.rdcost = 0;
2771 #if CONFIG_SUPERTX
2772 last_part_rate_nocoef = 0;
2773 #endif
2774 for (i = 0; i < 4; i++) {
2775 int x_idx = (i & 1) * hbs;
2776 int y_idx = (i >> 1) * hbs;
2777 int jj = i >> 1, ii = i & 0x01;
2778 RD_STATS tmp_rdc;
2779 #if CONFIG_SUPERTX
2780 int rt_nocoef;
2781 #endif
2782 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2783 continue;
2784
2785 av1_init_rd_stats(&tmp_rdc);
2786 rd_use_partition(cpi, td, tile_data,
2787 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2788 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2789 &tmp_rdc.dist,
2790 #if CONFIG_SUPERTX
2791 &rt_nocoef,
2792 #endif
2793 i != 3, pc_tree->split[i]);
2794 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
2795 av1_invalid_rd_stats(&last_part_rdc);
2796 #if CONFIG_SUPERTX
2797 last_part_rate_nocoef = INT_MAX;
2798 #endif
2799 break;
2800 }
2801 last_part_rdc.rate += tmp_rdc.rate;
2802 last_part_rdc.dist += tmp_rdc.dist;
2803 #if CONFIG_SUPERTX
2804 last_part_rate_nocoef += rt_nocoef;
2805 #endif
2806 }
2807 break;
2808 #if CONFIG_EXT_PARTITION_TYPES
2809 case PARTITION_VERT_A:
2810 case PARTITION_VERT_B:
2811 case PARTITION_HORZ_A:
2812 case PARTITION_HORZ_B:
2813 case PARTITION_HORZ_4:
2814 case PARTITION_VERT_4: assert(0 && "Cannot handle extended partiton types");
2815 #endif // CONFIG_EXT_PARTITION_TYPES
2816 default: assert(0); break;
2817 }
2818
2819 if (last_part_rdc.rate < INT_MAX) {
2820 last_part_rdc.rate += x->partition_cost[pl][partition];
2821 last_part_rdc.rdcost =
2822 RDCOST(x->rdmult, last_part_rdc.rate, last_part_rdc.dist);
2823 #if CONFIG_SUPERTX
2824 last_part_rate_nocoef += x->partition_cost[pl][partition];
2825 #endif
2826 }
2827
2828 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2829 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2830 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2831 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2832 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2833 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2834 chosen_rdc.rate = 0;
2835 chosen_rdc.dist = 0;
2836 #if CONFIG_SUPERTX
2837 chosen_rate_nocoef = 0;
2838 #endif
2839 #if !CONFIG_PVQ
2840 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2841 #else
2842 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2843 #endif
2844 pc_tree->partitioning = PARTITION_SPLIT;
2845
2846 // Split partition.
2847 for (i = 0; i < 4; i++) {
2848 int x_idx = (i & 1) * hbs;
2849 int y_idx = (i >> 1) * hbs;
2850 RD_STATS tmp_rdc;
2851 #if CONFIG_SUPERTX
2852 int rt_nocoef = 0;
2853 #endif
2854 #if CONFIG_PVQ
2855 od_rollback_buffer buf;
2856 #endif
2857 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2858 continue;
2859
2860 #if !CONFIG_PVQ
2861 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2862 #else
2863 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2864 #endif
2865 pc_tree->split[i]->partitioning = PARTITION_NONE;
2866 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2867 &tmp_rdc,
2868 #if CONFIG_SUPERTX
2869 &rt_nocoef,
2870 #endif
2871 #if CONFIG_EXT_PARTITION_TYPES
2872 PARTITION_SPLIT,
2873 #endif
2874 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2875
2876 #if !CONFIG_PVQ
2877 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2878 #else
2879 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2880 #endif
2881 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
2882 av1_invalid_rd_stats(&chosen_rdc);
2883 #if CONFIG_SUPERTX
2884 chosen_rate_nocoef = INT_MAX;
2885 #endif
2886 break;
2887 }
2888
2889 chosen_rdc.rate += tmp_rdc.rate;
2890 chosen_rdc.dist += tmp_rdc.dist;
2891 #if CONFIG_SUPERTX
2892 chosen_rate_nocoef += rt_nocoef;
2893 #endif
2894
2895 if (i != 3)
2896 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2897 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
2898
2899 chosen_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
2900 #if CONFIG_SUPERTX
2901 chosen_rate_nocoef += x->partition_cost[pl][PARTITION_SPLIT];
2902 #endif
2903 }
2904 if (chosen_rdc.rate < INT_MAX) {
2905 chosen_rdc.rate += x->partition_cost[pl][PARTITION_SPLIT];
2906 chosen_rdc.rdcost = RDCOST(x->rdmult, chosen_rdc.rate, chosen_rdc.dist);
2907 #if CONFIG_SUPERTX
2908 chosen_rate_nocoef += x->partition_cost[pl][PARTITION_NONE];
2909 #endif
2910 }
2911 }
2912
2913 // If last_part is better set the partitioning to that.
2914 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2915 mib[0]->mbmi.sb_type = bsize;
2916 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2917 chosen_rdc = last_part_rdc;
2918 #if CONFIG_SUPERTX
2919 chosen_rate_nocoef = last_part_rate_nocoef;
2920 #endif
2921 }
2922 // If none was better set the partitioning to that.
2923 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2924 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2925 chosen_rdc = none_rdc;
2926 #if CONFIG_SUPERTX
2927 chosen_rate_nocoef = none_rate_nocoef;
2928 #endif
2929 }
2930
2931 #if !CONFIG_PVQ
2932 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2933 #else
2934 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2935 #endif
2936
2937 // We must have chosen a partitioning and encoding or we'll fail later on.
2938 // No other opportunities for success.
2939 if (bsize == cm->sb_size)
2940 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2941
2942 if (do_recon) {
2943 if (bsize == cm->sb_size) {
2944 // NOTE: To get estimate for rate due to the tokens, use:
2945 // int rate_coeffs = 0;
2946 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2947 // bsize, pc_tree, &rate_coeffs);
2948 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2949 pc_tree, NULL);
2950 } else {
2951 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2952 pc_tree, NULL);
2953 }
2954 }
2955
2956 *rate = chosen_rdc.rate;
2957 *dist = chosen_rdc.dist;
2958 #if CONFIG_SUPERTX
2959 *rate_nocoef = chosen_rate_nocoef;
2960 #endif
2961 }
2962
2963 /* clang-format off */
2964 static const BLOCK_SIZE min_partition_size[BLOCK_SIZES_ALL] = {
2965 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
2966 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
2967 #endif
2968 BLOCK_4X4, // 4x4
2969 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2970 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2971 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2972 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2973 #if CONFIG_EXT_PARTITION
2974 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 64x128, 128x64, 128x128
2975 #endif // CONFIG_EXT_PARTITION
2976 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
2977 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
2978 #if CONFIG_EXT_PARTITION
2979 BLOCK_16X16, BLOCK_16X16 // 32x128, 128x32
2980 #endif // CONFIG_EXT_PARTITION
2981 };
2982
2983 static const BLOCK_SIZE max_partition_size[BLOCK_SIZES_ALL] = {
2984 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
2985 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 2x2, 2x4, 4x2
2986 #endif
2987 BLOCK_8X8, // 4x4
2988 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2989 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2990 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2991 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2992 #if CONFIG_EXT_PARTITION
2993 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 64x128, 128x64, 128x128
2994 #endif // CONFIG_EXT_PARTITION
2995 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 4x16, 16x4, 8x32
2996 BLOCK_32X32, BLOCK_LARGEST, BLOCK_LARGEST, // 32x8, 16x64, 64x16
2997 #if CONFIG_EXT_PARTITION
2998 BLOCK_LARGEST, BLOCK_LARGEST // 32x128, 128x32
2999 #endif // CONFIG_EXT_PARTITION
3000 };
3001
3002 // Next square block size less or equal than current block size.
3003 static const BLOCK_SIZE next_square_size[BLOCK_SIZES_ALL] = {
3004 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
3005 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3006 #endif
3007 BLOCK_4X4, // 4x4
3008 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
3009 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
3010 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
3011 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
3012 #if CONFIG_EXT_PARTITION
3013 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128, // 64x128, 128x64, 128x128
3014 #endif // CONFIG_EXT_PARTITION
3015 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
3016 BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
3017 #if CONFIG_EXT_PARTITION
3018 BLOCK_32X32, BLOCK_32X32 // 32x128, 128x32
3019 #endif // CONFIG_EXT_PARTITION
3020 };
3021 /* clang-format on */
3022
3023 // Look at all the mode_info entries for blocks that are part of this
3024 // partition and find the min and max values for sb_type.
3025 // At the moment this is designed to work on a superblock but could be
3026 // adjusted to use a size parameter.
3027 //
3028 // The min and max are assumed to have been initialized prior to calling this
3029 // function so repeat calls can accumulate a min and max of more than one
3030 // superblock.
get_sb_partition_size_range(const AV1_COMMON * const cm,MACROBLOCKD * xd,MODE_INFO ** mib,BLOCK_SIZE * min_block_size,BLOCK_SIZE * max_block_size)3031 static void get_sb_partition_size_range(const AV1_COMMON *const cm,
3032 MACROBLOCKD *xd, MODE_INFO **mib,
3033 BLOCK_SIZE *min_block_size,
3034 BLOCK_SIZE *max_block_size) {
3035 int i, j;
3036 int index = 0;
3037
3038 // Check the sb_type for each block that belongs to this region.
3039 for (i = 0; i < cm->mib_size; ++i) {
3040 for (j = 0; j < cm->mib_size; ++j) {
3041 MODE_INFO *mi = mib[index + j];
3042 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
3043 *min_block_size = AOMMIN(*min_block_size, sb_type);
3044 *max_block_size = AOMMAX(*max_block_size, sb_type);
3045 }
3046 index += xd->mi_stride;
3047 }
3048 }
3049
3050 // Look at neighboring blocks and set a min and max partition size based on
3051 // what they chose.
rd_auto_partition_range(AV1_COMP * cpi,const TileInfo * const tile,MACROBLOCKD * const xd,int mi_row,int mi_col,BLOCK_SIZE * min_block_size,BLOCK_SIZE * max_block_size)3052 static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
3053 MACROBLOCKD *const xd, int mi_row,
3054 int mi_col, BLOCK_SIZE *min_block_size,
3055 BLOCK_SIZE *max_block_size) {
3056 AV1_COMMON *const cm = &cpi->common;
3057 MODE_INFO **mi = xd->mi;
3058 const int left_in_image = xd->left_available && mi[-1];
3059 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3060 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3061 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3062 int bh, bw;
3063 BLOCK_SIZE min_size = BLOCK_4X4;
3064 BLOCK_SIZE max_size = BLOCK_LARGEST;
3065
3066 // Trap case where we do not have a prediction.
3067 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3068 // Default "min to max" and "max to min"
3069 min_size = BLOCK_LARGEST;
3070 max_size = BLOCK_4X4;
3071
3072 // NOTE: each call to get_sb_partition_size_range() uses the previous
3073 // passed in values for min and max as a starting point.
3074 // Find the min and max partition used in previous frame at this location
3075 if (cm->frame_type != KEY_FRAME) {
3076 MODE_INFO **prev_mi =
3077 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3078 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3079 }
3080 // Find the min and max partition sizes used in the left superblock
3081 if (left_in_image) {
3082 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3083 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3084 }
3085 // Find the min and max partition sizes used in the above suprblock.
3086 if (above_in_image) {
3087 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3088 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3089 }
3090
3091 // Adjust observed min and max for "relaxed" auto partition case.
3092 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3093 min_size = min_partition_size[min_size];
3094 max_size = max_partition_size[max_size];
3095 }
3096 }
3097
3098 // Check border cases where max and min from neighbors may not be legal.
3099 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3100 &bh, &bw);
3101 min_size = AOMMIN(min_size, max_size);
3102
3103 // Test for blocks at the edge of the active image.
3104 // This may be the actual edge of the image or where there are formatting
3105 // bars.
3106 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
3107 min_size = BLOCK_4X4;
3108 } else {
3109 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
3110 }
3111
3112 // When use_square_partition_only is true, make sure at least one square
3113 // partition is allowed by selecting the next smaller square size as
3114 // *min_block_size.
3115 if (cpi->sf.use_square_partition_only) {
3116 min_size = AOMMIN(min_size, next_square_size[max_size]);
3117 }
3118
3119 *min_block_size = AOMMIN(min_size, cm->sb_size);
3120 *max_block_size = AOMMIN(max_size, cm->sb_size);
3121 }
3122
3123 // TODO(jingning) refactor functions setting partition search range
set_partition_range(const AV1_COMMON * const cm,const MACROBLOCKD * const xd,int mi_row,int mi_col,BLOCK_SIZE bsize,BLOCK_SIZE * const min_bs,BLOCK_SIZE * const max_bs)3124 static void set_partition_range(const AV1_COMMON *const cm,
3125 const MACROBLOCKD *const xd, int mi_row,
3126 int mi_col, BLOCK_SIZE bsize,
3127 BLOCK_SIZE *const min_bs,
3128 BLOCK_SIZE *const max_bs) {
3129 const int mi_width = mi_size_wide[bsize];
3130 const int mi_height = mi_size_high[bsize];
3131 int idx, idy;
3132
3133 const int idx_str = cm->mi_stride * mi_row + mi_col;
3134 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3135 BLOCK_SIZE min_size = cm->sb_size; // default values
3136 BLOCK_SIZE max_size = BLOCK_4X4;
3137
3138 if (prev_mi) {
3139 for (idy = 0; idy < mi_height; ++idy) {
3140 for (idx = 0; idx < mi_width; ++idx) {
3141 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3142 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
3143 min_size = AOMMIN(min_size, bs);
3144 max_size = AOMMAX(max_size, bs);
3145 }
3146 }
3147 }
3148
3149 if (xd->left_available) {
3150 for (idy = 0; idy < mi_height; ++idy) {
3151 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3152 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
3153 min_size = AOMMIN(min_size, bs);
3154 max_size = AOMMAX(max_size, bs);
3155 }
3156 }
3157
3158 if (xd->up_available) {
3159 for (idx = 0; idx < mi_width; ++idx) {
3160 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3161 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
3162 min_size = AOMMIN(min_size, bs);
3163 max_size = AOMMAX(max_size, bs);
3164 }
3165 }
3166
3167 if (min_size == max_size) {
3168 min_size = min_partition_size[min_size];
3169 max_size = max_partition_size[max_size];
3170 }
3171
3172 *min_bs = AOMMIN(min_size, cm->sb_size);
3173 *max_bs = AOMMIN(max_size, cm->sb_size);
3174 }
3175
store_pred_mv(MACROBLOCK * x,PICK_MODE_CONTEXT * ctx)3176 static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3177 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3178 }
3179
load_pred_mv(MACROBLOCK * x,PICK_MODE_CONTEXT * ctx)3180 static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3181 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3182 }
3183
3184 #if CONFIG_FP_MB_STATS
3185 const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3186 0, 10, 10, 30, 40, 40, 60, 80, 80, 90, 100, 100, 120,
3187 #if CONFIG_EXT_PARTITION
3188 // TODO(debargha): What are the correct numbers here?
3189 130, 130, 150
3190 #endif // CONFIG_EXT_PARTITION
3191 };
3192 const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3193 0, 3, 3, 7, 15, 15, 30, 40, 40, 60, 80, 80, 120,
3194 #if CONFIG_EXT_PARTITION
3195 // TODO(debargha): What are the correct numbers here?
3196 160, 160, 240
3197 #endif // CONFIG_EXT_PARTITION
3198 };
3199 const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3200 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 6,
3201 #if CONFIG_EXT_PARTITION
3202 // TODO(debargha): What are the correct numbers here?
3203 8, 8, 10
3204 #endif // CONFIG_EXT_PARTITION
3205 };
3206
3207 typedef enum {
3208 MV_ZERO = 0,
3209 MV_LEFT = 1,
3210 MV_UP = 2,
3211 MV_RIGHT = 3,
3212 MV_DOWN = 4,
3213 MV_INVALID
3214 } MOTION_DIRECTION;
3215
get_motion_direction_fp(uint8_t fp_byte)3216 static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3217 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3218 return MV_ZERO;
3219 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3220 return MV_LEFT;
3221 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3222 return MV_RIGHT;
3223 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3224 return MV_UP;
3225 } else {
3226 return MV_DOWN;
3227 }
3228 }
3229
get_motion_inconsistency(MOTION_DIRECTION this_mv,MOTION_DIRECTION that_mv)3230 static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3231 MOTION_DIRECTION that_mv) {
3232 if (this_mv == that_mv) {
3233 return 0;
3234 } else {
3235 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3236 }
3237 }
3238 #endif
3239
3240 #if CONFIG_EXT_PARTITION_TYPES
3241 // Try searching for an encoding for the given subblock. Returns zero if the
3242 // rdcost is already too high (to tell the caller not to bother searching for
3243 // encodings of further subblocks)
rd_try_subblock(const AV1_COMP * const cpi,ThreadData * td,TileDataEnc * tile_data,TOKENEXTRA ** tp,int is_first,int is_last,int mi_row,int mi_col,BLOCK_SIZE subsize,RD_STATS * best_rdc,RD_STATS * sum_rdc,RD_STATS * this_rdc,int64_t best_rd,int * sum_rate_nocoef,int * this_rate_nocoef,int * abort_flag,PARTITION_TYPE partition,PICK_MODE_CONTEXT * prev_ctx,PICK_MODE_CONTEXT * this_ctx)3244 static int rd_try_subblock(const AV1_COMP *const cpi, ThreadData *td,
3245 TileDataEnc *tile_data, TOKENEXTRA **tp,
3246 int is_first, int is_last, int mi_row, int mi_col,
3247 BLOCK_SIZE subsize, RD_STATS *best_rdc,
3248 RD_STATS *sum_rdc, RD_STATS *this_rdc,
3249 #if CONFIG_SUPERTX
3250 int64_t best_rd, int *sum_rate_nocoef,
3251 int *this_rate_nocoef, int *abort_flag,
3252 #endif
3253 PARTITION_TYPE partition,
3254 PICK_MODE_CONTEXT *prev_ctx,
3255 PICK_MODE_CONTEXT *this_ctx) {
3256 #if CONFIG_SUPERTX
3257 #define RTS_X_RATE_NOCOEF_ARG ((is_first) ? sum_rate_nocoef : this_rate_nocoef),
3258 #define RTS_MAX_RDCOST INT64_MAX
3259 #else
3260 #define RTS_X_RATE_NOCOEF_ARG
3261 #define RTS_MAX_RDCOST best_rdc->rdcost
3262 #endif
3263
3264 MACROBLOCK *const x = &td->mb;
3265
3266 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, prev_ctx);
3267
3268 // On the first time around, write the rd stats straight to sum_rdc. Also, we
3269 // should treat sum_rdc as containing zeros (even if it doesn't) to avoid
3270 // having to zero it at the start.
3271 if (is_first) this_rdc = sum_rdc;
3272 const int64_t spent_rdcost = is_first ? 0 : sum_rdc->rdcost;
3273 const int64_t rdcost_remaining = best_rdc->rdcost - spent_rdcost;
3274
3275 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, this_rdc,
3276 RTS_X_RATE_NOCOEF_ARG partition, subsize, this_ctx,
3277 rdcost_remaining);
3278
3279 #if CONFIG_SUPERTX
3280 if (is_first) *abort_flag = sum_rdc->rdcost >= best_rd;
3281 #endif
3282
3283 if (!is_first) {
3284 if (this_rdc->rate == INT_MAX) {
3285 sum_rdc->rdcost = INT64_MAX;
3286 #if CONFIG_SUPERTX
3287 *sum_rate_nocoef = INT_MAX;
3288 #endif
3289 } else {
3290 sum_rdc->rate += this_rdc->rate;
3291 sum_rdc->dist += this_rdc->dist;
3292 sum_rdc->rdcost += this_rdc->rdcost;
3293 #if CONFIG_SUPERTX
3294 *sum_rate_nocoef += *this_rate_nocoef;
3295 #endif
3296 }
3297 }
3298
3299 if (sum_rdc->rdcost >= RTS_MAX_RDCOST) return 0;
3300
3301 if (!is_last) {
3302 update_state(cpi, td, this_ctx, mi_row, mi_col, subsize, 1);
3303 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
3304 NULL);
3305 }
3306
3307 return 1;
3308
3309 #undef RTS_X_RATE_NOCOEF_ARG
3310 #undef RTS_MAX_RDCOST
3311 }
3312
rd_test_partition3(const AV1_COMP * const cpi,ThreadData * td,TileDataEnc * tile_data,TOKENEXTRA ** tp,PC_TREE * pc_tree,RD_STATS * best_rdc,PICK_MODE_CONTEXT ctxs[3],PICK_MODE_CONTEXT * ctx,int mi_row,int mi_col,BLOCK_SIZE bsize,PARTITION_TYPE partition,int64_t best_rd,int * best_rate_nocoef,RD_SEARCH_MACROBLOCK_CONTEXT * x_ctx,int mi_row0,int mi_col0,BLOCK_SIZE subsize0,int mi_row1,int mi_col1,BLOCK_SIZE subsize1,int mi_row2,int mi_col2,BLOCK_SIZE subsize2)3313 static void rd_test_partition3(
3314 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3315 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_STATS *best_rdc,
3316 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3317 BLOCK_SIZE bsize, PARTITION_TYPE partition,
3318 #if CONFIG_SUPERTX
3319 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3320 #endif
3321 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3322 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3323 MACROBLOCK *const x = &td->mb;
3324 MACROBLOCKD *const xd = &x->e_mbd;
3325 RD_STATS sum_rdc, this_rdc;
3326 #if CONFIG_UNPOISON_PARTITION_CTX
3327 const AV1_COMMON *const cm = &cpi->common;
3328 const int hbs = mi_size_wide[bsize] / 2;
3329 const int has_rows = mi_row + hbs < cm->mi_rows;
3330 const int has_cols = mi_col + hbs < cm->mi_cols;
3331 #endif // CONFIG_UNPOISON_PARTITION_CTX
3332 #if CONFIG_SUPERTX || CONFIG_EXT_PARTITION_TYPES_AB
3333 const AV1_COMMON *const cm = &cpi->common;
3334 #endif
3335 #if CONFIG_SUPERTX
3336 TileInfo *const tile_info = &tile_data->tile_info;
3337 int sum_rate_nocoef, this_rate_nocoef;
3338 int abort_flag;
3339 const int supertx_allowed = !frame_is_intra_only(cm) &&
3340 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3341 !xd->lossless[0];
3342
3343 #define RTP_STX_TRY_ARGS \
3344 best_rd, &sum_rate_nocoef, &this_rate_nocoef, &abort_flag,
3345 #else
3346 #define RTP_STX_TRY_ARGS
3347 #endif
3348
3349 if (!rd_try_subblock(cpi, td, tile_data, tp, 1, 0, mi_row0, mi_col0, subsize0,
3350 best_rdc, &sum_rdc, &this_rdc,
3351 RTP_STX_TRY_ARGS partition, ctx, &ctxs[0]))
3352 return;
3353
3354 if (!rd_try_subblock(cpi, td, tile_data, tp, 0, 0, mi_row1, mi_col1, subsize1,
3355 best_rdc, &sum_rdc, &this_rdc,
3356 RTP_STX_TRY_ARGS partition, &ctxs[0], &ctxs[1]))
3357 return;
3358
3359 // With the new layout of mixed partitions for PARTITION_HORZ_B and
3360 // PARTITION_VERT_B, the last subblock might start past halfway through the
3361 // main block, so we might signal it even though the subblock lies strictly
3362 // outside the image. In that case, we won't spend any bits coding it and the
3363 // difference (obviously) doesn't contribute to the error.
3364 #if CONFIG_EXT_PARTITION_TYPES_AB
3365 const int try_block2 = mi_row2 < cm->mi_rows && mi_col2 < cm->mi_cols;
3366 #else
3367 const int try_block2 = 1;
3368 #endif
3369 if (try_block2 &&
3370 !rd_try_subblock(cpi, td, tile_data, tp, 0, 1, mi_row2, mi_col2, subsize2,
3371 best_rdc, &sum_rdc, &this_rdc,
3372 RTP_STX_TRY_ARGS partition, &ctxs[1], &ctxs[2]))
3373 return;
3374
3375 #if CONFIG_SUPERTX
3376 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3377 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3378 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3379 pc_tree->partitioning = partition;
3380 sum_rdc.rate += av1_cost_bit(
3381 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3382 [supertx_size],
3383 0);
3384 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3385
3386 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3387 TX_TYPE best_tx = DCT_DCT;
3388 RD_STATS tmp_rdc = { sum_rate_nocoef, 0, 0 };
3389
3390 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3391
3392 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
3393 &tmp_rdc.dist, &best_tx, pc_tree);
3394
3395 tmp_rdc.rate += av1_cost_bit(
3396 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3397 [supertx_size],
3398 1);
3399 tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
3400 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3401 sum_rdc = tmp_rdc;
3402 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3403 supertx_size, pc_tree);
3404 }
3405 }
3406
3407 pc_tree->partitioning = best_partition;
3408 }
3409 #endif
3410
3411 if (sum_rdc.rdcost >= best_rdc->rdcost) return;
3412
3413 int pl = partition_plane_context(xd, mi_row, mi_col,
3414 #if CONFIG_UNPOISON_PARTITION_CTX
3415 has_rows, has_cols,
3416 #endif
3417 bsize);
3418 sum_rdc.rate += x->partition_cost[pl][partition];
3419 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3420 #if CONFIG_SUPERTX
3421 sum_rate_nocoef += x->partition_cost[pl][partition];
3422 #endif
3423
3424 if (sum_rdc.rdcost >= best_rdc->rdcost) return;
3425
3426 #if CONFIG_SUPERTX
3427 *best_rate_nocoef = sum_rate_nocoef;
3428 assert(*best_rate_nocoef >= 0);
3429 #endif
3430 *best_rdc = sum_rdc;
3431 pc_tree->partitioning = partition;
3432
3433 #undef RTP_STX_TRY_ARGS
3434 }
3435 #endif // CONFIG_EXT_PARTITION_TYPES
3436
3437 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
dist_8x8_yuv(const AV1_COMP * const cpi,MACROBLOCK * const x,uint8_t * y_src_8x8)3438 static int64_t dist_8x8_yuv(const AV1_COMP *const cpi, MACROBLOCK *const x,
3439 uint8_t *y_src_8x8) {
3440 MACROBLOCKD *const xd = &x->e_mbd;
3441 int64_t dist_8x8, dist_8x8_uv, total_dist;
3442 const int src_stride = x->plane[0].src.stride;
3443 uint8_t *decoded_8x8;
3444 int plane;
3445
3446 #if CONFIG_HIGHBITDEPTH
3447 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3448 decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
3449 else
3450 #endif
3451 decoded_8x8 = (uint8_t *)x->decoded_8x8;
3452
3453 dist_8x8 = av1_dist_8x8(cpi, x, y_src_8x8, src_stride, decoded_8x8, 8,
3454 BLOCK_8X8, 8, 8, 8, 8, x->qindex)
3455 << 4;
3456
3457 // Compute chroma distortion for a luma 8x8 block
3458 dist_8x8_uv = 0;
3459
3460 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
3461 const int src_stride_uv = x->plane[plane].src.stride;
3462 const int dst_stride_uv = xd->plane[plane].dst.stride;
3463 // uv buff pointers now (i.e. the last sub8x8 block) is the same
3464 // to those at the first sub8x8 block because
3465 // uv buff pointer is set only once at first sub8x8 block in a 8x8.
3466 uint8_t *src_uv = x->plane[plane].src.buf;
3467 uint8_t *dst_uv = xd->plane[plane].dst.buf;
3468 unsigned sse;
3469 #if CONFIG_CHROMA_SUB8X8
3470 const BLOCK_SIZE plane_bsize =
3471 AOMMAX(BLOCK_4X4, get_plane_block_size(BLOCK_8X8, &xd->plane[plane]));
3472 #else
3473 const BLOCK_SIZE plane_bsize =
3474 get_plane_block_size(BLOCK_8X8, &xd->plane[plane]);
3475 #endif
3476 cpi->fn_ptr[plane_bsize].vf(src_uv, src_stride_uv, dst_uv, dst_stride_uv,
3477 &sse);
3478 dist_8x8_uv += (int64_t)sse << 4;
3479 }
3480
3481 return total_dist = dist_8x8 + dist_8x8_uv;
3482 }
3483 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
3484
3485 // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3486 // unlikely to be selected depending on previous rate-distortion optimization
3487 // results, for encoding speed-up.
rd_pick_partition(const AV1_COMP * const cpi,ThreadData * td,TileDataEnc * tile_data,TOKENEXTRA ** tp,int mi_row,int mi_col,BLOCK_SIZE bsize,RD_STATS * rd_cost,int * rate_nocoef,int64_t best_rd,PC_TREE * pc_tree)3488 static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
3489 TileDataEnc *tile_data, TOKENEXTRA **tp,
3490 int mi_row, int mi_col, BLOCK_SIZE bsize,
3491 RD_STATS *rd_cost,
3492 #if CONFIG_SUPERTX
3493 int *rate_nocoef,
3494 #endif
3495 int64_t best_rd, PC_TREE *pc_tree) {
3496 const AV1_COMMON *const cm = &cpi->common;
3497 TileInfo *const tile_info = &tile_data->tile_info;
3498 MACROBLOCK *const x = &td->mb;
3499 MACROBLOCKD *const xd = &x->e_mbd;
3500 const int mi_step = mi_size_wide[bsize] / 2;
3501 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
3502 const TOKENEXTRA *const tp_orig = *tp;
3503 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
3504 #if CONFIG_UNPOISON_PARTITION_CTX
3505 const int hbs = mi_size_wide[bsize] / 2;
3506 const int has_rows = mi_row + hbs < cm->mi_rows;
3507 const int has_cols = mi_col + hbs < cm->mi_cols;
3508 #else
3509 int tmp_partition_cost[PARTITION_TYPES];
3510 #endif
3511 BLOCK_SIZE subsize;
3512 RD_STATS this_rdc, sum_rdc, best_rdc;
3513 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3514 int do_square_split = bsize_at_least_8x8;
3515 #if CONFIG_CB4X4
3516 const int unify_bsize = 1;
3517 const int pl = bsize_at_least_8x8
3518 ? partition_plane_context(xd, mi_row, mi_col,
3519 #if CONFIG_UNPOISON_PARTITION_CTX
3520 has_rows, has_cols,
3521 #endif
3522 bsize)
3523 : 0;
3524 #else
3525 const int unify_bsize = 0;
3526 const int pl = partition_plane_context(xd, mi_row, mi_col,
3527 #if CONFIG_UNPOISON_PARTITION_CTX
3528 has_rows, has_cols,
3529 #endif
3530 bsize);
3531 #endif // CONFIG_CB4X4
3532 const int *partition_cost =
3533 pl >= 0 ? x->partition_cost[pl] : x->partition_cost[0];
3534 #if CONFIG_SUPERTX
3535 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3536 int abort_flag;
3537 const int supertx_allowed = !frame_is_intra_only(cm) && bsize >= BLOCK_8X8 &&
3538 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3539 !xd->lossless[0];
3540 #endif // CONFIG_SUPERTX
3541
3542 int do_rectangular_split = 1;
3543 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
3544 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3545 #endif
3546
3547 // Override skipping rectangular partition operations for edge blocks
3548 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3549 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3550 const int xss = x->e_mbd.plane[1].subsampling_x;
3551 const int yss = x->e_mbd.plane[1].subsampling_y;
3552
3553 BLOCK_SIZE min_size = x->min_partition_size;
3554 BLOCK_SIZE max_size = x->max_partition_size;
3555
3556 #if CONFIG_FP_MB_STATS
3557 unsigned int src_diff_var = UINT_MAX;
3558 int none_complexity = 0;
3559 #endif
3560
3561 int partition_none_allowed = !force_horz_split && !force_vert_split;
3562 int partition_horz_allowed =
3563 !force_vert_split && yss <= xss && bsize_at_least_8x8;
3564 int partition_vert_allowed =
3565 !force_horz_split && xss <= yss && bsize_at_least_8x8;
3566
3567 #if CONFIG_PVQ
3568 od_rollback_buffer pre_rdo_buf;
3569 #endif
3570
3571 (void)*tp_orig;
3572
3573 #if !CONFIG_UNPOISON_PARTITION_CTX
3574 if (force_horz_split || force_vert_split) {
3575 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3576
3577 if (!force_vert_split) { // force_horz_split only
3578 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3579 tmp_partition_cost[PARTITION_HORZ] =
3580 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
3581 tmp_partition_cost[PARTITION_SPLIT] =
3582 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
3583 } else if (!force_horz_split) { // force_vert_split only
3584 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3585 tmp_partition_cost[PARTITION_VERT] =
3586 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
3587 tmp_partition_cost[PARTITION_SPLIT] =
3588 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
3589 } else { // force_ horz_split && force_vert_split horz_split
3590 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3591 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3592 tmp_partition_cost[PARTITION_SPLIT] = 0;
3593 }
3594
3595 partition_cost = tmp_partition_cost;
3596 }
3597 #endif
3598
3599 #if CONFIG_VAR_TX
3600 #ifndef NDEBUG
3601 // Nothing should rely on the default value of this array (which is just
3602 // leftover from encoding the previous block. Setting it to magic number
3603 // when debugging.
3604 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3605 #endif // NDEBUG
3606 #endif // CONFIG_VAR_TX
3607
3608 assert(mi_size_wide[bsize] == mi_size_high[bsize]);
3609
3610 av1_init_rd_stats(&this_rdc);
3611 av1_init_rd_stats(&sum_rdc);
3612 av1_invalid_rd_stats(&best_rdc);
3613 best_rdc.rdcost = best_rd;
3614
3615 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3616
3617 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
3618 x->mb_energy = av1_block_energy(cpi, x, bsize);
3619
3620 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
3621 const int cb_partition_search_ctrl =
3622 ((pc_tree->index == 0 || pc_tree->index == 3) +
3623 get_chessboard_index(cm->current_video_frame)) &
3624 0x1;
3625
3626 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3627 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3628 }
3629
3630 // Determine partition types in search according to the speed features.
3631 // The threshold set here has to be of square block size.
3632 if (cpi->sf.auto_min_max_partition_size) {
3633 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3634 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3635 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3636 partition_none_allowed &= no_partition_allowed;
3637 partition_horz_allowed &= partition_allowed || force_horz_split;
3638 partition_vert_allowed &= partition_allowed || force_vert_split;
3639 do_square_split &= bsize > min_size;
3640 }
3641 if (cpi->sf.use_square_partition_only) {
3642 partition_horz_allowed &= force_horz_split;
3643 partition_vert_allowed &= force_vert_split;
3644 }
3645
3646 #if CONFIG_VAR_TX
3647 xd->above_txfm_context =
3648 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
3649 xd->left_txfm_context = xd->left_txfm_context_buffer +
3650 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
3651 #endif
3652 #if !CONFIG_PVQ
3653 save_context(x, &x_ctx, mi_row, mi_col, bsize);
3654 #else
3655 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3656 #endif
3657
3658 #if CONFIG_FP_MB_STATS
3659 if (cpi->use_fp_mb_stats) {
3660 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3661 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3662 mi_col, bsize);
3663 }
3664
3665 // Decide whether we shall split directly and skip searching NONE by using
3666 // the first pass block statistics
3667 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
3668 partition_none_allowed && src_diff_var > 4 &&
3669 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3670 int mb_row = mi_row >> 1;
3671 int mb_col = mi_col >> 1;
3672 int mb_row_end =
3673 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
3674 int mb_col_end =
3675 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
3676 int r, c;
3677
3678 // compute a complexity measure, basically measure inconsistency of motion
3679 // vectors obtained from the first pass in the current block
3680 for (r = mb_row; r < mb_row_end; r++) {
3681 for (c = mb_col; c < mb_col_end; c++) {
3682 const int mb_index = r * cm->mb_cols + c;
3683
3684 MOTION_DIRECTION this_mv;
3685 MOTION_DIRECTION right_mv;
3686 MOTION_DIRECTION bottom_mv;
3687
3688 this_mv =
3689 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3690
3691 // to its right
3692 if (c != mb_col_end - 1) {
3693 right_mv = get_motion_direction_fp(
3694 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3695 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3696 }
3697
3698 // to its bottom
3699 if (r != mb_row_end - 1) {
3700 bottom_mv = get_motion_direction_fp(
3701 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3702 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3703 }
3704
3705 // do not count its left and top neighbors to avoid double counting
3706 }
3707 }
3708
3709 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3710 partition_none_allowed = 0;
3711 }
3712 }
3713 #endif
3714
3715 // PARTITION_NONE
3716 if (partition_none_allowed) {
3717 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3718 #if CONFIG_SUPERTX
3719 &this_rate_nocoef,
3720 #endif
3721 #if CONFIG_EXT_PARTITION_TYPES
3722 PARTITION_NONE,
3723 #endif
3724 bsize, ctx_none, best_rdc.rdcost);
3725 if (this_rdc.rate != INT_MAX) {
3726 if (bsize_at_least_8x8) {
3727 const int pt_cost = partition_cost[PARTITION_NONE] < INT_MAX
3728 ? partition_cost[PARTITION_NONE]
3729 : 0;
3730 this_rdc.rate += pt_cost;
3731 this_rdc.rdcost = RDCOST(x->rdmult, this_rdc.rate, this_rdc.dist);
3732 #if CONFIG_SUPERTX
3733 this_rate_nocoef += pt_cost;
3734 #endif
3735 }
3736
3737 if (this_rdc.rdcost < best_rdc.rdcost) {
3738 // Adjust dist breakout threshold according to the partition size.
3739 const int64_t dist_breakout_thr =
3740 cpi->sf.partition_search_breakout_dist_thr >>
3741 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3742 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3743 const int rate_breakout_thr =
3744 cpi->sf.partition_search_breakout_rate_thr *
3745 num_pels_log2_lookup[bsize];
3746
3747 best_rdc = this_rdc;
3748 #if CONFIG_SUPERTX
3749 best_rate_nocoef = this_rate_nocoef;
3750 assert(best_rate_nocoef >= 0);
3751 #endif
3752 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
3753
3754 // If all y, u, v transform blocks in this partition are skippable, and
3755 // the dist & rate are within the thresholds, the partition search is
3756 // terminated for current branch of the partition search tree.
3757 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3758 // early termination at that speed.
3759 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
3760 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
3761 best_rdc.rate < rate_breakout_thr)) {
3762 do_square_split = 0;
3763 do_rectangular_split = 0;
3764 }
3765
3766 #if CONFIG_FP_MB_STATS
3767 // Check if every 16x16 first pass block statistics has zero
3768 // motion and the corresponding first pass residue is small enough.
3769 // If that is the case, check the difference variance between the
3770 // current frame and the last frame. If the variance is small enough,
3771 // stop further splitting in RD optimization
3772 if (cpi->use_fp_mb_stats && do_square_split &&
3773 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3774 int mb_row = mi_row >> 1;
3775 int mb_col = mi_col >> 1;
3776 int mb_row_end =
3777 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
3778 int mb_col_end =
3779 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
3780 int r, c;
3781
3782 int skip = 1;
3783 for (r = mb_row; r < mb_row_end; r++) {
3784 for (c = mb_col; c < mb_col_end; c++) {
3785 const int mb_index = r * cm->mb_cols + c;
3786 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3787 FPMB_MOTION_ZERO_MASK) ||
3788 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3789 FPMB_ERROR_SMALL_MASK)) {
3790 skip = 0;
3791 break;
3792 }
3793 }
3794 if (skip == 0) {
3795 break;
3796 }
3797 }
3798 if (skip) {
3799 if (src_diff_var == UINT_MAX) {
3800 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3801 src_diff_var = get_sby_perpixel_diff_variance(
3802 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3803 }
3804 if (src_diff_var < 8) {
3805 do_square_split = 0;
3806 do_rectangular_split = 0;
3807 }
3808 }
3809 }
3810 #endif
3811 }
3812 }
3813 #if !CONFIG_PVQ
3814 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3815 #else
3816 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3817 #endif
3818 #if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
3819 if (!x->skip_chroma_rd) {
3820 cfl_clear_sub8x8_val(xd->cfl);
3821 }
3822 #endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
3823 }
3824
3825 // store estimated motion vector
3826 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
3827
3828 #if CONFIG_SUPERTX
3829 int64_t temp_best_rdcost = INT64_MAX;
3830 #else
3831 int64_t temp_best_rdcost = best_rdc.rdcost;
3832 #endif
3833
3834 // PARTITION_SPLIT
3835 // TODO(jingning): use the motion vectors given by the above search as
3836 // the starting point of motion search in the following partition type check.
3837 if (do_square_split) {
3838 int reached_last_index = 0;
3839 subsize = get_subsize(bsize, PARTITION_SPLIT);
3840 if (bsize == BLOCK_8X8 && !unify_bsize) {
3841 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3842 pc_tree->leaf_split[0]->pred_interp_filter =
3843 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
3844
3845 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3846 #if CONFIG_SUPERTX
3847 &sum_rate_nocoef,
3848 #endif
3849 #if CONFIG_EXT_PARTITION_TYPES
3850 PARTITION_SPLIT,
3851 #endif
3852 subsize, pc_tree->leaf_split[0], temp_best_rdcost);
3853 if (sum_rdc.rate == INT_MAX) {
3854 sum_rdc.rdcost = INT64_MAX;
3855 #if CONFIG_SUPERTX
3856 sum_rate_nocoef = INT_MAX;
3857 #endif
3858 }
3859 #if CONFIG_SUPERTX
3860 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3861 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3862 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3863
3864 pc_tree->partitioning = PARTITION_SPLIT;
3865
3866 sum_rdc.rate += av1_cost_bit(
3867 cm->fc->supertx_prob[partition_supertx_context_lookup
3868 [PARTITION_SPLIT]][supertx_size],
3869 0);
3870 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3871
3872 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3873 TX_TYPE best_tx = DCT_DCT;
3874 RD_STATS tmp_rdc;
3875 av1_init_rd_stats(&tmp_rdc);
3876 tmp_rdc.rate = sum_rate_nocoef;
3877
3878 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3879
3880 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3881 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3882
3883 tmp_rdc.rate += av1_cost_bit(
3884 cm->fc->supertx_prob[partition_supertx_context_lookup
3885 [PARTITION_SPLIT]][supertx_size],
3886 1);
3887 tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
3888 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3889 sum_rdc = tmp_rdc;
3890 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3891 supertx_size, pc_tree);
3892 }
3893 }
3894
3895 pc_tree->partitioning = best_partition;
3896 }
3897 #endif // CONFIG_SUPERTX
3898 reached_last_index = 1;
3899 } else {
3900 int idx;
3901 for (idx = 0; idx < 4 && sum_rdc.rdcost < temp_best_rdcost; ++idx) {
3902 const int x_idx = (idx & 1) * mi_step;
3903 const int y_idx = (idx >> 1) * mi_step;
3904
3905 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3906 continue;
3907
3908 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
3909
3910 pc_tree->split[idx]->index = idx;
3911 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3912 mi_col + x_idx, subsize, &this_rdc,
3913 #if CONFIG_SUPERTX
3914 &this_rate_nocoef,
3915 #endif
3916 temp_best_rdcost - sum_rdc.rdcost,
3917 pc_tree->split[idx]);
3918
3919 if (this_rdc.rate == INT_MAX) {
3920 sum_rdc.rdcost = INT64_MAX;
3921 #if CONFIG_SUPERTX
3922 sum_rate_nocoef = INT_MAX;
3923 #endif // CONFIG_SUPERTX
3924 break;
3925 } else {
3926 sum_rdc.rate += this_rdc.rate;
3927 sum_rdc.dist += this_rdc.dist;
3928 sum_rdc.rdcost += this_rdc.rdcost;
3929 #if CONFIG_SUPERTX
3930 sum_rate_nocoef += this_rate_nocoef;
3931 #endif // CONFIG_SUPERTX
3932 }
3933 }
3934 reached_last_index = (idx == 4);
3935
3936 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
3937 if (x->using_dist_8x8 && reached_last_index &&
3938 sum_rdc.rdcost != INT64_MAX && bsize == BLOCK_8X8) {
3939 const int src_stride = x->plane[0].src.stride;
3940 int64_t dist_8x8;
3941 dist_8x8 =
3942 dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride - 4);
3943 sum_rdc.dist = dist_8x8;
3944 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3945 }
3946 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
3947
3948 #if CONFIG_SUPERTX
3949 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
3950 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3951 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3952
3953 pc_tree->partitioning = PARTITION_SPLIT;
3954
3955 sum_rdc.rate += av1_cost_bit(
3956 cm->fc->supertx_prob[partition_supertx_context_lookup
3957 [PARTITION_SPLIT]][supertx_size],
3958 0);
3959 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3960
3961 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3962 TX_TYPE best_tx = DCT_DCT;
3963 RD_STATS tmp_rdc;
3964 av1_init_rd_stats(&tmp_rdc);
3965 tmp_rdc.rate = sum_rate_nocoef;
3966
3967 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3968
3969 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3970 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3971
3972 tmp_rdc.rate += av1_cost_bit(
3973 cm->fc->supertx_prob[partition_supertx_context_lookup
3974 [PARTITION_SPLIT]][supertx_size],
3975 1);
3976 tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
3977 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3978 sum_rdc = tmp_rdc;
3979 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3980 supertx_size, pc_tree);
3981 }
3982 }
3983
3984 pc_tree->partitioning = best_partition;
3985 }
3986 #endif // CONFIG_SUPERTX
3987 }
3988
3989 #if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
3990 if (!reached_last_index && sum_rdc.rdcost >= best_rdc.rdcost)
3991 cfl_clear_sub8x8_val(xd->cfl);
3992 #endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
3993
3994 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
3995 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3996 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
3997 #if CONFIG_SUPERTX
3998 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3999 #endif // CONFIG_SUPERTX
4000
4001 if (sum_rdc.rdcost < best_rdc.rdcost) {
4002 best_rdc = sum_rdc;
4003 #if CONFIG_SUPERTX
4004 best_rate_nocoef = sum_rate_nocoef;
4005 assert(best_rate_nocoef >= 0);
4006 #else
4007 temp_best_rdcost = best_rdc.rdcost;
4008 #endif // CONFIG_SUPERTX
4009 pc_tree->partitioning = PARTITION_SPLIT;
4010 }
4011 } else if (cpi->sf.less_rectangular_check) {
4012 // skip rectangular partition test when larger block size
4013 // gives better rd cost
4014 do_rectangular_split &= !partition_none_allowed;
4015 }
4016 #if !CONFIG_PVQ
4017 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4018 #else
4019 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4020 #endif
4021 } // if (do_split)
4022
4023 // PARTITION_HORZ
4024 if (partition_horz_allowed &&
4025 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
4026 subsize = get_subsize(bsize, PARTITION_HORZ);
4027 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
4028 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4029 partition_none_allowed)
4030 pc_tree->horizontal[0].pred_interp_filter =
4031 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
4032
4033 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4034 #if CONFIG_SUPERTX
4035 &sum_rate_nocoef,
4036 #endif // CONFIG_SUPERTX
4037 #if CONFIG_EXT_PARTITION_TYPES
4038 PARTITION_HORZ,
4039 #endif
4040 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
4041
4042 #if CONFIG_SUPERTX
4043 abort_flag =
4044 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4045 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
4046 #endif
4047 if (sum_rdc.rdcost < temp_best_rdcost && !force_horz_split &&
4048 (bsize > BLOCK_8X8 || unify_bsize)) {
4049 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
4050 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
4051 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4052 NULL);
4053
4054 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
4055
4056 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4057 partition_none_allowed)
4058 pc_tree->horizontal[1].pred_interp_filter =
4059 av1_extract_interp_filter(ctx_h->mic.mbmi.interp_filters, 0);
4060
4061 #if CONFIG_SUPERTX
4062 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4063 &this_rate_nocoef,
4064 #if CONFIG_EXT_PARTITION_TYPES
4065 PARTITION_HORZ,
4066 #endif
4067 subsize, &pc_tree->horizontal[1], INT64_MAX);
4068 #else
4069 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4070 #if CONFIG_EXT_PARTITION_TYPES
4071 PARTITION_HORZ,
4072 #endif
4073 subsize, &pc_tree->horizontal[1],
4074 best_rdc.rdcost - sum_rdc.rdcost);
4075 #endif // CONFIG_SUPERTX
4076
4077 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
4078 if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
4079 update_state(cpi, td, &pc_tree->horizontal[1], mi_row + mi_step, mi_col,
4080 subsize, DRY_RUN_NORMAL);
4081 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row + mi_step, mi_col,
4082 subsize, NULL);
4083 }
4084 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
4085
4086 if (this_rdc.rate == INT_MAX) {
4087 sum_rdc.rdcost = INT64_MAX;
4088 #if CONFIG_SUPERTX
4089 sum_rate_nocoef = INT_MAX;
4090 #endif // CONFIG_SUPERTX
4091 } else {
4092 sum_rdc.rate += this_rdc.rate;
4093 sum_rdc.dist += this_rdc.dist;
4094 sum_rdc.rdcost += this_rdc.rdcost;
4095 #if CONFIG_SUPERTX
4096 sum_rate_nocoef += this_rate_nocoef;
4097 #endif // CONFIG_SUPERTX
4098 }
4099 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
4100 if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
4101 bsize == BLOCK_8X8) {
4102 const int src_stride = x->plane[0].src.stride;
4103 int64_t dist_8x8;
4104 dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride);
4105 sum_rdc.dist = dist_8x8;
4106 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4107 }
4108 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
4109 }
4110
4111 #if CONFIG_SUPERTX
4112 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4113 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4114 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4115
4116 pc_tree->partitioning = PARTITION_HORZ;
4117
4118 sum_rdc.rate += av1_cost_bit(
4119 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4120 [supertx_size],
4121 0);
4122 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4123
4124 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4125 TX_TYPE best_tx = DCT_DCT;
4126 RD_STATS tmp_rdc;
4127 av1_init_rd_stats(&tmp_rdc);
4128 tmp_rdc.rate = sum_rate_nocoef;
4129
4130 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4131
4132 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4133 &tmp_rdc.dist, &best_tx, pc_tree);
4134
4135 tmp_rdc.rate += av1_cost_bit(
4136 cm->fc
4137 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4138 [supertx_size],
4139 1);
4140 tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
4141 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4142 sum_rdc = tmp_rdc;
4143 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4144 supertx_size, pc_tree);
4145 }
4146 }
4147
4148 pc_tree->partitioning = best_partition;
4149 }
4150 #endif // CONFIG_SUPERTX
4151
4152 #if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
4153 cfl_clear_sub8x8_val(xd->cfl);
4154 #endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
4155 if (sum_rdc.rdcost < best_rdc.rdcost) {
4156 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4157 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4158 #if CONFIG_SUPERTX
4159 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4160 #endif // CONFIG_SUPERTX
4161 if (sum_rdc.rdcost < best_rdc.rdcost) {
4162 best_rdc = sum_rdc;
4163 #if CONFIG_SUPERTX
4164 best_rate_nocoef = sum_rate_nocoef;
4165 assert(best_rate_nocoef >= 0);
4166 #endif // CONFIG_SUPERTX
4167 pc_tree->partitioning = PARTITION_HORZ;
4168 }
4169 }
4170 #if !CONFIG_PVQ
4171 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4172 #else
4173 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4174 #endif
4175 }
4176
4177 // PARTITION_VERT
4178 if (partition_vert_allowed &&
4179 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
4180 subsize = get_subsize(bsize, PARTITION_VERT);
4181
4182 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
4183
4184 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4185 partition_none_allowed)
4186 pc_tree->vertical[0].pred_interp_filter =
4187 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
4188
4189 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4190 #if CONFIG_SUPERTX
4191 &sum_rate_nocoef,
4192 #endif // CONFIG_SUPERTX
4193 #if CONFIG_EXT_PARTITION_TYPES
4194 PARTITION_VERT,
4195 #endif
4196 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4197 #if CONFIG_SUPERTX
4198 abort_flag =
4199 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4200 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
4201 const int64_t vert_max_rdcost = INT64_MAX;
4202 #else
4203 const int64_t vert_max_rdcost = best_rdc.rdcost;
4204 #endif // CONFIG_SUPERTX
4205 if (sum_rdc.rdcost < vert_max_rdcost && !force_vert_split &&
4206 (bsize > BLOCK_8X8 || unify_bsize)) {
4207 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4208 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4209 NULL);
4210
4211 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
4212
4213 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4214 partition_none_allowed)
4215 pc_tree->vertical[1].pred_interp_filter =
4216 av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
4217
4218 #if CONFIG_SUPERTX
4219 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4220 &this_rate_nocoef,
4221 #if CONFIG_EXT_PARTITION_TYPES
4222 PARTITION_VERT,
4223 #endif
4224 subsize, &pc_tree->vertical[1],
4225 INT64_MAX - sum_rdc.rdcost);
4226 #else
4227 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4228 #if CONFIG_EXT_PARTITION_TYPES
4229 PARTITION_VERT,
4230 #endif
4231 subsize, &pc_tree->vertical[1],
4232 best_rdc.rdcost - sum_rdc.rdcost);
4233 #endif // CONFIG_SUPERTX
4234
4235 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
4236 if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
4237 update_state(cpi, td, &pc_tree->vertical[1], mi_row, mi_col + mi_step,
4238 subsize, DRY_RUN_NORMAL);
4239 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col + mi_step,
4240 subsize, NULL);
4241 }
4242 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
4243
4244 if (this_rdc.rate == INT_MAX) {
4245 sum_rdc.rdcost = INT64_MAX;
4246 #if CONFIG_SUPERTX
4247 sum_rate_nocoef = INT_MAX;
4248 #endif // CONFIG_SUPERTX
4249 } else {
4250 sum_rdc.rate += this_rdc.rate;
4251 sum_rdc.dist += this_rdc.dist;
4252 sum_rdc.rdcost += this_rdc.rdcost;
4253 #if CONFIG_SUPERTX
4254 sum_rate_nocoef += this_rate_nocoef;
4255 #endif // CONFIG_SUPERTX
4256 }
4257 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
4258 if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
4259 bsize == BLOCK_8X8) {
4260 int64_t dist_8x8;
4261 dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4);
4262 sum_rdc.dist = dist_8x8;
4263 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4264 }
4265 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
4266 }
4267 #if CONFIG_SUPERTX
4268 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4269 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4270 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4271
4272 pc_tree->partitioning = PARTITION_VERT;
4273
4274 sum_rdc.rate += av1_cost_bit(
4275 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4276 [supertx_size],
4277 0);
4278 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4279
4280 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4281 TX_TYPE best_tx = DCT_DCT;
4282 RD_STATS tmp_rdc;
4283 av1_init_rd_stats(&tmp_rdc);
4284 tmp_rdc.rate = sum_rate_nocoef;
4285
4286 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4287
4288 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4289 &tmp_rdc.dist, &best_tx, pc_tree);
4290
4291 tmp_rdc.rate += av1_cost_bit(
4292 cm->fc
4293 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4294 [supertx_size],
4295 1);
4296 tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
4297 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4298 sum_rdc = tmp_rdc;
4299 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4300 supertx_size, pc_tree);
4301 }
4302 }
4303
4304 pc_tree->partitioning = best_partition;
4305 }
4306 #endif // CONFIG_SUPERTX
4307
4308 #if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
4309 cfl_clear_sub8x8_val(xd->cfl);
4310 #endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
4311
4312 if (sum_rdc.rdcost < best_rdc.rdcost) {
4313 sum_rdc.rate += partition_cost[PARTITION_VERT];
4314 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4315 #if CONFIG_SUPERTX
4316 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4317 #endif // CONFIG_SUPERTX
4318 if (sum_rdc.rdcost < best_rdc.rdcost) {
4319 best_rdc = sum_rdc;
4320 #if CONFIG_SUPERTX
4321 best_rate_nocoef = sum_rate_nocoef;
4322 assert(best_rate_nocoef >= 0);
4323 #endif // CONFIG_SUPERTX
4324 pc_tree->partitioning = PARTITION_VERT;
4325 }
4326 }
4327 #if !CONFIG_PVQ
4328 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4329 #else
4330 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4331 #endif
4332 }
4333
4334 #if CONFIG_EXT_PARTITION_TYPES
4335 const int ext_partition_allowed =
4336 do_rectangular_split && bsize > BLOCK_8X8 && partition_none_allowed;
4337
4338 #if CONFIG_EXT_PARTITION && CONFIG_EXT_PARTITION_TYPES_AB
4339 // Don't allow A/B partitions on 128x128 blocks for now (support for
4340 // 128x32 and 32x128 blocks doesn't yet exist).
4341 const int ab_partition_allowed =
4342 ext_partition_allowed && bsize < BLOCK_128X128;
4343 #else
4344 const int ab_partition_allowed = ext_partition_allowed;
4345 #endif
4346
4347 // PARTITION_HORZ_A
4348 if (partition_horz_allowed && ab_partition_allowed) {
4349 #if CONFIG_EXT_PARTITION_TYPES_AB
4350 rd_test_partition3(
4351 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontala,
4352 ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_A,
4353 #if CONFIG_SUPERTX
4354 best_rd, &best_rate_nocoef, &x_ctx,
4355 #endif
4356 mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ_4),
4357 mi_row + mi_step / 2, mi_col, get_subsize(bsize, PARTITION_HORZ_4),
4358 mi_row + mi_step, mi_col, get_subsize(bsize, PARTITION_HORZ));
4359 #else
4360 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4361 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4362 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
4363 PARTITION_HORZ_A,
4364 #if CONFIG_SUPERTX
4365 best_rd, &best_rate_nocoef, &x_ctx,
4366 #endif
4367 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4368 mi_row + mi_step, mi_col, subsize);
4369 #endif
4370 #if !CONFIG_PVQ
4371 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4372 #else
4373 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4374 #endif // !CONFIG_PVQ
4375 }
4376 // PARTITION_HORZ_B
4377 if (partition_horz_allowed && ab_partition_allowed) {
4378 #if CONFIG_EXT_PARTITION_TYPES_AB
4379 rd_test_partition3(
4380 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontalb,
4381 ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_B,
4382 #if CONFIG_SUPERTX
4383 best_rd, &best_rate_nocoef, &x_ctx,
4384 #endif
4385 mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ), mi_row + mi_step,
4386 mi_col, get_subsize(bsize, PARTITION_HORZ_4), mi_row + 3 * mi_step / 2,
4387 mi_col, get_subsize(bsize, PARTITION_HORZ_4));
4388 #else
4389 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4390 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4391 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
4392 PARTITION_HORZ_B,
4393 #if CONFIG_SUPERTX
4394 best_rd, &best_rate_nocoef, &x_ctx,
4395 #endif
4396 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4397 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4398 #endif
4399 #if !CONFIG_PVQ
4400 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4401 #else
4402 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4403 #endif // !CONFIG_PVQ
4404 }
4405 // PARTITION_VERT_A
4406 if (partition_vert_allowed && ab_partition_allowed) {
4407 #if CONFIG_EXT_PARTITION_TYPES_AB
4408 rd_test_partition3(
4409 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticala,
4410 ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_A,
4411 #if CONFIG_SUPERTX
4412 best_rd, &best_rate_nocoef, &x_ctx,
4413 #endif
4414 mi_row, mi_col, get_subsize(bsize, PARTITION_VERT_4), mi_row,
4415 mi_col + mi_step / 2, get_subsize(bsize, PARTITION_VERT_4), mi_row,
4416 mi_col + mi_step, get_subsize(bsize, PARTITION_VERT));
4417 #else
4418 subsize = get_subsize(bsize, PARTITION_VERT_A);
4419 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4420 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
4421 PARTITION_VERT_A,
4422 #if CONFIG_SUPERTX
4423 best_rd, &best_rate_nocoef, &x_ctx,
4424 #endif
4425 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4426 mi_row, mi_col + mi_step, subsize);
4427 #endif
4428 #if !CONFIG_PVQ
4429 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4430 #else
4431 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4432 #endif // !CONFIG_PVQ
4433 }
4434 // PARTITION_VERT_B
4435 if (partition_vert_allowed && ab_partition_allowed) {
4436 #if CONFIG_EXT_PARTITION_TYPES_AB
4437 rd_test_partition3(
4438 cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticalb,
4439 ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_B,
4440 #if CONFIG_SUPERTX
4441 best_rd, &best_rate_nocoef, &x_ctx,
4442 #endif
4443 mi_row, mi_col, get_subsize(bsize, PARTITION_VERT), mi_row,
4444 mi_col + mi_step, get_subsize(bsize, PARTITION_VERT_4), mi_row,
4445 mi_col + 3 * mi_step / 2, get_subsize(bsize, PARTITION_VERT_4));
4446 #else
4447 subsize = get_subsize(bsize, PARTITION_VERT_B);
4448 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
4449 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
4450 PARTITION_VERT_B,
4451 #if CONFIG_SUPERTX
4452 best_rd, &best_rate_nocoef, &x_ctx,
4453 #endif
4454 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4455 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4456 #endif
4457 #if !CONFIG_PVQ
4458 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4459 #else
4460 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4461 #endif // !CONFIG_PVQ
4462 }
4463
4464 #if CONFIG_EXT_PARTITION
4465 const int can_partition_4 = (bsize == BLOCK_128X128 || bsize == BLOCK_64X64 ||
4466 bsize == BLOCK_32X32 || bsize == BLOCK_16X16);
4467 #else
4468 const int can_partition_4 =
4469 (bsize == BLOCK_64X64 || bsize == BLOCK_32X32 || bsize == BLOCK_16X16);
4470 #endif // CONFIG_EXT_PARTITION
4471
4472 // PARTITION_HORZ_4
4473 // TODO(david.barker): For this and PARTITION_VERT_4,
4474 // * Add support for BLOCK_16X16 once we support 2x8 and 8x2 blocks for the
4475 // chroma plane
4476 // * Add support for supertx
4477 if (can_partition_4 && partition_horz_allowed && !force_horz_split &&
4478 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
4479 const int quarter_step = mi_size_high[bsize] / 4;
4480 PICK_MODE_CONTEXT *ctx_prev = ctx_none;
4481
4482 subsize = get_subsize(bsize, PARTITION_HORZ_4);
4483
4484 for (int i = 0; i < 4; ++i) {
4485 int this_mi_row = mi_row + i * quarter_step;
4486
4487 if (i > 0 && this_mi_row >= cm->mi_rows) break;
4488
4489 PICK_MODE_CONTEXT *ctx_this = &pc_tree->horizontal4[i];
4490
4491 if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3),
4492 this_mi_row, mi_col, subsize, &best_rdc, &sum_rdc,
4493 &this_rdc, PARTITION_HORZ_4, ctx_prev, ctx_this))
4494 break;
4495
4496 ctx_prev = ctx_this;
4497 }
4498
4499 if (sum_rdc.rdcost < best_rdc.rdcost) {
4500 sum_rdc.rate += partition_cost[PARTITION_HORZ_4];
4501 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4502 if (sum_rdc.rdcost < best_rdc.rdcost) {
4503 best_rdc = sum_rdc;
4504 pc_tree->partitioning = PARTITION_HORZ_4;
4505 }
4506 }
4507 #if !CONFIG_PVQ
4508 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4509 #else
4510 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4511 #endif
4512 }
4513 // PARTITION_VERT_4
4514 if (can_partition_4 && partition_vert_allowed && !force_vert_split &&
4515 (do_rectangular_split || av1_active_v_edge(cpi, mi_row, mi_step))) {
4516 const int quarter_step = mi_size_wide[bsize] / 4;
4517 PICK_MODE_CONTEXT *ctx_prev = ctx_none;
4518
4519 subsize = get_subsize(bsize, PARTITION_VERT_4);
4520
4521 for (int i = 0; i < 4; ++i) {
4522 int this_mi_col = mi_col + i * quarter_step;
4523
4524 if (i > 0 && this_mi_col >= cm->mi_cols) break;
4525
4526 PICK_MODE_CONTEXT *ctx_this = &pc_tree->vertical4[i];
4527
4528 if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3), mi_row,
4529 this_mi_col, subsize, &best_rdc, &sum_rdc, &this_rdc,
4530 PARTITION_VERT_4, ctx_prev, ctx_this))
4531 break;
4532
4533 ctx_prev = ctx_this;
4534 }
4535
4536 if (sum_rdc.rdcost < best_rdc.rdcost) {
4537 sum_rdc.rate += partition_cost[PARTITION_VERT_4];
4538 sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
4539 if (sum_rdc.rdcost < best_rdc.rdcost) {
4540 best_rdc = sum_rdc;
4541 pc_tree->partitioning = PARTITION_VERT_4;
4542 }
4543 }
4544 #if !CONFIG_PVQ
4545 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4546 #else
4547 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4548 #endif
4549 }
4550 #endif // CONFIG_EXT_PARTITION_TYPES
4551
4552 // TODO(jbb): This code added so that we avoid static analysis
4553 // warning related to the fact that best_rd isn't used after this
4554 // point. This code should be refactored so that the duplicate
4555 // checks occur in some sub function and thus are used...
4556 (void)best_rd;
4557 *rd_cost = best_rdc;
4558
4559 #if CONFIG_SUPERTX
4560 *rate_nocoef = best_rate_nocoef;
4561 #endif // CONFIG_SUPERTX
4562
4563 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4564 pc_tree->index != 3) {
4565 if (bsize == cm->sb_size) {
4566 #if CONFIG_MOTION_VAR && NC_MODE_INFO
4567 set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
4568 #endif
4569
4570 #if CONFIG_LV_MAP
4571 x->cb_offset = 0;
4572 #endif
4573
4574 #if CONFIG_NCOBMC_ADAPT_WEIGHT
4575 set_sb_mi_boundaries(cm, xd, mi_row, mi_col);
4576 #endif
4577 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4578 pc_tree, NULL);
4579 } else {
4580 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4581 pc_tree, NULL);
4582 }
4583 }
4584
4585 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
4586 if (x->using_dist_8x8 && best_rdc.rate < INT_MAX &&
4587 best_rdc.dist < INT64_MAX && bsize == BLOCK_4X4 && pc_tree->index == 3) {
4588 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4589 pc_tree, NULL);
4590 }
4591 #endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
4592
4593 if (bsize == cm->sb_size) {
4594 #if !CONFIG_PVQ && !CONFIG_LV_MAP
4595 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
4596 #endif
4597 assert(best_rdc.rate < INT_MAX);
4598 assert(best_rdc.dist < INT64_MAX);
4599 } else {
4600 assert(tp_orig == *tp);
4601 }
4602 }
4603
encode_rd_sb_row(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,int mi_row,TOKENEXTRA ** tp)4604 static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
4605 TileDataEnc *tile_data, int mi_row,
4606 TOKENEXTRA **tp) {
4607 AV1_COMMON *const cm = &cpi->common;
4608 const TileInfo *const tile_info = &tile_data->tile_info;
4609 MACROBLOCK *const x = &td->mb;
4610 MACROBLOCKD *const xd = &x->e_mbd;
4611 SPEED_FEATURES *const sf = &cpi->sf;
4612 int mi_col;
4613 #if CONFIG_EXT_PARTITION
4614 const int leaf_nodes = 256;
4615 #else
4616 const int leaf_nodes = 64;
4617 #endif // CONFIG_EXT_PARTITION
4618
4619 // Initialize the left context for the new SB row
4620 av1_zero_left_context(xd);
4621
4622 // Reset delta for every tile
4623 if (cm->delta_q_present_flag)
4624 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4625 #if CONFIG_EXT_DELTA_Q
4626 if (cm->delta_lf_present_flag) {
4627 #if CONFIG_LOOPFILTER_LEVEL
4628 if (mi_row == tile_info->mi_row_start)
4629 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
4630 xd->prev_delta_lf[lf_id] = 0;
4631 #endif // CONFIG_LOOPFILTER_LEVEL
4632 if (mi_row == tile_info->mi_row_start) xd->prev_delta_lf_from_base = 0;
4633 }
4634 #endif
4635
4636 // Code each SB in the row
4637 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4638 mi_col += cm->mib_size) {
4639 const struct segmentation *const seg = &cm->seg;
4640 int dummy_rate;
4641 int64_t dummy_dist;
4642 RD_STATS dummy_rdc;
4643 #if CONFIG_SUPERTX
4644 int dummy_rate_nocoef;
4645 #endif // CONFIG_SUPERTX
4646 int i;
4647 int seg_skip = 0;
4648
4649 const int idx_str = cm->mi_stride * mi_row + mi_col;
4650 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4651 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4652
4653 #if CONFIG_LV_MAP && LV_MAP_PROB
4654 av1_fill_coeff_costs(&td->mb, xd->tile_ctx);
4655 #else
4656 av1_fill_token_costs_from_cdf(x->token_head_costs,
4657 x->e_mbd.tile_ctx->coef_head_cdfs);
4658 av1_fill_token_costs_from_cdf(x->token_tail_costs,
4659 x->e_mbd.tile_ctx->coef_tail_cdfs);
4660 #endif
4661 av1_fill_mode_rates(cm, x, xd->tile_ctx);
4662
4663 if (sf->adaptive_pred_interp_filter) {
4664 #if !CONFIG_CB4X4
4665 for (i = 0; i < leaf_nodes; ++i)
4666 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4667 #endif
4668
4669 for (i = 0; i < leaf_nodes; ++i) {
4670 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4671 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4672 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4673 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4674 }
4675 }
4676
4677 x->tx_rd_record.num = x->tx_rd_record.index_start = 0;
4678 av1_zero(x->pred_mv);
4679 pc_root->index = 0;
4680
4681 if (seg->enabled) {
4682 const uint8_t *const map =
4683 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4684 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4685 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4686 }
4687 #if CONFIG_AMVR
4688 xd->cur_frame_mv_precision_level = cm->cur_frame_mv_precision_level;
4689 #endif
4690
4691 if (cm->delta_q_present_flag) {
4692 // Test mode for delta quantization
4693 int sb_row = mi_row >> 3;
4694 int sb_col = mi_col >> 3;
4695 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4696 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
4697
4698 // Ensure divisibility of delta_qindex by delta_q_res
4699 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4700 int qmask = ~(cm->delta_q_res - 1);
4701 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4702 cm->delta_q_res, 256 - cm->delta_q_res);
4703
4704 current_qindex =
4705 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4706 cm->base_qindex;
4707 assert(current_qindex > 0);
4708
4709 xd->delta_qindex = current_qindex - cm->base_qindex;
4710 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4711 xd->mi[0]->mbmi.current_q_index = current_qindex;
4712 #if !CONFIG_EXT_DELTA_Q
4713 xd->mi[0]->mbmi.segment_id = 0;
4714 #endif // CONFIG_EXT_DELTA_Q
4715 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
4716 #if CONFIG_EXT_DELTA_Q
4717 if (cpi->oxcf.deltaq_mode == DELTA_Q_LF) {
4718 int j, k;
4719 int lfmask = ~(cm->delta_lf_res - 1);
4720 int current_delta_lf_from_base = offset_qindex / 2;
4721 current_delta_lf_from_base =
4722 ((current_delta_lf_from_base + cm->delta_lf_res / 2) & lfmask);
4723
4724 // pre-set the delta lf for loop filter. Note that this value is set
4725 // before mi is assigned for each block in current superblock
4726 for (j = 0; j < AOMMIN(cm->mib_size, cm->mi_rows - mi_row); j++) {
4727 for (k = 0; k < AOMMIN(cm->mib_size, cm->mi_cols - mi_col); k++) {
4728 cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
4729 .mbmi.current_delta_lf_from_base =
4730 clamp(current_delta_lf_from_base, 0, MAX_LOOP_FILTER);
4731 #if CONFIG_LOOPFILTER_LEVEL
4732 for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
4733 cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
4734 .mbmi.curr_delta_lf[lf_id] = current_delta_lf_from_base;
4735 }
4736 #endif // CONFIG_LOOPFILTER_LEVEL
4737 }
4738 }
4739 }
4740 #endif // CONFIG_EXT_DELTA_Q
4741 }
4742
4743 x->source_variance = UINT_MAX;
4744 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4745 BLOCK_SIZE bsize;
4746 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4747 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4748 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4749 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4750 &dummy_rate, &dummy_dist,
4751 #if CONFIG_SUPERTX
4752 &dummy_rate_nocoef,
4753 #endif // CONFIG_SUPERTX
4754 1, pc_root);
4755 } else if (cpi->partition_search_skippable_frame) {
4756 BLOCK_SIZE bsize;
4757 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4758 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4759 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4760 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4761 &dummy_rate, &dummy_dist,
4762 #if CONFIG_SUPERTX
4763 &dummy_rate_nocoef,
4764 #endif // CONFIG_SUPERTX
4765 1, pc_root);
4766 } else {
4767 // If required set upper and lower partition size limits
4768 if (sf->auto_min_max_partition_size) {
4769 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4770 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4771 &x->min_partition_size, &x->max_partition_size);
4772 }
4773 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4774 &dummy_rdc,
4775 #if CONFIG_SUPERTX
4776 &dummy_rate_nocoef,
4777 #endif // CONFIG_SUPERTX
4778 INT64_MAX, pc_root);
4779 }
4780 }
4781 }
4782
init_encode_frame_mb_context(AV1_COMP * cpi)4783 static void init_encode_frame_mb_context(AV1_COMP *cpi) {
4784 MACROBLOCK *const x = &cpi->td.mb;
4785 AV1_COMMON *const cm = &cpi->common;
4786 MACROBLOCKD *const xd = &x->e_mbd;
4787
4788 // Copy data over into macro block data structures.
4789 av1_setup_src_planes(x, cpi->source, 0, 0);
4790
4791 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
4792 }
4793
4794 #if !CONFIG_REF_ADAPT
check_dual_ref_flags(AV1_COMP * cpi)4795 static int check_dual_ref_flags(AV1_COMP *cpi) {
4796 const int ref_flags = cpi->ref_frame_flags;
4797
4798 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4799 return 0;
4800 } else {
4801 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
4802 #if CONFIG_EXT_REFS
4803 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4804 !!(ref_flags & AOM_BWD_FLAG) + !!(ref_flags & AOM_ALT2_FLAG) +
4805 #endif // CONFIG_EXT_REFS
4806 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
4807 }
4808 }
4809 #endif // !CONFIG_REF_ADAPT
4810
4811 #if !CONFIG_VAR_TX
reset_skip_tx_size(AV1_COMMON * cm,TX_SIZE max_tx_size)4812 static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
4813 int mi_row, mi_col;
4814 const int mis = cm->mi_stride;
4815 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4816
4817 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4818 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4819 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4820 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4821 }
4822 }
4823 }
4824 #endif
4825
get_frame_type(const AV1_COMP * cpi)4826 static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
4827 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4828 #if CONFIG_EXT_REFS
4829 // We will not update the golden frame with an internal overlay frame
4830 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4831 cpi->rc.is_src_frame_ext_arf)
4832 #else
4833 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4834 #endif // CONFIG_EXT_REFS
4835 return ALTREF_FRAME;
4836 else if (cpi->refresh_golden_frame ||
4837 #if CONFIG_EXT_REFS
4838 cpi->refresh_alt2_ref_frame ||
4839 #endif // CONFIG_EXT_REFS
4840 cpi->refresh_alt_ref_frame)
4841 return GOLDEN_FRAME;
4842 else
4843 // TODO(zoeliu): To investigate whether a frame_type other than
4844 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4845 return LAST_FRAME;
4846 }
4847
select_tx_mode(const AV1_COMP * cpi)4848 static TX_MODE select_tx_mode(const AV1_COMP *cpi) {
4849 if (cpi->common.all_lossless) return ONLY_4X4;
4850 #if CONFIG_VAR_TX_NO_TX_MODE
4851 return TX_MODE_SELECT;
4852 #else
4853 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
4854 return ALLOW_32X32 + CONFIG_TX64X64;
4855 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4856 cpi->sf.tx_size_search_method == USE_TX_8X8)
4857 return TX_MODE_SELECT;
4858 else
4859 return cpi->common.tx_mode;
4860 #endif // CONFIG_VAR_TX_NO_TX_MODE
4861 }
4862
av1_init_tile_data(AV1_COMP * cpi)4863 void av1_init_tile_data(AV1_COMP *cpi) {
4864 AV1_COMMON *const cm = &cpi->common;
4865 const int tile_cols = cm->tile_cols;
4866 const int tile_rows = cm->tile_rows;
4867 int tile_col, tile_row;
4868 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4869 unsigned int tile_tok = 0;
4870
4871 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
4872 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4873 CHECK_MEM_ERROR(
4874 cm, cpi->tile_data,
4875 aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)));
4876 cpi->allocated_tiles = tile_cols * tile_rows;
4877
4878 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4879 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4880 TileDataEnc *const tile_data =
4881 &cpi->tile_data[tile_row * tile_cols + tile_col];
4882 int i, j;
4883 for (i = 0; i < BLOCK_SIZES_ALL; ++i) {
4884 for (j = 0; j < MAX_MODES; ++j) {
4885 tile_data->thresh_freq_fact[i][j] = 32;
4886 tile_data->mode_map[i][j] = j;
4887 }
4888 }
4889 #if CONFIG_PVQ
4890 // This will be dynamically increased as more pvq block is encoded.
4891 tile_data->pvq_q.buf_len = 1000;
4892 CHECK_MEM_ERROR(
4893 cm, tile_data->pvq_q.buf,
4894 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
4895 tile_data->pvq_q.curr_pos = 0;
4896 #endif
4897 }
4898 }
4899
4900 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4901 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4902 TileInfo *const tile_info =
4903 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
4904 av1_tile_init(tile_info, cm, tile_row, tile_col);
4905
4906 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4907 pre_tok = cpi->tile_tok[tile_row][tile_col];
4908 tile_tok = allocated_tokens(*tile_info);
4909 #if CONFIG_PVQ
4910 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4911 #endif
4912 }
4913 }
4914 }
4915
av1_encode_tile(AV1_COMP * cpi,ThreadData * td,int tile_row,int tile_col)4916 void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4917 int tile_col) {
4918 AV1_COMMON *const cm = &cpi->common;
4919 TileDataEnc *const this_tile =
4920 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4921 const TileInfo *const tile_info = &this_tile->tile_info;
4922 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4923 int mi_row;
4924
4925 #if CONFIG_DEPENDENT_HORZTILES
4926 if ((!cm->dependent_horz_tiles) || (tile_row == 0) ||
4927 tile_info->tg_horz_boundary) {
4928 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
4929 }
4930 #else
4931 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
4932 #endif
4933
4934 // Set up pointers to per thread motion search counters.
4935 this_tile->m_search_count = 0; // Count of motion search hits.
4936 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4937 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4938 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
4939
4940 #if CONFIG_PVQ
4941 td->mb.pvq_q = &this_tile->pvq_q;
4942
4943 // TODO(yushin) : activity masking info needs be signaled by a bitstream
4944 td->mb.daala_enc.use_activity_masking = AV1_PVQ_ENABLE_ACTIVITY_MASKING;
4945
4946 if (td->mb.daala_enc.use_activity_masking)
4947 td->mb.daala_enc.qm = OD_HVS_QM; // Hard coded. Enc/dec required to sync.
4948 else
4949 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4950
4951 {
4952 // FIXME: Multiple segments support
4953 int segment_id = 0;
4954 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4955 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4956 #if CONFIG_HIGHBITDEPTH
4957 const int quantizer_shift = td->mb.e_mbd.bd - 8;
4958 #else
4959 const int quantizer_shift = 0;
4960 #endif // CONFIG_HIGHBITDEPTH
4961 int64_t q_ac = OD_MAXI(
4962 1, av1_ac_quant(qindex, 0, cpi->common.bit_depth) >> quantizer_shift);
4963 int64_t q_dc = OD_MAXI(
4964 1, av1_dc_quant(qindex, 0, cpi->common.bit_depth) >> quantizer_shift);
4965 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4966 td->mb.daala_enc.pvq_norm_lambda =
4967 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4968 td->mb.daala_enc.pvq_norm_lambda_dc =
4969 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4970 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4971 }
4972 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4973 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
4974
4975 if (td->mb.daala_enc.use_activity_masking) {
4976 int pli;
4977 int use_masking = td->mb.daala_enc.use_activity_masking;
4978 int segment_id = 0;
4979 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4980
4981 for (pli = 0; pli < MAX_MB_PLANE; pli++) {
4982 int i;
4983 int q;
4984
4985 q = qindex;
4986 if (q <= OD_DEFAULT_QMS[use_masking][0][pli].interp_q << OD_COEFF_SHIFT) {
4987 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4988 &OD_DEFAULT_QMS[use_masking][0][pli], NULL);
4989 } else {
4990 i = 0;
4991 while (OD_DEFAULT_QMS[use_masking][i + 1][pli].qm_q4 != NULL &&
4992 q > OD_DEFAULT_QMS[use_masking][i + 1][pli].interp_q
4993 << OD_COEFF_SHIFT) {
4994 i++;
4995 }
4996 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4997 &OD_DEFAULT_QMS[use_masking][i][pli],
4998 &OD_DEFAULT_QMS[use_masking][i + 1][pli]);
4999 }
5000 }
5001 }
5002
5003 #if !CONFIG_ANS
5004 od_ec_enc_init(&td->mb.daala_enc.w.ec, 65025);
5005 od_ec_enc_reset(&td->mb.daala_enc.w.ec);
5006 #else
5007 #error "CONFIG_PVQ currently requires !CONFIG_ANS."
5008 #endif
5009 #endif // #if CONFIG_PVQ
5010
5011 this_tile->tctx = *cm->fc;
5012 td->mb.e_mbd.tile_ctx = &this_tile->tctx;
5013
5014 #if CONFIG_CFL
5015 MACROBLOCKD *const xd = &td->mb.e_mbd;
5016 xd->cfl = &this_tile->cfl;
5017 cfl_init(xd->cfl, cm);
5018 #endif
5019
5020 #if CONFIG_PVQ
5021 td->mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context;
5022 #endif // CONFIG_PVQ
5023
5024 #if CONFIG_LOOPFILTERING_ACROSS_TILES
5025 if (!cm->loop_filter_across_tiles_enabled)
5026 av1_setup_across_tile_boundary_info(cm, tile_info);
5027 #endif
5028
5029 av1_crc_calculator_init(&td->mb.tx_rd_record.crc_calculator, 24, 0x5D6DCB);
5030
5031 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
5032 mi_row += cm->mib_size) {
5033 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
5034 }
5035
5036 cpi->tok_count[tile_row][tile_col] =
5037 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
5038 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
5039 #if CONFIG_PVQ
5040 #if !CONFIG_ANS
5041 od_ec_enc_clear(&td->mb.daala_enc.w.ec);
5042 #else
5043 #error "CONFIG_PVQ currently requires !CONFIG_ANS."
5044 #endif
5045
5046 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
5047 // rewind current position so that bitstream can be written
5048 // from the 1st pvq block
5049 td->mb.pvq_q->curr_pos = 0;
5050
5051 td->mb.pvq_q = NULL;
5052 #endif
5053 }
5054
encode_tiles(AV1_COMP * cpi)5055 static void encode_tiles(AV1_COMP *cpi) {
5056 AV1_COMMON *const cm = &cpi->common;
5057 int tile_col, tile_row;
5058
5059 av1_init_tile_data(cpi);
5060
5061 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
5062 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
5063 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
5064 }
5065
5066 #if CONFIG_FP_MB_STATS
input_fpmb_stats(FIRSTPASS_MB_STATS * firstpass_mb_stats,AV1_COMMON * cm,uint8_t ** this_frame_mb_stats)5067 static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
5068 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
5069 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
5070 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
5071
5072 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
5073
5074 *this_frame_mb_stats = mb_stats_in;
5075
5076 return 1;
5077 }
5078 #endif
5079
5080 #if CONFIG_GLOBAL_MOTION
5081 #define GLOBAL_TRANS_TYPES_ENC 3 // highest motion model to search
gm_get_params_cost(const WarpedMotionParams * gm,const WarpedMotionParams * ref_gm,int allow_hp)5082 static int gm_get_params_cost(const WarpedMotionParams *gm,
5083 const WarpedMotionParams *ref_gm, int allow_hp) {
5084 assert(gm->wmtype < GLOBAL_TRANS_TYPES);
5085 int params_cost = 0;
5086 int trans_bits, trans_prec_diff;
5087 switch (gm->wmtype) {
5088 case HOMOGRAPHY:
5089 case HORTRAPEZOID:
5090 case VERTRAPEZOID:
5091 if (gm->wmtype != HORTRAPEZOID)
5092 params_cost += aom_count_signed_primitive_refsubexpfin(
5093 GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
5094 (ref_gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
5095 (gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
5096 if (gm->wmtype != VERTRAPEZOID)
5097 params_cost += aom_count_signed_primitive_refsubexpfin(
5098 GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
5099 (ref_gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
5100 (gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
5101 // Fallthrough intended
5102 case AFFINE:
5103 case ROTZOOM:
5104 params_cost += aom_count_signed_primitive_refsubexpfin(
5105 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
5106 (ref_gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
5107 (gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
5108 if (gm->wmtype != VERTRAPEZOID)
5109 params_cost += aom_count_signed_primitive_refsubexpfin(
5110 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
5111 (ref_gm->wmmat[3] >> GM_ALPHA_PREC_DIFF),
5112 (gm->wmmat[3] >> GM_ALPHA_PREC_DIFF));
5113 if (gm->wmtype >= AFFINE) {
5114 if (gm->wmtype != HORTRAPEZOID)
5115 params_cost += aom_count_signed_primitive_refsubexpfin(
5116 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
5117 (ref_gm->wmmat[4] >> GM_ALPHA_PREC_DIFF),
5118 (gm->wmmat[4] >> GM_ALPHA_PREC_DIFF));
5119 params_cost += aom_count_signed_primitive_refsubexpfin(
5120 GM_ALPHA_MAX + 1, SUBEXPFIN_K,
5121 (ref_gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
5122 (1 << GM_ALPHA_PREC_BITS),
5123 (gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
5124 }
5125 // Fallthrough intended
5126 case TRANSLATION:
5127 trans_bits = (gm->wmtype == TRANSLATION)
5128 ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
5129 : GM_ABS_TRANS_BITS;
5130 trans_prec_diff = (gm->wmtype == TRANSLATION)
5131 ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
5132 : GM_TRANS_PREC_DIFF;
5133 params_cost += aom_count_signed_primitive_refsubexpfin(
5134 (1 << trans_bits) + 1, SUBEXPFIN_K,
5135 (ref_gm->wmmat[0] >> trans_prec_diff),
5136 (gm->wmmat[0] >> trans_prec_diff));
5137 params_cost += aom_count_signed_primitive_refsubexpfin(
5138 (1 << trans_bits) + 1, SUBEXPFIN_K,
5139 (ref_gm->wmmat[1] >> trans_prec_diff),
5140 (gm->wmmat[1] >> trans_prec_diff));
5141 // Fallthrough intended
5142 case IDENTITY: break;
5143 default: assert(0);
5144 }
5145 return (params_cost << AV1_PROB_COST_SHIFT);
5146 }
5147
do_gm_search_logic(SPEED_FEATURES * const sf,int num_refs_using_gm,int frame)5148 static int do_gm_search_logic(SPEED_FEATURES *const sf, int num_refs_using_gm,
5149 int frame) {
5150 (void)num_refs_using_gm;
5151 (void)frame;
5152 switch (sf->gm_search_type) {
5153 case GM_FULL_SEARCH: return 1;
5154 case GM_REDUCED_REF_SEARCH:
5155 #if CONFIG_EXT_REFS
5156 return !(frame == LAST2_FRAME || frame == LAST3_FRAME);
5157 #else
5158 return (num_refs_using_gm < 2);
5159 #endif // CONFIG_EXT_REFS
5160 case GM_DISABLE_SEARCH: return 0;
5161 default: assert(0);
5162 }
5163 return 1;
5164 }
5165 #endif // CONFIG_GLOBAL_MOTION
5166
5167 // TODO(anybody) : remove this flag when PVQ supports pallete coding tool
5168 #if !CONFIG_PVQ
5169 // Estimate if the source frame is screen content, based on the portion of
5170 // blocks that have no more than 4 (experimentally selected) luma colors.
is_screen_content(const uint8_t * src,int use_hbd,int bd,int stride,int width,int height)5171 static int is_screen_content(const uint8_t *src,
5172 #if CONFIG_HIGHBITDEPTH
5173 int use_hbd, int bd,
5174 #endif // CONFIG_HIGHBITDEPTH
5175 int stride, int width, int height) {
5176 assert(src != NULL);
5177 int counts = 0;
5178 const int blk_w = 16;
5179 const int blk_h = 16;
5180 const int limit = 4;
5181 for (int r = 0; r + blk_h <= height; r += blk_h) {
5182 for (int c = 0; c + blk_w <= width; c += blk_w) {
5183 const int n_colors =
5184 #if CONFIG_HIGHBITDEPTH
5185 use_hbd ? av1_count_colors_highbd(src + r * stride + c, stride, blk_w,
5186 blk_h, bd)
5187 :
5188 #endif // CONFIG_HIGHBITDEPTH
5189 av1_count_colors(src + r * stride + c, stride, blk_w, blk_h);
5190 if (n_colors > 1 && n_colors <= limit) counts++;
5191 }
5192 }
5193 // The threshold is 10%.
5194 return counts * blk_h * blk_w * 10 > width * height;
5195 }
5196 #endif // !CONFIG_PVQ
5197
encode_frame_internal(AV1_COMP * cpi)5198 static void encode_frame_internal(AV1_COMP *cpi) {
5199 ThreadData *const td = &cpi->td;
5200 MACROBLOCK *const x = &td->mb;
5201 AV1_COMMON *const cm = &cpi->common;
5202 MACROBLOCKD *const xd = &x->e_mbd;
5203 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5204 int i;
5205 #if CONFIG_TEMPMV_SIGNALING || CONFIG_EXT_REFS
5206 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
5207 #endif // CONFIG_TEMPMV_SIGNALING || CONFIG_EXT_REFS
5208
5209 #if CONFIG_ADAPT_SCAN
5210 av1_deliver_eob_threshold(cm, xd);
5211 #endif
5212
5213 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
5214 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
5215 #if CONFIG_DIST_8X8
5216 x->using_dist_8x8 = cpi->oxcf.using_dist_8x8;
5217 x->tune_metric = cpi->oxcf.tuning;
5218 #endif
5219 cm->setup_mi(cm);
5220
5221 xd->mi = cm->mi_grid_visible;
5222 xd->mi[0] = cm->mi;
5223
5224 av1_zero(*td->counts);
5225 av1_zero(rdc->comp_pred_diff);
5226
5227 if (frame_is_intra_only(cm)) {
5228 // TODO(anybody) : remove this flag when PVQ supports pallete coding tool
5229 #if !CONFIG_PVQ
5230 cm->allow_screen_content_tools =
5231 cpi->oxcf.content == AOM_CONTENT_SCREEN ||
5232 is_screen_content(cpi->source->y_buffer,
5233 #if CONFIG_HIGHBITDEPTH
5234 cpi->source->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5235 #endif // CONFIG_HIGHBITDEPTH
5236 cpi->source->y_stride, cpi->source->y_width,
5237 cpi->source->y_height);
5238 #else
5239 cm->allow_screen_content_tools = 0;
5240 #endif // !CONFIG_PVQ
5241 }
5242
5243 #if CONFIG_HASH_ME
5244 if (cpi->oxcf.pass != 1 && cpi->common.allow_screen_content_tools) {
5245 // add to hash table
5246 const int pic_width = cpi->source->y_crop_width;
5247 const int pic_height = cpi->source->y_crop_height;
5248 uint32_t *block_hash_values[2][2];
5249 int8_t *is_block_same[2][3];
5250 int k, j;
5251
5252 for (k = 0; k < 2; k++) {
5253 for (j = 0; j < 2; j++) {
5254 CHECK_MEM_ERROR(cm, block_hash_values[k][j],
5255 aom_malloc(sizeof(uint32_t) * pic_width * pic_height));
5256 }
5257
5258 for (j = 0; j < 3; j++) {
5259 CHECK_MEM_ERROR(cm, is_block_same[k][j],
5260 aom_malloc(sizeof(int8_t) * pic_width * pic_height));
5261 }
5262 }
5263
5264 av1_hash_table_create(&cm->cur_frame->hash_table);
5265 av1_generate_block_2x2_hash_value(cpi->source, block_hash_values[0],
5266 is_block_same[0]);
5267 av1_generate_block_hash_value(cpi->source, 4, block_hash_values[0],
5268 block_hash_values[1], is_block_same[0],
5269 is_block_same[1]);
5270 av1_add_to_hash_map_by_row_with_precal_data(
5271 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
5272 pic_width, pic_height, 4);
5273 av1_generate_block_hash_value(cpi->source, 8, block_hash_values[1],
5274 block_hash_values[0], is_block_same[1],
5275 is_block_same[0]);
5276 av1_add_to_hash_map_by_row_with_precal_data(
5277 &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
5278 pic_width, pic_height, 8);
5279 av1_generate_block_hash_value(cpi->source, 16, block_hash_values[0],
5280 block_hash_values[1], is_block_same[0],
5281 is_block_same[1]);
5282 av1_add_to_hash_map_by_row_with_precal_data(
5283 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
5284 pic_width, pic_height, 16);
5285 av1_generate_block_hash_value(cpi->source, 32, block_hash_values[1],
5286 block_hash_values[0], is_block_same[1],
5287 is_block_same[0]);
5288 av1_add_to_hash_map_by_row_with_precal_data(
5289 &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
5290 pic_width, pic_height, 32);
5291 av1_generate_block_hash_value(cpi->source, 64, block_hash_values[0],
5292 block_hash_values[1], is_block_same[0],
5293 is_block_same[1]);
5294 av1_add_to_hash_map_by_row_with_precal_data(
5295 &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
5296 pic_width, pic_height, 64);
5297
5298 for (k = 0; k < 2; k++) {
5299 for (j = 0; j < 2; j++) {
5300 aom_free(block_hash_values[k][j]);
5301 }
5302
5303 for (j = 0; j < 3; j++) {
5304 aom_free(is_block_same[k][j]);
5305 }
5306 }
5307 }
5308 #endif
5309
5310 #if CONFIG_NCOBMC_ADAPT_WEIGHT
5311 alloc_ncobmc_pred_buffer(xd);
5312 #endif
5313
5314 #if CONFIG_GLOBAL_MOTION
5315 av1_zero(rdc->global_motion_used);
5316 av1_zero(cpi->gmparams_cost);
5317 if (cpi->common.frame_type == INTER_FRAME && cpi->source &&
5318 !cpi->global_motion_search_done) {
5319 YV12_BUFFER_CONFIG *ref_buf[TOTAL_REFS_PER_FRAME];
5320 int frame;
5321 double params_by_motion[RANSAC_NUM_MOTIONS * (MAX_PARAMDIM - 1)];
5322 const double *params_this_motion;
5323 int inliers_by_motion[RANSAC_NUM_MOTIONS];
5324 WarpedMotionParams tmp_wm_params;
5325 static const double kIdentityParams[MAX_PARAMDIM - 1] = {
5326 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
5327 };
5328 int num_refs_using_gm = 0;
5329
5330 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
5331 ref_buf[frame] = get_ref_frame_buffer(cpi, frame);
5332 int pframe;
5333 cm->global_motion[frame] = default_warp_params;
5334 const WarpedMotionParams *ref_params =
5335 cm->error_resilient_mode ? &default_warp_params
5336 : &cm->prev_frame->global_motion[frame];
5337 // check for duplicate buffer
5338 for (pframe = LAST_FRAME; pframe < frame; ++pframe) {
5339 if (ref_buf[frame] == ref_buf[pframe]) break;
5340 }
5341 if (pframe < frame) {
5342 memcpy(&cm->global_motion[frame], &cm->global_motion[pframe],
5343 sizeof(WarpedMotionParams));
5344 } else if (ref_buf[frame] &&
5345 ref_buf[frame]->y_crop_width == cpi->source->y_crop_width &&
5346 ref_buf[frame]->y_crop_height == cpi->source->y_crop_height &&
5347 do_gm_search_logic(&cpi->sf, num_refs_using_gm, frame)) {
5348 TransformationType model;
5349 const int64_t ref_frame_error = av1_frame_error(
5350 #if CONFIG_HIGHBITDEPTH
5351 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5352 #endif // CONFIG_HIGHBITDEPTH
5353 ref_buf[frame]->y_buffer, ref_buf[frame]->y_stride,
5354 cpi->source->y_buffer, cpi->source->y_width, cpi->source->y_height,
5355 cpi->source->y_stride);
5356
5357 if (ref_frame_error == 0) continue;
5358
5359 aom_clear_system_state();
5360 for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES_ENC; ++model) {
5361 int64_t best_warp_error = INT64_MAX;
5362 // Initially set all params to identity.
5363 for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
5364 memcpy(params_by_motion + (MAX_PARAMDIM - 1) * i, kIdentityParams,
5365 (MAX_PARAMDIM - 1) * sizeof(*params_by_motion));
5366 }
5367
5368 compute_global_motion_feature_based(
5369 model, cpi->source, ref_buf[frame],
5370 #if CONFIG_HIGHBITDEPTH
5371 cpi->common.bit_depth,
5372 #endif // CONFIG_HIGHBITDEPTH
5373 inliers_by_motion, params_by_motion, RANSAC_NUM_MOTIONS);
5374
5375 for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
5376 if (inliers_by_motion[i] == 0) continue;
5377
5378 params_this_motion = params_by_motion + (MAX_PARAMDIM - 1) * i;
5379 convert_model_to_params(params_this_motion, &tmp_wm_params);
5380
5381 if (tmp_wm_params.wmtype != IDENTITY) {
5382 const int64_t warp_error = refine_integerized_param(
5383 &tmp_wm_params, tmp_wm_params.wmtype,
5384 #if CONFIG_HIGHBITDEPTH
5385 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5386 #endif // CONFIG_HIGHBITDEPTH
5387 ref_buf[frame]->y_buffer, ref_buf[frame]->y_width,
5388 ref_buf[frame]->y_height, ref_buf[frame]->y_stride,
5389 cpi->source->y_buffer, cpi->source->y_width,
5390 cpi->source->y_height, cpi->source->y_stride, 5,
5391 best_warp_error);
5392 if (warp_error < best_warp_error) {
5393 best_warp_error = warp_error;
5394 // Save the wm_params modified by refine_integerized_param()
5395 // rather than motion index to avoid rerunning refine() below.
5396 memcpy(&(cm->global_motion[frame]), &tmp_wm_params,
5397 sizeof(WarpedMotionParams));
5398 }
5399 }
5400 }
5401 if (cm->global_motion[frame].wmtype <= AFFINE)
5402 if (!get_shear_params(&cm->global_motion[frame]))
5403 cm->global_motion[frame] = default_warp_params;
5404
5405 if (cm->global_motion[frame].wmtype == TRANSLATION) {
5406 cm->global_motion[frame].wmmat[0] =
5407 convert_to_trans_prec(cm->allow_high_precision_mv,
5408 cm->global_motion[frame].wmmat[0]) *
5409 GM_TRANS_ONLY_DECODE_FACTOR;
5410 cm->global_motion[frame].wmmat[1] =
5411 convert_to_trans_prec(cm->allow_high_precision_mv,
5412 cm->global_motion[frame].wmmat[1]) *
5413 GM_TRANS_ONLY_DECODE_FACTOR;
5414 }
5415
5416 // If the best error advantage found doesn't meet the threshold for
5417 // this motion type, revert to IDENTITY.
5418 if (!is_enough_erroradvantage(
5419 (double)best_warp_error / ref_frame_error,
5420 gm_get_params_cost(&cm->global_motion[frame], ref_params,
5421 cm->allow_high_precision_mv))) {
5422 cm->global_motion[frame] = default_warp_params;
5423 }
5424 if (cm->global_motion[frame].wmtype != IDENTITY) break;
5425 }
5426 aom_clear_system_state();
5427 }
5428 if (cm->global_motion[frame].wmtype != IDENTITY) num_refs_using_gm++;
5429 cpi->gmparams_cost[frame] =
5430 gm_get_params_cost(&cm->global_motion[frame], ref_params,
5431 cm->allow_high_precision_mv) +
5432 cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
5433 cpi->gmtype_cost[IDENTITY];
5434 }
5435 cpi->global_motion_search_done = 1;
5436 }
5437 memcpy(cm->cur_frame->global_motion, cm->global_motion,
5438 TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
5439 #endif // CONFIG_GLOBAL_MOTION
5440
5441 for (i = 0; i < MAX_SEGMENTS; ++i) {
5442 const int qindex = cm->seg.enabled
5443 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
5444 : cm->base_qindex;
5445 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
5446 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
5447 xd->qindex[i] = qindex;
5448 }
5449 cm->all_lossless = all_lossless(cm, xd);
5450 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
5451
5452 cm->tx_mode = select_tx_mode(cpi);
5453
5454 // Fix delta q resolution for the moment
5455 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
5456 // Set delta_q_present_flag before it is used for the first time
5457 #if CONFIG_EXT_DELTA_Q
5458 cm->delta_lf_res = DEFAULT_DELTA_LF_RES;
5459 // update delta_q_present_flag and delta_lf_present_flag based on base_qindex
5460 cm->delta_q_present_flag &= cm->base_qindex > 0;
5461 cm->delta_lf_present_flag &= cm->base_qindex > 0;
5462 #else
5463 cm->delta_q_present_flag =
5464 cpi->oxcf.aq_mode == DELTA_AQ && cm->base_qindex > 0;
5465 #endif // CONFIG_EXT_DELTA_Q
5466
5467 av1_frame_init_quantizer(cpi);
5468
5469 av1_initialize_rd_consts(cpi);
5470 av1_initialize_me_consts(cpi, x, cm->base_qindex);
5471 init_encode_frame_mb_context(cpi);
5472
5473 #if CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
5474 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
5475 // show_exisiting_frame=1, nor can it take a frame not used as
5476 // a reference, it is probable that by the time it is being
5477 // referred to, the frame buffer it originally points to may
5478 // already get expired and have been reassigned to the current
5479 // newly coded frame. Hence, we need to check whether this is
5480 // the case, and if yes, we have 2 choices:
5481 // (1) Simply disable the use of previous frame mvs; or
5482 // (2) Have cm->prev_frame point to one reference frame buffer,
5483 // e.g. LAST_FRAME.
5484 if (!enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
5485 // Reassign the LAST_FRAME buffer to cm->prev_frame.
5486 cm->prev_frame = last_fb_buf_idx != INVALID_IDX
5487 ? &cm->buffer_pool->frame_bufs[last_fb_buf_idx]
5488 : NULL;
5489 }
5490 #endif // CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
5491
5492 #if CONFIG_TEMPMV_SIGNALING
5493 cm->use_prev_frame_mvs &= frame_can_use_prev_frame_mvs(cm);
5494 #else
5495 if (cm->prev_frame) {
5496 cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
5497 #if CONFIG_FRAME_SUPERRES
5498 cm->width == cm->last_width &&
5499 cm->height == cm->last_height &&
5500 #else
5501 cm->width == cm->prev_frame->buf.y_crop_width &&
5502 cm->height == cm->prev_frame->buf.y_crop_height &&
5503 #endif // CONFIG_FRAME_SUPERRES
5504 !cm->intra_only && cm->last_show_frame;
5505 } else {
5506 cm->use_prev_frame_mvs = 0;
5507 }
5508 #endif // CONFIG_TEMPMV_SIGNALING
5509
5510 // Special case: set prev_mi to NULL when the previous mode info
5511 // context cannot be used.
5512 cm->prev_mi =
5513 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
5514
5515 #if CONFIG_VAR_TX
5516 x->txb_split_count = 0;
5517 av1_zero(x->blk_skip_drl);
5518 #endif
5519
5520 #if CONFIG_MFMV
5521 av1_setup_motion_field(cm);
5522 #endif // CONFIG_MFMV
5523
5524 {
5525 struct aom_usec_timer emr_timer;
5526 aom_usec_timer_start(&emr_timer);
5527
5528 #if CONFIG_FP_MB_STATS
5529 if (cpi->use_fp_mb_stats) {
5530 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
5531 &cpi->twopass.this_frame_mb_stats);
5532 }
5533 #endif
5534
5535 av1_setup_frame_boundary_info(cm);
5536
5537 // If allowed, encoding tiles in parallel with one thread handling one tile.
5538 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
5539 // 1 tile rows, as it uses the single above_context et al arrays from
5540 // cpi->common
5541 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
5542 av1_encode_tiles_mt(cpi);
5543 else
5544 encode_tiles(cpi);
5545
5546 aom_usec_timer_mark(&emr_timer);
5547 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
5548 }
5549 #if CONFIG_NCOBMC_ADAPT_WEIGHT
5550 free_ncobmc_pred_buffer(xd);
5551 #endif
5552
5553 #if 0
5554 // Keep record of the total distortion this time around for future use
5555 cpi->last_frame_distortion = cpi->frame_distortion;
5556 #endif
5557 }
5558
make_consistent_compound_tools(AV1_COMMON * cm)5559 static void make_consistent_compound_tools(AV1_COMMON *cm) {
5560 (void)cm;
5561 #if CONFIG_INTERINTRA
5562 if (frame_is_intra_only(cm) || cm->reference_mode == COMPOUND_REFERENCE)
5563 cm->allow_interintra_compound = 0;
5564 #endif // CONFIG_INTERINTRA
5565 #if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
5566 #if CONFIG_COMPOUND_SINGLEREF
5567 if (frame_is_intra_only(cm))
5568 #else // !CONFIG_COMPOUND_SINGLEREF
5569 if (frame_is_intra_only(cm) || cm->reference_mode == SINGLE_REFERENCE)
5570 #endif // CONFIG_COMPOUND_SINGLEREF
5571 cm->allow_masked_compound = 0;
5572 #endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
5573 }
5574
av1_encode_frame(AV1_COMP * cpi)5575 void av1_encode_frame(AV1_COMP *cpi) {
5576 AV1_COMMON *const cm = &cpi->common;
5577 #if CONFIG_EXT_TX
5578 // Indicates whether or not to use a default reduced set for ext-tx
5579 // rather than the potential full set of 16 transforms
5580 cm->reduced_tx_set_used = 0;
5581 #endif // CONFIG_EXT_TX
5582 #if CONFIG_ADAPT_SCAN
5583 cm->use_adapt_scan = 1;
5584 // TODO(angiebird): call av1_init_scan_order only when use_adapt_scan
5585 // switches from 1 to 0
5586 if (cm->use_adapt_scan == 0) av1_init_scan_order(cm);
5587 #endif
5588
5589 #if CONFIG_FRAME_MARKER
5590 if (cm->show_frame == 0) {
5591 int arf_offset = AOMMIN(
5592 (MAX_GF_INTERVAL - 1),
5593 cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
5594 #if CONFIG_EXT_REFS
5595 int brf_offset =
5596 cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
5597 arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
5598 #endif // CONFIG_EXT_REFS
5599 cm->frame_offset = cm->current_video_frame + arf_offset;
5600 } else {
5601 cm->frame_offset = cm->current_video_frame;
5602 }
5603 av1_setup_frame_buf_refs(cm);
5604 #if CONFIG_FRAME_SIGN_BIAS
5605 av1_setup_frame_sign_bias(cm);
5606 #endif // CONFIG_FRAME_SIGN_BIAS
5607 #endif // CONFIG_FRAME_MARKER
5608
5609 // In the longer term the encoder should be generalized to match the
5610 // decoder such that we allow compound where one of the 3 buffers has a
5611 // different sign bias and that buffer is then the fixed ref. However, this
5612 // requires further work in the rd loop. For now the only supported encoder
5613 // side behavior is where the ALT ref buffer has opposite sign bias to
5614 // the other two.
5615 if (!frame_is_intra_only(cm)) {
5616 #if !CONFIG_ONE_SIDED_COMPOUND
5617 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5618 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
5619 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5620 cm->ref_frame_sign_bias[LAST_FRAME])) {
5621 cpi->allow_comp_inter_inter = 0;
5622 } else {
5623 #endif // !CONFIG_ONE_SIDED_COMPOUND
5624 cpi->allow_comp_inter_inter = 1;
5625 #if CONFIG_EXT_REFS
5626 cm->comp_fwd_ref[0] = LAST_FRAME;
5627 cm->comp_fwd_ref[1] = LAST2_FRAME;
5628 cm->comp_fwd_ref[2] = LAST3_FRAME;
5629 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
5630 cm->comp_bwd_ref[0] = BWDREF_FRAME;
5631 cm->comp_bwd_ref[1] = ALTREF2_FRAME;
5632 cm->comp_bwd_ref[2] = ALTREF_FRAME;
5633 #else // !CONFIG_EXT_REFS
5634 cm->comp_fixed_ref = ALTREF_FRAME;
5635 cm->comp_var_ref[0] = LAST_FRAME;
5636 cm->comp_var_ref[1] = GOLDEN_FRAME;
5637 #endif // CONFIG_EXT_REFS
5638 #if !CONFIG_ONE_SIDED_COMPOUND // Normative in encoder
5639 }
5640 #endif // !CONFIG_ONE_SIDED_COMPOUND
5641 } else {
5642 cpi->allow_comp_inter_inter = 0;
5643 }
5644
5645 if (cpi->sf.frame_parameter_update) {
5646 int i;
5647 RD_OPT *const rd_opt = &cpi->rd;
5648 FRAME_COUNTS *counts = cpi->td.counts;
5649 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5650
5651 // This code does a single RD pass over the whole frame assuming
5652 // either compound, single or hybrid prediction as per whatever has
5653 // worked best for that type of frame in the past.
5654 // It also predicts whether another coding mode would have worked
5655 // better than this coding mode. If that is the case, it remembers
5656 // that for subsequent frames.
5657 // It does the same analysis for transform size selection also.
5658 //
5659 // TODO(zoeliu): To investigate whether a frame_type other than
5660 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
5661 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
5662 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
5663 const int is_alt_ref = frame_type == ALTREF_FRAME;
5664
5665 /* prediction (compound, single or hybrid) mode selection */
5666 #if CONFIG_REF_ADAPT
5667 // NOTE(zoeliu): "is_alt_ref" is true only for OVERLAY/INTNL_OVERLAY frames
5668 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5669 cm->reference_mode = SINGLE_REFERENCE;
5670 else
5671 cm->reference_mode = REFERENCE_MODE_SELECT;
5672 #else
5673 #if CONFIG_BGSPRITE
5674 (void)is_alt_ref;
5675 if (!cpi->allow_comp_inter_inter)
5676 #else
5677 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5678 #endif // CONFIG_BGSPRITE
5679 cm->reference_mode = SINGLE_REFERENCE;
5680 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
5681 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
5682 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
5683 cm->reference_mode = COMPOUND_REFERENCE;
5684 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
5685 cm->reference_mode = SINGLE_REFERENCE;
5686 else
5687 cm->reference_mode = REFERENCE_MODE_SELECT;
5688 #endif // CONFIG_REF_ADAPT
5689
5690 #if CONFIG_DUAL_FILTER
5691 cm->interp_filter = SWITCHABLE;
5692 #endif
5693
5694 make_consistent_compound_tools(cm);
5695
5696 rdc->single_ref_used_flag = 0;
5697 rdc->compound_ref_used_flag = 0;
5698
5699 encode_frame_internal(cpi);
5700
5701 for (i = 0; i < REFERENCE_MODES; ++i)
5702 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
5703
5704 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5705 // Use a flag that includes 4x4 blocks
5706 if (rdc->compound_ref_used_flag == 0) {
5707 cm->reference_mode = SINGLE_REFERENCE;
5708 av1_zero(counts->comp_inter);
5709 #if !CONFIG_REF_ADAPT
5710 // Use a flag that includes 4x4 blocks
5711 } else if (rdc->single_ref_used_flag == 0) {
5712 cm->reference_mode = COMPOUND_REFERENCE;
5713 av1_zero(counts->comp_inter);
5714 #endif // !CONFIG_REF_ADAPT
5715 }
5716 }
5717 make_consistent_compound_tools(cm);
5718
5719 #if CONFIG_VAR_TX
5720 #if CONFIG_RECT_TX_EXT
5721 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0 &&
5722 counts->quarter_tx_size[1] == 0)
5723 #else
5724 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
5725 #endif
5726 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
5727 #else
5728 #if CONFIG_RECT_TX_EXT && CONFIG_EXT_TX
5729 if (cm->tx_mode == TX_MODE_SELECT && counts->quarter_tx_size[1] == 0)
5730 #else
5731 if (cm->tx_mode == TX_MODE_SELECT)
5732 #endif
5733 {
5734 #if CONFIG_TX64X64
5735 int count4x4 = 0;
5736 int count8x8_8x8p = 0, count8x8_lp = 0;
5737 int count16x16_16x16p = 0, count16x16_lp = 0;
5738 int count32x32_32x32p = 0, count32x32_lp = 0;
5739 int count64x64_64x64p = 0;
5740 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5741 int depth;
5742 // counts->tx_size[max_depth][context_idx][this_depth_level]
5743 depth = tx_size_to_depth(TX_4X4);
5744 count4x4 += counts->tx_size[TX_8X8 - TX_SIZE_CTX_MIN][i][depth];
5745 count4x4 += counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5746 count4x4 += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5747 count4x4 += counts->tx_size[TX_64X64 - TX_SIZE_CTX_MIN][i][depth];
5748
5749 depth = tx_size_to_depth(TX_8X8);
5750 count8x8_8x8p += counts->tx_size[TX_8X8 - TX_SIZE_CTX_MIN][i][depth];
5751 count8x8_lp += counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5752 count8x8_lp += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5753 count8x8_lp += counts->tx_size[TX_64X64 - TX_SIZE_CTX_MIN][i][depth];
5754
5755 depth = tx_size_to_depth(TX_16X16);
5756 count16x16_16x16p +=
5757 counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5758 count16x16_lp += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5759 count16x16_lp += counts->tx_size[TX_64X64 - TX_SIZE_CTX_MIN][i][depth];
5760
5761 depth = tx_size_to_depth(TX_32X32);
5762 count32x32_32x32p +=
5763 counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5764 count32x32_lp += counts->tx_size[TX_64X64 - TX_SIZE_CTX_MIN][i][depth];
5765
5766 depth = tx_size_to_depth(TX_64X64);
5767 count64x64_64x64p +=
5768 counts->tx_size[TX_64X64 - TX_SIZE_CTX_MIN][i][depth];
5769 }
5770 #if CONFIG_EXT_TX && CONFIG_RECT_TX
5771 count4x4 += counts->tx_size_implied[TX_4X4][TX_4X4];
5772 count4x4 += counts->tx_size_implied[TX_8X8][TX_4X4];
5773 count4x4 += counts->tx_size_implied[TX_16X16][TX_4X4];
5774 count4x4 += counts->tx_size_implied[TX_32X32][TX_4X4];
5775 count8x8_8x8p += counts->tx_size_implied[TX_8X8][TX_8X8];
5776 count8x8_lp += counts->tx_size_implied[TX_16X16][TX_8X8];
5777 count8x8_lp += counts->tx_size_implied[TX_32X32][TX_8X8];
5778 count8x8_lp += counts->tx_size_implied[TX_64X64][TX_8X8];
5779 count16x16_16x16p += counts->tx_size_implied[TX_16X16][TX_16X16];
5780 count16x16_lp += counts->tx_size_implied[TX_32X32][TX_16X16];
5781 count16x16_lp += counts->tx_size_implied[TX_64X64][TX_16X16];
5782 count32x32_32x32p += counts->tx_size_implied[TX_32X32][TX_32X32];
5783 count32x32_lp += counts->tx_size_implied[TX_64X64][TX_32X32];
5784 count64x64_64x64p += counts->tx_size_implied[TX_64X64][TX_64X64];
5785 #endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5786 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5787 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5788 #if CONFIG_SUPERTX
5789 cm->counts.supertx_size[TX_16X16] == 0 &&
5790 cm->counts.supertx_size[TX_32X32] == 0 &&
5791 cm->counts.supertx_size[TX_64X64] == 0 &&
5792 #endif
5793 count64x64_64x64p == 0) {
5794 cm->tx_mode = ALLOW_8X8;
5795 reset_skip_tx_size(cm, TX_8X8);
5796 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5797 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5798 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5799 #if CONFIG_SUPERTX
5800 cm->counts.supertx_size[TX_8X8] == 0 &&
5801 cm->counts.supertx_size[TX_16X16] == 0 &&
5802 cm->counts.supertx_size[TX_32X32] == 0 &&
5803 cm->counts.supertx_size[TX_64X64] == 0 &&
5804 #endif
5805 count64x64_64x64p == 0) {
5806 cm->tx_mode = ONLY_4X4;
5807 reset_skip_tx_size(cm, TX_4X4);
5808 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5809 count32x32_lp == 0) {
5810 cm->tx_mode = ALLOW_64X64;
5811 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5812 #if CONFIG_SUPERTX
5813 cm->counts.supertx_size[TX_64X64] == 0 &&
5814 #endif
5815 count64x64_64x64p == 0) {
5816 cm->tx_mode = ALLOW_32X32;
5817 reset_skip_tx_size(cm, TX_32X32);
5818 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5819 count32x32_32x32p == 0 &&
5820 #if CONFIG_SUPERTX
5821 cm->counts.supertx_size[TX_32X32] == 0 &&
5822 cm->counts.supertx_size[TX_64X64] == 0 &&
5823 #endif
5824 count64x64_64x64p == 0) {
5825 cm->tx_mode = ALLOW_16X16;
5826 reset_skip_tx_size(cm, TX_16X16);
5827 }
5828
5829 #else // CONFIG_TX64X64
5830
5831 int count4x4 = 0;
5832 int count8x8_lp = 0, count8x8_8x8p = 0;
5833 int count16x16_16x16p = 0, count16x16_lp = 0;
5834 int count32x32 = 0;
5835 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5836 int depth;
5837 // counts->tx_size[max_depth][context_idx][this_depth_level]
5838 depth = tx_size_to_depth(TX_4X4);
5839 count4x4 += counts->tx_size[TX_8X8 - TX_SIZE_CTX_MIN][i][depth];
5840 count4x4 += counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5841 count4x4 += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5842
5843 depth = tx_size_to_depth(TX_8X8);
5844 count8x8_8x8p += counts->tx_size[TX_8X8 - TX_SIZE_CTX_MIN][i][depth];
5845 count8x8_lp += counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5846 count8x8_lp += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5847
5848 depth = tx_size_to_depth(TX_16X16);
5849 count16x16_16x16p +=
5850 counts->tx_size[TX_16X16 - TX_SIZE_CTX_MIN][i][depth];
5851 count16x16_lp += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5852
5853 depth = tx_size_to_depth(TX_32X32);
5854 count32x32 += counts->tx_size[TX_32X32 - TX_SIZE_CTX_MIN][i][depth];
5855 }
5856 #if CONFIG_EXT_TX && CONFIG_RECT_TX
5857 count4x4 += counts->tx_size_implied[TX_4X4][TX_4X4];
5858 count4x4 += counts->tx_size_implied[TX_8X8][TX_4X4];
5859 count4x4 += counts->tx_size_implied[TX_16X16][TX_4X4];
5860 count4x4 += counts->tx_size_implied[TX_32X32][TX_4X4];
5861 count8x8_8x8p += counts->tx_size_implied[TX_8X8][TX_8X8];
5862 count8x8_lp += counts->tx_size_implied[TX_16X16][TX_8X8];
5863 count8x8_lp += counts->tx_size_implied[TX_32X32][TX_8X8];
5864 count16x16_16x16p += counts->tx_size_implied[TX_16X16][TX_16X16];
5865 count16x16_lp += counts->tx_size_implied[TX_32X32][TX_16X16];
5866 count32x32 += counts->tx_size_implied[TX_32X32][TX_32X32];
5867 #endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5868 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5869 #if CONFIG_SUPERTX
5870 cm->counts.supertx_size[TX_16X16] == 0 &&
5871 cm->counts.supertx_size[TX_32X32] == 0 &&
5872 #endif // CONFIG_SUPERTX
5873 count32x32 == 0) {
5874 cm->tx_mode = ALLOW_8X8;
5875 reset_skip_tx_size(cm, TX_8X8);
5876 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5877 count8x8_lp == 0 && count16x16_lp == 0 &&
5878 #if CONFIG_SUPERTX
5879 cm->counts.supertx_size[TX_8X8] == 0 &&
5880 cm->counts.supertx_size[TX_16X16] == 0 &&
5881 cm->counts.supertx_size[TX_32X32] == 0 &&
5882 #endif // CONFIG_SUPERTX
5883 count32x32 == 0) {
5884 cm->tx_mode = ONLY_4X4;
5885 reset_skip_tx_size(cm, TX_4X4);
5886 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5887 cm->tx_mode = ALLOW_32X32;
5888 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5889 #if CONFIG_SUPERTX
5890 cm->counts.supertx_size[TX_32X32] == 0 &&
5891 #endif // CONFIG_SUPERTX
5892 count4x4 == 0) {
5893 cm->tx_mode = ALLOW_16X16;
5894 reset_skip_tx_size(cm, TX_16X16);
5895 }
5896 #endif // CONFIG_TX64X64
5897 }
5898 #endif
5899 } else {
5900 make_consistent_compound_tools(cm);
5901 encode_frame_internal(cpi);
5902 }
5903 }
5904
sum_intra_stats(FRAME_COUNTS * counts,MACROBLOCKD * xd,const MODE_INFO * mi,const MODE_INFO * above_mi,const MODE_INFO * left_mi,const int intraonly,const int mi_row,const int mi_col)5905 static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
5906 const MODE_INFO *mi, const MODE_INFO *above_mi,
5907 const MODE_INFO *left_mi, const int intraonly,
5908 const int mi_row, const int mi_col) {
5909 FRAME_CONTEXT *fc = xd->tile_ctx;
5910 const MB_MODE_INFO *const mbmi = &mi->mbmi;
5911 const PREDICTION_MODE y_mode = mbmi->mode;
5912 const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
5913 (void)counts;
5914 const BLOCK_SIZE bsize = mbmi->sb_type;
5915 const int unify_bsize = CONFIG_CB4X4;
5916
5917 if (bsize < BLOCK_8X8 && !unify_bsize) {
5918 int idx, idy;
5919 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5920 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5921 for (idy = 0; idy < 2; idy += num_4x4_h)
5922 for (idx = 0; idx < 2; idx += num_4x4_w) {
5923 const int bidx = idy * 2 + idx;
5924 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5925 if (intraonly) {
5926 #if CONFIG_ENTROPY_STATS
5927 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5928 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
5929 ++counts->kf_y_mode[a][l][bmode];
5930 #endif // CONFIG_ENTROPY_STATS
5931 update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, bidx), bmode,
5932 INTRA_MODES);
5933 } else {
5934 #if CONFIG_ENTROPY_STATS
5935 ++counts->y_mode[0][bmode];
5936 #endif // CONFIG_ENTROPY_STATS
5937 update_cdf(fc->y_mode_cdf[0], bmode, INTRA_MODES);
5938 }
5939 }
5940 } else {
5941 if (intraonly) {
5942 #if CONFIG_ENTROPY_STATS
5943 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5944 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
5945 ++counts->kf_y_mode[above][left][y_mode];
5946 #endif // CONFIG_ENTROPY_STATS
5947 update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, 0), y_mode,
5948 INTRA_MODES);
5949 } else {
5950 #if CONFIG_ENTROPY_STATS
5951 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5952 #endif // CONFIG_ENTROPY_STATS
5953 update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
5954 }
5955
5956 #if CONFIG_FILTER_INTRA
5957 if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0) {
5958 const int use_filter_intra_mode =
5959 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5960 ++counts->filter_intra[0][use_filter_intra_mode];
5961 }
5962 if (mbmi->uv_mode == UV_DC_PRED
5963 #if CONFIG_CB4X4
5964 &&
5965 is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
5966 xd->plane[1].subsampling_y)
5967 #endif
5968 && mbmi->palette_mode_info.palette_size[1] == 0) {
5969 const int use_filter_intra_mode =
5970 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5971 ++counts->filter_intra[1][use_filter_intra_mode];
5972 }
5973 #endif // CONFIG_FILTER_INTRA
5974 #if CONFIG_EXT_INTRA && CONFIG_INTRA_INTERP
5975 if (av1_is_directional_mode(mbmi->mode, bsize)) {
5976 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
5977 const int p_angle =
5978 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
5979 if (av1_is_intra_filter_switchable(p_angle))
5980 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5981 }
5982 #endif // CONFIG_INTRA_INTERP && CONFIG_INTRA_INTERP
5983 }
5984
5985 #if CONFIG_CB4X4
5986 if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
5987 xd->plane[1].subsampling_y))
5988 return;
5989 #else
5990 (void)mi_row;
5991 (void)mi_col;
5992 (void)xd;
5993 #endif
5994 #if CONFIG_ENTROPY_STATS
5995 ++counts->uv_mode[y_mode][uv_mode];
5996 #endif // CONFIG_ENTROPY_STATS
5997 update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
5998 }
5999
6000 #if CONFIG_VAR_TX
update_txfm_count(MACROBLOCK * x,MACROBLOCKD * xd,FRAME_COUNTS * counts,TX_SIZE tx_size,int depth,int blk_row,int blk_col)6001 static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
6002 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
6003 int blk_row, int blk_col) {
6004 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6005 const int tx_row = blk_row >> 1;
6006 const int tx_col = blk_col >> 1;
6007 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
6008 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
6009 int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
6010 xd->left_txfm_context + blk_row,
6011 mbmi->sb_type, tx_size);
6012 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
6013
6014 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
6015 assert(tx_size > TX_4X4);
6016
6017 if (depth == MAX_VARTX_DEPTH) {
6018 // Don't add to counts in this case
6019 #if CONFIG_RECT_TX_EXT
6020 if (tx_size == plane_tx_size)
6021 #endif
6022 mbmi->tx_size = tx_size;
6023 txfm_partition_update(xd->above_txfm_context + blk_col,
6024 xd->left_txfm_context + blk_row, tx_size, tx_size);
6025 return;
6026 }
6027
6028 #if CONFIG_RECT_TX_EXT
6029 if (tx_size == plane_tx_size ||
6030 mbmi->tx_size == quarter_txsize_lookup[mbmi->sb_type])
6031 #else
6032 if (tx_size == plane_tx_size)
6033 #endif
6034 {
6035 ++counts->txfm_partition[ctx][0];
6036 #if CONFIG_RECT_TX_EXT
6037 if (tx_size == plane_tx_size)
6038 #endif
6039 mbmi->tx_size = tx_size;
6040 txfm_partition_update(xd->above_txfm_context + blk_col,
6041 xd->left_txfm_context + blk_row, tx_size, tx_size);
6042 } else {
6043 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
6044 const int bs = tx_size_wide_unit[sub_txs];
6045 int i;
6046
6047 ++counts->txfm_partition[ctx][1];
6048 ++x->txb_split_count;
6049
6050 if (sub_txs == TX_4X4) {
6051 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
6052 mbmi->tx_size = TX_4X4;
6053 txfm_partition_update(xd->above_txfm_context + blk_col,
6054 xd->left_txfm_context + blk_row, TX_4X4, tx_size);
6055 return;
6056 }
6057
6058 for (i = 0; i < 4; ++i) {
6059 int offsetr = (i >> 1) * bs;
6060 int offsetc = (i & 0x01) * bs;
6061 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
6062 blk_col + offsetc);
6063 }
6064 }
6065 }
6066
tx_partition_count_update(const AV1_COMMON * const cm,MACROBLOCK * x,BLOCK_SIZE plane_bsize,int mi_row,int mi_col,FRAME_COUNTS * td_counts)6067 static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
6068 BLOCK_SIZE plane_bsize, int mi_row,
6069 int mi_col, FRAME_COUNTS *td_counts) {
6070 MACROBLOCKD *xd = &x->e_mbd;
6071 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
6072 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
6073 TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
6074 const int bh = tx_size_high_unit[max_tx_size];
6075 const int bw = tx_size_wide_unit[max_tx_size];
6076 int idx, idy;
6077 int init_depth =
6078 (mi_height != mi_width) ? RECT_VARTX_DEPTH_INIT : SQR_VARTX_DEPTH_INIT;
6079
6080 #if CONFIG_INTRABC
6081 // Intrabc doesn't support var-tx yet. So no need to update tx partition
6082 // info., except for the split count (otherwise common->tx_mode may be
6083 // modified, causing mismatch).
6084 if (is_intrabc_block(&x->e_mbd.mi[0]->mbmi)) {
6085 if (x->e_mbd.mi[0]->mbmi.tx_size != max_tx_size) ++x->txb_split_count;
6086 return;
6087 }
6088 #endif // CONFIG_INTRABC
6089
6090 xd->above_txfm_context =
6091 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
6092 xd->left_txfm_context = xd->left_txfm_context_buffer +
6093 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
6094
6095 for (idy = 0; idy < mi_height; idy += bh)
6096 for (idx = 0; idx < mi_width; idx += bw)
6097 update_txfm_count(x, xd, td_counts, max_tx_size, init_depth, idy, idx);
6098 }
6099
set_txfm_context(MACROBLOCKD * xd,TX_SIZE tx_size,int blk_row,int blk_col)6100 static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
6101 int blk_col) {
6102 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6103 const int tx_row = blk_row >> 1;
6104 const int tx_col = blk_col >> 1;
6105 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
6106 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
6107 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
6108
6109 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
6110
6111 if (tx_size == plane_tx_size) {
6112 mbmi->tx_size = tx_size;
6113 txfm_partition_update(xd->above_txfm_context + blk_col,
6114 xd->left_txfm_context + blk_row, tx_size, tx_size);
6115
6116 } else {
6117 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
6118 const int bsl = tx_size_wide_unit[sub_txs];
6119 int i;
6120
6121 if (tx_size == TX_8X8) {
6122 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
6123 mbmi->tx_size = TX_4X4;
6124 txfm_partition_update(xd->above_txfm_context + blk_col,
6125 xd->left_txfm_context + blk_row, TX_4X4, tx_size);
6126 return;
6127 }
6128
6129 assert(bsl > 0);
6130 for (i = 0; i < 4; ++i) {
6131 int offsetr = (i >> 1) * bsl;
6132 int offsetc = (i & 0x01) * bsl;
6133 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
6134 }
6135 }
6136 }
6137
tx_partition_set_contexts(const AV1_COMMON * const cm,MACROBLOCKD * xd,BLOCK_SIZE plane_bsize,int mi_row,int mi_col)6138 static void tx_partition_set_contexts(const AV1_COMMON *const cm,
6139 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
6140 int mi_row, int mi_col) {
6141 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
6142 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
6143 TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
6144 const int bh = tx_size_high_unit[max_tx_size];
6145 const int bw = tx_size_wide_unit[max_tx_size];
6146 int idx, idy;
6147
6148 xd->above_txfm_context =
6149 cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
6150 xd->left_txfm_context = xd->left_txfm_context_buffer +
6151 ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
6152
6153 for (idy = 0; idy < mi_height; idy += bh)
6154 for (idx = 0; idx < mi_width; idx += bw)
6155 set_txfm_context(xd, max_tx_size, idy, idx);
6156 }
6157 #endif
6158
av1_update_tx_type_count(const AV1_COMMON * cm,MACROBLOCKD * xd,int blk_row,int blk_col,int block,int plane,BLOCK_SIZE bsize,TX_SIZE tx_size,FRAME_COUNTS * counts)6159 void av1_update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
6160 #if CONFIG_TXK_SEL
6161 int blk_row, int blk_col, int block, int plane,
6162 #endif
6163 BLOCK_SIZE bsize, TX_SIZE tx_size,
6164 FRAME_COUNTS *counts) {
6165 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
6166 int is_inter = is_inter_block(mbmi);
6167 FRAME_CONTEXT *fc = xd->tile_ctx;
6168 #if !CONFIG_ENTROPY_STATS
6169 (void)counts;
6170 #endif // !CONFIG_ENTROPY_STATS
6171
6172 #if !CONFIG_TXK_SEL
6173 TX_TYPE tx_type = mbmi->tx_type;
6174 #else
6175 (void)blk_row;
6176 (void)blk_col;
6177 // Only y plane's tx_type is updated
6178 if (plane > 0) return;
6179 TX_TYPE tx_type =
6180 av1_get_tx_type(PLANE_TYPE_Y, xd, blk_row, blk_col, block, tx_size);
6181 #endif
6182 #if CONFIG_EXT_TX
6183 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) > 1 &&
6184 cm->base_qindex > 0 && !mbmi->skip &&
6185 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
6186 const int eset =
6187 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
6188 if (eset > 0) {
6189 #if !CONFIG_LGT_FROM_PRED
6190 const TxSetType tx_set_type = get_ext_tx_set_type(
6191 tx_size, bsize, is_inter, cm->reduced_tx_set_used);
6192 if (is_inter) {
6193 update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
6194 av1_ext_tx_ind[tx_set_type][tx_type],
6195 av1_num_ext_tx_set[tx_set_type]);
6196 #if CONFIG_ENTROPY_STATS
6197 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
6198 #endif // CONFIG_ENTROPY_STATS
6199 } else {
6200 #if CONFIG_ENTROPY_STATS
6201 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
6202 [tx_type];
6203 #endif // CONFIG_ENTROPY_STATS
6204 update_cdf(
6205 fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][mbmi->mode],
6206 av1_ext_tx_ind[tx_set_type][tx_type],
6207 av1_num_ext_tx_set[tx_set_type]);
6208 }
6209 #else
6210 (void)tx_type;
6211 (void)fc;
6212 if (is_inter) {
6213 if (LGT_FROM_PRED_INTER) {
6214 if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
6215 ++counts->inter_lgt[txsize_sqr_map[tx_size]][mbmi->use_lgt];
6216 #if CONFIG_ENTROPY_STATS
6217 if (!mbmi->use_lgt)
6218 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
6219 else
6220 #endif // CONFIG_ENTROPY_STATS
6221 mbmi->tx_type = DCT_DCT;
6222 } else {
6223 #if CONFIG_ENTROPY_STATS
6224 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
6225 #endif // CONFIG_ENTROPY_STATS
6226 }
6227 } else {
6228 if (LGT_FROM_PRED_INTRA) {
6229 if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
6230 ++counts->intra_lgt[txsize_sqr_map[tx_size]][mbmi->mode]
6231 [mbmi->use_lgt];
6232 #if CONFIG_ENTROPY_STATS
6233 if (!mbmi->use_lgt)
6234 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
6235 [tx_type];
6236 else
6237 #endif // CONFIG_ENTROPY_STATS
6238 mbmi->tx_type = DCT_DCT;
6239 } else {
6240 #if CONFIG_ENTROPY_STATS
6241 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
6242 [tx_type];
6243 #endif // CONFIG_ENTROPY_STATS
6244 }
6245 }
6246 #endif // CONFIG_LGT_FROM_PRED
6247 }
6248 }
6249 #else
6250 (void)bsize;
6251 if (tx_size < TX_32X32 &&
6252 ((!cm->seg.enabled && cm->base_qindex > 0) ||
6253 (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
6254 !mbmi->skip &&
6255 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
6256 if (is_inter) {
6257 #if CONFIG_ENTROPY_STATS
6258 ++counts->inter_ext_tx[tx_size][tx_type];
6259 #endif // CONFIG_ENTROPY_STATS
6260 update_cdf(fc->inter_ext_tx_cdf[tx_size], av1_ext_tx_ind[tx_type],
6261 TX_TYPES);
6262 } else {
6263 #if CONFIG_ENTROPY_STATS
6264 ++counts->intra_ext_tx[tx_size][intra_mode_to_tx_type_context[mbmi->mode]]
6265 [tx_type];
6266 #endif // CONFIG_ENTROPY_STATS
6267 update_cdf(
6268 fc->intra_ext_tx_cdf[tx_size]
6269 [intra_mode_to_tx_type_context[mbmi->mode]],
6270 av1_ext_tx_ind[tx_type], TX_TYPES);
6271 }
6272 }
6273 #endif // CONFIG_EXT_TX
6274 }
6275
encode_superblock(const AV1_COMP * const cpi,ThreadData * td,TOKENEXTRA ** t,RUN_TYPE dry_run,int mi_row,int mi_col,BLOCK_SIZE bsize,int * rate)6276 static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
6277 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
6278 int mi_col, BLOCK_SIZE bsize, int *rate) {
6279 const AV1_COMMON *const cm = &cpi->common;
6280 MACROBLOCK *const x = &td->mb;
6281 MACROBLOCKD *const xd = &x->e_mbd;
6282 MODE_INFO **mi_8x8 = xd->mi;
6283 MODE_INFO *mi = mi_8x8[0];
6284 MB_MODE_INFO *mbmi = &mi->mbmi;
6285 const int seg_skip =
6286 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
6287 const int mis = cm->mi_stride;
6288 const int mi_width = mi_size_wide[bsize];
6289 const int mi_height = mi_size_high[bsize];
6290 const int is_inter = is_inter_block(mbmi);
6291 #if CONFIG_CB4X4
6292 const BLOCK_SIZE block_size = bsize;
6293 #else
6294 const BLOCK_SIZE block_size = AOMMAX(bsize, BLOCK_8X8);
6295 #endif
6296
6297 #if CONFIG_PVQ
6298 x->pvq_speed = 0;
6299 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
6300 #endif
6301
6302 if (!is_inter) {
6303 #if CONFIG_CFL
6304 xd->cfl->store_y = 1;
6305 #endif // CONFIG_CFL
6306 int plane;
6307 mbmi->skip = 1;
6308 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
6309 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
6310 mi_row, mi_col);
6311 }
6312 #if CONFIG_CFL
6313 xd->cfl->store_y = 0;
6314 #if CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
6315 if (is_chroma_reference(mi_row, mi_col, bsize, xd->cfl->subsampling_x,
6316 xd->cfl->subsampling_y) &&
6317 !xd->cfl->are_parameters_computed) {
6318 cfl_clear_sub8x8_val(xd->cfl);
6319 }
6320 #endif // CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
6321 #endif // CONFIG_CFL
6322 if (!dry_run) {
6323 sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
6324 frame_is_intra_only(cm), mi_row, mi_col);
6325 }
6326
6327 // TODO(anybody) : remove this flag when PVQ supports pallete coding tool
6328 #if !CONFIG_PVQ
6329 if (bsize >= BLOCK_8X8) {
6330 for (plane = 0; plane <= 1; ++plane) {
6331 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
6332 if (!dry_run)
6333 av1_tokenize_color_map(x, plane, 0, t, bsize, mbmi->tx_size,
6334 PALETTE_MAP);
6335 else if (dry_run == DRY_RUN_COSTCOEFFS)
6336 rate += av1_cost_color_map(x, plane, 0, bsize, mbmi->tx_size,
6337 PALETTE_MAP);
6338 }
6339 }
6340 }
6341 #endif // !CONFIG_PVQ
6342
6343 #if CONFIG_VAR_TX
6344 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
6345 #endif
6346 #if CONFIG_LV_MAP
6347 av1_update_txb_context(cpi, td, dry_run, block_size, rate, mi_row, mi_col);
6348 #else // CONFIG_LV_MAP
6349 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
6350 #endif // CONFIG_LV_MAP
6351 } else {
6352 int ref;
6353 const int is_compound = has_second_ref(mbmi);
6354
6355 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
6356 for (ref = 0; ref < 1 + is_compound; ++ref) {
6357 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
6358 #if CONFIG_INTRABC
6359 assert(IMPLIES(!is_intrabc_block(mbmi), cfg));
6360 #else
6361 assert(cfg != NULL);
6362 #endif // !CONFIG_INTRABC
6363 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
6364 &xd->block_refs[ref]->sf);
6365 }
6366 #if CONFIG_COMPOUND_SINGLEREF
6367 // Single ref compound mode
6368 if (!is_compound && is_inter_singleref_comp_mode(mbmi->mode)) {
6369 xd->block_refs[1] = xd->block_refs[0];
6370 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[0]);
6371 #if CONFIG_INTRABC
6372 assert(IMPLIES(!is_intrabc_block(mbmi), cfg));
6373 #else
6374 assert(cfg != NULL);
6375 #endif // !CONFIG_INTRABC
6376 av1_setup_pre_planes(xd, 1, cfg, mi_row, mi_col, &xd->block_refs[1]->sf);
6377 }
6378 #endif // CONFIG_COMPOUND_SINGLEREF
6379
6380 av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, block_size);
6381
6382 #if !CONFIG_NCOBMC_ADAPT_WEIGHT
6383 #if CONFIG_MOTION_VAR
6384 if (mbmi->motion_mode == OBMC_CAUSAL) {
6385 #if CONFIG_NCOBMC
6386 if (dry_run == OUTPUT_ENABLED)
6387 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
6388 else
6389 #endif
6390 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
6391 }
6392 #endif // CONFIG_MOTION_VAR
6393 #else
6394 if (mbmi->motion_mode == OBMC_CAUSAL) {
6395 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
6396 } else if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT &&
6397 dry_run == OUTPUT_ENABLED) {
6398 int p;
6399 for (p = 0; p < MAX_MB_PLANE; ++p) {
6400 get_pred_from_intrpl_buf(xd, mi_row, mi_col, block_size, p);
6401 }
6402 }
6403 #endif
6404
6405 av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
6406 #if CONFIG_VAR_TX
6407 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
6408 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size,
6409 rate);
6410 #else
6411 #if CONFIG_LV_MAP
6412 av1_update_txb_context(cpi, td, dry_run, block_size, rate, mi_row, mi_col);
6413 #else // CONFIG_LV_MAP
6414 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
6415 #endif // CONFIG_LV_MAP
6416 #endif
6417 }
6418
6419 #if CONFIG_DIST_8X8 && CONFIG_CB4X4
6420 if (x->using_dist_8x8 && bsize < BLOCK_8X8) {
6421 dist_8x8_set_sub8x8_dst(x, (uint8_t *)x->decoded_8x8, bsize,
6422 block_size_wide[bsize], block_size_high[bsize],
6423 mi_row, mi_col);
6424 }
6425 #endif
6426
6427 if (!dry_run) {
6428 #if CONFIG_VAR_TX
6429 TX_SIZE tx_size =
6430 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
6431 #else
6432 TX_SIZE tx_size = mbmi->tx_size;
6433 #endif
6434 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id] &&
6435 #if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX
6436 mbmi->sb_type > BLOCK_4X4 &&
6437 #else
6438 mbmi->sb_type >= BLOCK_8X8 &&
6439 #endif
6440 !(is_inter && (mbmi->skip || seg_skip))) {
6441 #if CONFIG_VAR_TX
6442 if (is_inter) {
6443 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
6444 } else {
6445 const int tx_size_ctx = get_tx_size_context(xd);
6446 const int32_t tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
6447 : intra_tx_size_cat_lookup[bsize];
6448 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
6449 const int depth = tx_size_to_depth(coded_tx_size);
6450 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
6451 if (tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
6452 }
6453 #else
6454 const int tx_size_ctx = get_tx_size_context(xd);
6455 const int32_t tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
6456 : intra_tx_size_cat_lookup[bsize];
6457 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
6458 const int depth = tx_size_to_depth(coded_tx_size);
6459
6460 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
6461 #endif
6462
6463 #if CONFIG_RECT_TX_EXT && (CONFIG_EXT_TX || CONFIG_VAR_TX)
6464 if (is_quarter_tx_allowed(xd, mbmi, is_inter) &&
6465 quarter_txsize_lookup[bsize] != max_txsize_rect_lookup[bsize] &&
6466 (mbmi->tx_size == quarter_txsize_lookup[bsize] ||
6467 mbmi->tx_size == max_txsize_rect_lookup[bsize])) {
6468 ++td->counts
6469 ->quarter_tx_size[mbmi->tx_size == quarter_txsize_lookup[bsize]];
6470 }
6471 #endif
6472 #if CONFIG_EXT_TX && CONFIG_RECT_TX
6473 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
6474 #endif // CONFIG_EXT_TX && CONFIG_RECT_TX
6475 } else {
6476 int i, j;
6477 TX_SIZE intra_tx_size;
6478 // The new intra coding scheme requires no change of transform size
6479 if (is_inter) {
6480 if (xd->lossless[mbmi->segment_id]) {
6481 intra_tx_size = TX_4X4;
6482 } else {
6483 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
6484 }
6485 } else {
6486 #if CONFIG_EXT_TX && CONFIG_RECT_TX
6487 intra_tx_size = tx_size;
6488 #else
6489 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
6490 #endif // CONFIG_EXT_TX && CONFIG_RECT_TX
6491 }
6492 #if CONFIG_EXT_TX && CONFIG_RECT_TX
6493 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
6494 [txsize_sqr_up_map[tx_size]];
6495 #endif // CONFIG_EXT_TX && CONFIG_RECT_TX
6496
6497 for (j = 0; j < mi_height; j++)
6498 for (i = 0; i < mi_width; i++)
6499 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
6500 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
6501
6502 #if CONFIG_VAR_TX
6503 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
6504 if (intra_tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
6505 #endif
6506 }
6507
6508 #if !CONFIG_TXK_SEL
6509 av1_update_tx_type_count(cm, xd, bsize, tx_size, td->counts);
6510 #endif
6511 }
6512
6513 #if CONFIG_VAR_TX
6514 if (cm->tx_mode == TX_MODE_SELECT &&
6515 #if CONFIG_CB4X4
6516 mbmi->sb_type > BLOCK_4X4 &&
6517 #else
6518 mbmi->sb_type >= BLOCK_8X8 &&
6519 #endif
6520 is_inter && !(mbmi->skip || seg_skip) &&
6521 !xd->lossless[mbmi->segment_id]) {
6522 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
6523 } else {
6524 TX_SIZE tx_size = mbmi->tx_size;
6525 // The new intra coding scheme requires no change of transform size
6526 if (is_inter) {
6527 if (xd->lossless[mbmi->segment_id]) {
6528 tx_size = TX_4X4;
6529 } else {
6530 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
6531 }
6532 } else {
6533 tx_size = (bsize > BLOCK_4X4) ? tx_size : TX_4X4;
6534 }
6535 mbmi->tx_size = tx_size;
6536 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
6537 }
6538 #endif // CONFIG_VAR_TX
6539 #if CONFIG_CFL && CONFIG_CHROMA_SUB8X8
6540 CFL_CTX *const cfl = xd->cfl;
6541 #if CONFIG_DEBUG
6542 if (is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
6543 cfl->subsampling_y) &&
6544 !cfl->are_parameters_computed) {
6545 cfl_clear_sub8x8_val(cfl);
6546 }
6547 #endif // CONFIG_DEBUG
6548 if (is_inter_block(mbmi) &&
6549 !is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
6550 cfl->subsampling_y)) {
6551 cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
6552 }
6553 #endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8
6554 }
6555
6556 #if CONFIG_SUPERTX
check_intra_b(PICK_MODE_CONTEXT * ctx)6557 static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
6558 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
6559 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
6560 return 0;
6561 }
6562
check_intra_sb(const AV1_COMP * const cpi,const TileInfo * const tile,int mi_row,int mi_col,BLOCK_SIZE bsize,PC_TREE * pc_tree)6563 static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
6564 int mi_row, int mi_col, BLOCK_SIZE bsize,
6565 PC_TREE *pc_tree) {
6566 const AV1_COMMON *const cm = &cpi->common;
6567 const int hbs = mi_size_wide[bsize] / 2;
6568 const PARTITION_TYPE partition = pc_tree->partitioning;
6569 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
6570 #if CONFIG_EXT_PARTITION_TYPES
6571 int i;
6572 #endif
6573 #if CONFIG_CB4X4
6574 const int unify_bsize = 1;
6575 #else
6576 const int unify_bsize = 0;
6577 #endif
6578
6579 #if !CONFIG_CB4X4
6580 assert(bsize >= BLOCK_8X8);
6581 #endif
6582
6583 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
6584
6585 switch (partition) {
6586 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
6587 case PARTITION_VERT:
6588 if (check_intra_b(&pc_tree->vertical[0])) return 1;
6589 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
6590 if (check_intra_b(&pc_tree->vertical[1])) return 1;
6591 }
6592 break;
6593 case PARTITION_HORZ:
6594 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
6595 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
6596 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
6597 }
6598 break;
6599 case PARTITION_SPLIT:
6600 if (bsize == BLOCK_8X8 && !unify_bsize) {
6601 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
6602 } else {
6603 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
6604 pc_tree->split[0]))
6605 return 1;
6606 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
6607 pc_tree->split[1]))
6608 return 1;
6609 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
6610 pc_tree->split[2]))
6611 return 1;
6612 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
6613 pc_tree->split[3]))
6614 return 1;
6615 }
6616 break;
6617 #if CONFIG_EXT_PARTITION_TYPES
6618 #if CONFIG_EXT_PARTITION_TYPES_AB
6619 #error HORZ/VERT_A/B partitions not yet updated in superres code
6620 #endif
6621 case PARTITION_HORZ_A:
6622 for (i = 0; i < 3; i++) {
6623 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
6624 }
6625 break;
6626 case PARTITION_HORZ_B:
6627 for (i = 0; i < 3; i++) {
6628 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
6629 }
6630 break;
6631 case PARTITION_VERT_A:
6632 for (i = 0; i < 3; i++) {
6633 if (check_intra_b(&pc_tree->verticala[i])) return 1;
6634 }
6635 break;
6636 case PARTITION_VERT_B:
6637 for (i = 0; i < 3; i++) {
6638 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
6639 }
6640 break;
6641 #endif // CONFIG_EXT_PARTITION_TYPES
6642 default: assert(0);
6643 }
6644 return 0;
6645 }
6646
check_supertx_b(TX_SIZE supertx_size,PICK_MODE_CONTEXT * ctx)6647 static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
6648 return ctx->mic.mbmi.tx_size == supertx_size;
6649 }
6650
check_supertx_sb(BLOCK_SIZE bsize,TX_SIZE supertx_size,PC_TREE * pc_tree)6651 static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
6652 PC_TREE *pc_tree) {
6653 PARTITION_TYPE partition;
6654 BLOCK_SIZE subsize;
6655 #if CONFIG_CB4X4
6656 const int unify_bsize = 1;
6657 #else
6658 const int unify_bsize = 0;
6659 #endif
6660
6661 partition = pc_tree->partitioning;
6662 subsize = get_subsize(bsize, partition);
6663 switch (partition) {
6664 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
6665 case PARTITION_VERT:
6666 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
6667 case PARTITION_HORZ:
6668 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
6669 case PARTITION_SPLIT:
6670 if (bsize == BLOCK_8X8 && !unify_bsize)
6671 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
6672 else
6673 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
6674 #if CONFIG_EXT_PARTITION_TYPES
6675 #if CONFIG_EXT_PARTITION_TYPES_AB
6676 #error HORZ/VERT_A/B partitions not yet updated in superres code
6677 #endif
6678 case PARTITION_HORZ_A:
6679 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
6680 case PARTITION_HORZ_B:
6681 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
6682 case PARTITION_VERT_A:
6683 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
6684 case PARTITION_VERT_B:
6685 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
6686 #endif // CONFIG_EXT_PARTITION_TYPES
6687 default: assert(0); return 0;
6688 }
6689 }
6690
predict_superblock(const AV1_COMP * const cpi,ThreadData * td,int mi_row_ori,int mi_col_ori,int mi_row_pred,int mi_col_pred,int plane,BLOCK_SIZE bsize_pred,int b_sub8x8,int block)6691 static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
6692 int mi_row_ori, int mi_col_ori, int mi_row_pred,
6693 int mi_col_pred, int plane,
6694 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
6695 // Used in supertx
6696 // (mi_row_ori, mi_col_ori): location for mv
6697 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
6698 const AV1_COMMON *const cm = &cpi->common;
6699 MACROBLOCK *const x = &td->mb;
6700 MACROBLOCKD *const xd = &x->e_mbd;
6701 MODE_INFO *mi_8x8 = xd->mi[0];
6702 MODE_INFO *mi = mi_8x8;
6703 MB_MODE_INFO *mbmi = &mi->mbmi;
6704 int ref;
6705 const int is_compound = has_second_ref(mbmi);
6706
6707 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
6708
6709 for (ref = 0; ref < 1 + is_compound; ++ref) {
6710 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
6711 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
6712 &xd->block_refs[ref]->sf);
6713 }
6714
6715 #if CONFIG_COMPOUND_SINGLEREF
6716 // Single ref compound mode
6717 if (!is_compound && is_inter_singleref_comp_mode(mbmi->mode)) {
6718 xd->block_refs[1] = xd->block_refs[0];
6719 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[0]);
6720 av1_setup_pre_planes(xd, 1, cfg, mi_row_pred, mi_col_pred,
6721 &xd->block_refs[1]->sf);
6722 }
6723 #endif // CONFIG_COMPOUND_SINGLEREF
6724
6725 if (!b_sub8x8)
6726 av1_build_inter_predictor_sb_extend(cm, xd, mi_row_ori, mi_col_ori,
6727 mi_row_pred, mi_col_pred, plane,
6728 bsize_pred);
6729 else
6730 av1_build_inter_predictor_sb_sub8x8_extend(cm, xd, mi_row_ori, mi_col_ori,
6731 mi_row_pred, mi_col_pred, plane,
6732 bsize_pred, block);
6733 }
6734
predict_b_extend(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int block,int mi_row_ori,int mi_col_ori,int mi_row_pred,int mi_col_pred,int mi_row_top,int mi_col_top,int plane,uint8_t * dst_buf,int dst_stride,BLOCK_SIZE bsize_top,BLOCK_SIZE bsize_pred,RUN_TYPE dry_run,int b_sub8x8)6735 static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
6736 const TileInfo *const tile, int block,
6737 int mi_row_ori, int mi_col_ori, int mi_row_pred,
6738 int mi_col_pred, int mi_row_top, int mi_col_top,
6739 int plane, uint8_t *dst_buf, int dst_stride,
6740 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
6741 RUN_TYPE dry_run, int b_sub8x8) {
6742 // Used in supertx
6743 // (mi_row_ori, mi_col_ori): location for mv
6744 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
6745 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
6746 // block: sub location of sub8x8 blocks
6747 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
6748 // bextend: 1: region to predict is an extension of ori; 0: not
6749
6750 MACROBLOCK *const x = &td->mb;
6751 const AV1_COMMON *const cm = &cpi->common;
6752 MACROBLOCKD *const xd = &x->e_mbd;
6753 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
6754 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
6755 const int mi_width_top = mi_size_wide[bsize_top];
6756 const int mi_height_top = mi_size_high[bsize_top];
6757
6758 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
6759 mi_row_pred >= mi_row_top + mi_height_top ||
6760 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
6761 mi_col_pred >= cm->mi_cols)
6762 return;
6763
6764 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
6765 mi_col_ori, bsize_pred);
6766 xd->plane[plane].dst.stride = dst_stride;
6767 xd->plane[plane].dst.buf =
6768 dst_buf + (r >> xd->plane[plane].subsampling_y) * dst_stride +
6769 (c >> xd->plane[plane].subsampling_x);
6770
6771 predict_superblock(cpi, td, mi_row_ori, mi_col_ori, mi_row_pred, mi_col_pred,
6772 plane, bsize_pred, b_sub8x8, block);
6773
6774 if (!dry_run && (plane == 0) && (block == 0 || !b_sub8x8))
6775 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
6776 }
6777
extend_dir(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int block,BLOCK_SIZE bsize,BLOCK_SIZE top_bsize,int mi_row_ori,int mi_col_ori,int mi_row,int mi_col,int mi_row_top,int mi_col_top,int plane,uint8_t * dst_buf,int dst_stride,int dir)6778 static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
6779 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6780 BLOCK_SIZE top_bsize, int mi_row_ori, int mi_col_ori,
6781 int mi_row, int mi_col, int mi_row_top, int mi_col_top,
6782 int plane, uint8_t *dst_buf, int dst_stride, int dir) {
6783 // dir: 0-lower, 1-upper, 2-left, 3-right
6784 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
6785 MACROBLOCKD *xd = &td->mb.e_mbd;
6786 const int mi_width = mi_size_wide[bsize];
6787 const int mi_height = mi_size_high[bsize];
6788 int xss = xd->plane[1].subsampling_x;
6789 int yss = xd->plane[1].subsampling_y;
6790 #if CONFIG_CB4X4
6791 const int unify_bsize = 1;
6792 #else
6793 const int unify_bsize = 0;
6794 #endif
6795 int b_sub8x8 = (bsize < BLOCK_8X8) && !unify_bsize ? 1 : 0;
6796 int wide_unit, high_unit;
6797 int i, j;
6798 int ext_offset = 0;
6799
6800 BLOCK_SIZE extend_bsize;
6801 int mi_row_pred, mi_col_pred;
6802
6803 if (dir == 0 || dir == 1) { // lower and upper
6804 extend_bsize =
6805 (mi_width == mi_size_wide[BLOCK_8X8] || bsize < BLOCK_8X8 || xss < yss)
6806 ? BLOCK_8X8
6807 : BLOCK_16X8;
6808
6809 #if CONFIG_CB4X4
6810 if (bsize < BLOCK_8X8) {
6811 extend_bsize = BLOCK_4X4;
6812 ext_offset = mi_size_wide[BLOCK_8X8];
6813 }
6814 #endif
6815 wide_unit = mi_size_wide[extend_bsize];
6816 high_unit = mi_size_high[extend_bsize];
6817
6818 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -(mi_height + ext_offset));
6819 mi_col_pred = mi_col;
6820
6821 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6822 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6823 predict_b_extend(cpi, td, tile, block, mi_row_ori, mi_col_ori,
6824 mi_row_pred + j, mi_col_pred + i, mi_row_top,
6825 mi_col_top, plane, dst_buf, dst_stride, top_bsize,
6826 extend_bsize, 1, b_sub8x8);
6827 } else if (dir == 2 || dir == 3) { // left and right
6828 extend_bsize =
6829 (mi_height == mi_size_high[BLOCK_8X8] || bsize < BLOCK_8X8 || yss < xss)
6830 ? BLOCK_8X8
6831 : BLOCK_8X16;
6832 #if CONFIG_CB4X4
6833 if (bsize < BLOCK_8X8) {
6834 extend_bsize = BLOCK_4X4;
6835 ext_offset = mi_size_wide[BLOCK_8X8];
6836 }
6837 #endif
6838 wide_unit = mi_size_wide[extend_bsize];
6839 high_unit = mi_size_high[extend_bsize];
6840
6841 mi_row_pred = mi_row;
6842 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -(mi_width + ext_offset));
6843
6844 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6845 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6846 predict_b_extend(cpi, td, tile, block, mi_row_ori, mi_col_ori,
6847 mi_row_pred + j, mi_col_pred + i, mi_row_top,
6848 mi_col_top, plane, dst_buf, dst_stride, top_bsize,
6849 extend_bsize, 1, b_sub8x8);
6850 } else {
6851 extend_bsize = BLOCK_8X8;
6852 #if CONFIG_CB4X4
6853 if (bsize < BLOCK_8X8) {
6854 extend_bsize = BLOCK_4X4;
6855 ext_offset = mi_size_wide[BLOCK_8X8];
6856 }
6857 #endif
6858 wide_unit = mi_size_wide[extend_bsize];
6859 high_unit = mi_size_high[extend_bsize];
6860
6861 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height
6862 : -(mi_height + ext_offset));
6863 mi_col_pred =
6864 mi_col + ((dir == 6 || dir == 7) ? mi_width : -(mi_width + ext_offset));
6865
6866 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6867 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6868 predict_b_extend(cpi, td, tile, block, mi_row_ori, mi_col_ori,
6869 mi_row_pred + j, mi_col_pred + i, mi_row_top,
6870 mi_col_top, plane, dst_buf, dst_stride, top_bsize,
6871 extend_bsize, 1, b_sub8x8);
6872 }
6873 }
6874
extend_all(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int block,BLOCK_SIZE bsize,BLOCK_SIZE top_bsize,int mi_row_ori,int mi_col_ori,int mi_row,int mi_col,int mi_row_top,int mi_col_top,int plane,uint8_t * dst_buf,int dst_stride)6875 static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
6876 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6877 BLOCK_SIZE top_bsize, int mi_row_ori, int mi_col_ori,
6878 int mi_row, int mi_col, int mi_row_top, int mi_col_top,
6879 int plane, uint8_t *dst_buf, int dst_stride) {
6880 assert(block >= 0 && block < 4);
6881 for (int i = 0; i < 8; ++i) {
6882 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row_ori, mi_col_ori,
6883 mi_row, mi_col, mi_row_top, mi_col_top, plane, dst_buf,
6884 dst_stride, i);
6885 }
6886 }
6887
6888 // This function generates prediction for multiple blocks, between which
6889 // discontinuity around boundary is reduced by smoothing masks. The basic
6890 // smoothing mask is a soft step function along horz/vert direction. In more
6891 // complicated case when a block is split into 4 subblocks, the basic mask is
6892 // first applied to neighboring subblocks (2 pairs) in horizontal direction and
6893 // then applied to the 2 masked prediction mentioned above in vertical direction
6894 // If the block is split into more than one level, at every stage, masked
6895 // prediction is stored in dst_buf[] passed from higher level.
predict_sb_complex(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int mi_row,int mi_col,int mi_row_top,int mi_col_top,RUN_TYPE dry_run,BLOCK_SIZE bsize,BLOCK_SIZE top_bsize,uint8_t * dst_buf[3],int dst_stride[3],PC_TREE * pc_tree)6896 static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
6897 const TileInfo *const tile, int mi_row,
6898 int mi_col, int mi_row_top, int mi_col_top,
6899 RUN_TYPE dry_run, BLOCK_SIZE bsize,
6900 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
6901 int dst_stride[3], PC_TREE *pc_tree) {
6902 const AV1_COMMON *const cm = &cpi->common;
6903 MACROBLOCK *const x = &td->mb;
6904 MACROBLOCKD *const xd = &x->e_mbd;
6905 const int hbs = mi_size_wide[bsize] / 2;
6906 const int is_partition_root = bsize >= BLOCK_8X8;
6907 const int ctx = is_partition_root
6908 ? partition_plane_context(xd, mi_row, mi_col,
6909 #if CONFIG_UNPOISON_PARTITION_CTX
6910 mi_row + hbs < cm->mi_rows,
6911 mi_col + hbs < cm->mi_cols,
6912 #endif
6913 bsize)
6914 : -1;
6915 const PARTITION_TYPE partition = pc_tree->partitioning;
6916 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
6917 #if CONFIG_EXT_PARTITION_TYPES
6918 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
6919 #endif
6920
6921 int i;
6922 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
6923 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6924 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6925 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6926 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6927 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6928 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6929 #if CONFIG_CB4X4
6930 const int unify_bsize = 1;
6931 #else
6932 const int unify_bsize = 0;
6933 assert(bsize >= BLOCK_8X8);
6934 #endif
6935
6936 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
6937
6938 #if CONFIG_HIGHBITDEPTH
6939 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6940 int len = sizeof(uint16_t);
6941 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6942 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
6943 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
6944 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6945 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
6946 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
6947 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
6948 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
6949 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
6950 } else {
6951 #endif // CONFIG_HIGHBITDEPTH
6952 dst_buf1[0] = tmp_buf1;
6953 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
6954 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
6955 dst_buf2[0] = tmp_buf2;
6956 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
6957 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
6958 dst_buf3[0] = tmp_buf3;
6959 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
6960 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
6961 #if CONFIG_HIGHBITDEPTH
6962 }
6963 #endif // CONFIG_HIGHBITDEPTH
6964
6965 if (!dry_run && ctx >= 0 && bsize < top_bsize) {
6966 // Explicitly cast away const.
6967 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6968 frame_counts->partition[ctx][partition]++;
6969 }
6970
6971 for (i = 0; i < MAX_MB_PLANE; i++) {
6972 xd->plane[i].dst.buf = dst_buf[i];
6973 xd->plane[i].dst.stride = dst_stride[i];
6974 }
6975
6976 switch (partition) {
6977 case PARTITION_NONE:
6978 assert(bsize < top_bsize);
6979 for (i = 0; i < MAX_MB_PLANE; ++i) {
6980 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6981 mi_row_top, mi_col_top, i, dst_buf[i], dst_stride[i],
6982 top_bsize, bsize, dry_run, 0);
6983 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row,
6984 mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
6985 dst_stride[i]);
6986 }
6987 break;
6988 case PARTITION_HORZ:
6989 if (bsize == BLOCK_8X8 && !unify_bsize) {
6990 for (i = 0; i < MAX_MB_PLANE; ++i) {
6991 // First half
6992 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6993 mi_row_top, mi_col_top, i, dst_buf[i], dst_stride[i],
6994 top_bsize, BLOCK_8X8, dry_run, 1);
6995 if (bsize < top_bsize)
6996 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
6997 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
6998 dst_stride[i]);
6999
7000 // Second half
7001 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
7002 mi_row_top, mi_col_top, i, dst_buf1[i],
7003 dst_stride1[i], top_bsize, BLOCK_8X8, dry_run, 1);
7004 if (bsize < top_bsize)
7005 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
7006 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf1[i],
7007 dst_stride1[i]);
7008 }
7009
7010 // Smooth
7011 xd->plane[0].dst.buf = dst_buf[0];
7012 xd->plane[0].dst.stride = dst_stride[0];
7013 av1_build_masked_inter_predictor_complex(
7014 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
7015 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
7016 0);
7017 } else {
7018 for (i = 0; i < MAX_MB_PLANE; ++i) {
7019 #if CONFIG_CB4X4
7020 const struct macroblockd_plane *pd = &xd->plane[i];
7021 int handle_chroma_sub8x8 = need_handle_chroma_sub8x8(
7022 subsize, pd->subsampling_x, pd->subsampling_y);
7023
7024 if (handle_chroma_sub8x8) {
7025 int mode_offset_row = CONFIG_CHROMA_SUB8X8 ? hbs : 0;
7026
7027 predict_b_extend(cpi, td, tile, 0, mi_row + mode_offset_row, mi_col,
7028 mi_row, mi_col, mi_row_top, mi_col_top, i,
7029 dst_buf[i], dst_stride[i], top_bsize, bsize,
7030 dry_run, 0);
7031 if (bsize < top_bsize)
7032 extend_all(cpi, td, tile, 0, bsize, top_bsize,
7033 mi_row + mode_offset_row, mi_col, mi_row, mi_col,
7034 mi_row_top, mi_col_top, i, dst_buf[i], dst_stride[i]);
7035 } else {
7036 #endif
7037 // First half
7038 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7039 mi_row_top, mi_col_top, i, dst_buf[i],
7040 dst_stride[i], top_bsize, subsize, dry_run, 0);
7041 if (bsize < top_bsize)
7042 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7043 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7044 dst_stride[i]);
7045 else
7046 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7047 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7048 dst_stride[i], 0);
7049 xd->plane[i].dst.buf = dst_buf[i];
7050 xd->plane[i].dst.stride = dst_stride[i];
7051
7052 if (mi_row + hbs < cm->mi_rows) {
7053 // Second half
7054 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col,
7055 mi_row + hbs, mi_col, mi_row_top, mi_col_top, i,
7056 dst_buf1[i], dst_stride1[i], top_bsize, subsize,
7057 dry_run, 0);
7058 if (bsize < top_bsize)
7059 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
7060 mi_col, mi_row + hbs, mi_col, mi_row_top, mi_col_top,
7061 i, dst_buf1[i], dst_stride1[i]);
7062 else
7063 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
7064 mi_col, mi_row + hbs, mi_col, mi_row_top, mi_col_top,
7065 i, dst_buf1[i], dst_stride1[i], 1);
7066 // Smooth
7067 xd->plane[i].dst.buf = dst_buf[i];
7068 xd->plane[i].dst.stride = dst_stride[i];
7069 av1_build_masked_inter_predictor_complex(
7070 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
7071 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7072 PARTITION_HORZ, i);
7073 }
7074 #if CONFIG_CB4X4
7075 }
7076 #endif
7077 }
7078 }
7079 break;
7080 case PARTITION_VERT:
7081 if (bsize == BLOCK_8X8 && !unify_bsize) {
7082 for (i = 0; i < MAX_MB_PLANE; ++i) {
7083 // First half
7084 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7085 mi_row_top, mi_col_top, i, dst_buf[i], dst_stride[i],
7086 top_bsize, BLOCK_8X8, dry_run, 1);
7087 if (bsize < top_bsize)
7088 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7089 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7090 dst_stride[i]);
7091
7092 // Second half
7093 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
7094 mi_row_top, mi_col_top, i, dst_buf1[i],
7095 dst_stride1[i], top_bsize, BLOCK_8X8, dry_run, 1);
7096 if (bsize < top_bsize)
7097 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
7098 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf1[i],
7099 dst_stride1[i]);
7100 }
7101
7102 // Smooth
7103 xd->plane[0].dst.buf = dst_buf[0];
7104 xd->plane[0].dst.stride = dst_stride[0];
7105 av1_build_masked_inter_predictor_complex(
7106 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
7107 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
7108 0);
7109 } else {
7110 for (i = 0; i < MAX_MB_PLANE; ++i) {
7111 #if CONFIG_CB4X4
7112 const struct macroblockd_plane *pd = &xd->plane[i];
7113 int handle_chroma_sub8x8 = need_handle_chroma_sub8x8(
7114 subsize, pd->subsampling_x, pd->subsampling_y);
7115
7116 if (handle_chroma_sub8x8) {
7117 int mode_offset_col = CONFIG_CHROMA_SUB8X8 ? hbs : 0;
7118
7119 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + mode_offset_col,
7120 mi_row, mi_col, mi_row_top, mi_col_top, i,
7121 dst_buf[i], dst_stride[i], top_bsize, bsize,
7122 dry_run, 0);
7123 if (bsize < top_bsize)
7124 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row,
7125 mi_col + mode_offset_col, mi_row, mi_col, mi_row_top,
7126 mi_col_top, i, dst_buf[i], dst_stride[i]);
7127 } else {
7128 #endif
7129 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7130 mi_row_top, mi_col_top, i, dst_buf[i],
7131 dst_stride[i], top_bsize, subsize, dry_run, 0);
7132 if (bsize < top_bsize)
7133 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7134 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7135 dst_stride[i]);
7136 else
7137 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7138 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7139 dst_stride[i], 3);
7140 xd->plane[i].dst.buf = dst_buf[i];
7141 xd->plane[i].dst.stride = dst_stride[i];
7142
7143 if (mi_col + hbs < cm->mi_cols) {
7144 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
7145 mi_col + hbs, mi_row_top, mi_col_top, i,
7146 dst_buf1[i], dst_stride1[i], top_bsize, subsize,
7147 dry_run, 0);
7148 if (bsize < top_bsize)
7149 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
7150 mi_col + hbs, mi_row, mi_col + hbs, mi_row_top,
7151 mi_col_top, i, dst_buf1[i], dst_stride1[i]);
7152 else
7153 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
7154 mi_col + hbs, mi_row, mi_col + hbs, mi_row_top,
7155 mi_col_top, i, dst_buf1[i], dst_stride1[i], 2);
7156
7157 // smooth
7158 xd->plane[i].dst.buf = dst_buf[i];
7159 xd->plane[i].dst.stride = dst_stride[i];
7160 av1_build_masked_inter_predictor_complex(
7161 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
7162 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7163 PARTITION_VERT, i);
7164 }
7165 #if CONFIG_CB4X4
7166 }
7167 #endif
7168 }
7169 }
7170 break;
7171 case PARTITION_SPLIT:
7172 if (bsize == BLOCK_8X8 && !unify_bsize) {
7173 for (i = 0; i < MAX_MB_PLANE; i++) {
7174 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7175 mi_row_top, mi_col_top, i, dst_buf[i], dst_stride[i],
7176 top_bsize, BLOCK_8X8, dry_run, 1);
7177 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
7178 mi_row_top, mi_col_top, i, dst_buf1[i],
7179 dst_stride1[i], top_bsize, BLOCK_8X8, dry_run, 1);
7180 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
7181 mi_row_top, mi_col_top, i, dst_buf2[i],
7182 dst_stride2[i], top_bsize, BLOCK_8X8, dry_run, 1);
7183 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
7184 mi_row_top, mi_col_top, i, dst_buf3[i],
7185 dst_stride3[i], top_bsize, BLOCK_8X8, dry_run, 1);
7186
7187 if (bsize < top_bsize) {
7188 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7189 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7190 dst_stride[i]);
7191 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
7192 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf1[i],
7193 dst_stride1[i]);
7194 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
7195 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf2[i],
7196 dst_stride2[i]);
7197 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
7198 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf3[i],
7199 dst_stride3[i]);
7200 }
7201 }
7202 #if CONFIG_CB4X4
7203 } else if (bsize == BLOCK_8X8) {
7204 for (i = 0; i < MAX_MB_PLANE; i++) {
7205 const struct macroblockd_plane *pd = &xd->plane[i];
7206 int handle_chroma_sub8x8 = need_handle_chroma_sub8x8(
7207 subsize, pd->subsampling_x, pd->subsampling_y);
7208
7209 if (handle_chroma_sub8x8) {
7210 int mode_offset_row =
7211 CONFIG_CHROMA_SUB8X8 && mi_row + hbs < cm->mi_rows ? hbs : 0;
7212 int mode_offset_col =
7213 CONFIG_CHROMA_SUB8X8 && mi_col + hbs < cm->mi_cols ? hbs : 0;
7214
7215 predict_b_extend(cpi, td, tile, 0, mi_row + mode_offset_row,
7216 mi_col + mode_offset_col, mi_row, mi_col,
7217 mi_row_top, mi_col_top, i, dst_buf[i],
7218 dst_stride[i], top_bsize, BLOCK_8X8, dry_run, 0);
7219 if (bsize < top_bsize)
7220 extend_all(cpi, td, tile, 0, BLOCK_8X8, top_bsize,
7221 mi_row + mode_offset_row, mi_col + mode_offset_col,
7222 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7223 dst_stride[i]);
7224 } else {
7225 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7226 mi_row_top, mi_col_top, i, dst_buf[i],
7227 dst_stride[i], top_bsize, subsize, dry_run, 0);
7228 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7229 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
7230 mi_col + hbs, mi_row_top, mi_col_top, i,
7231 dst_buf1[i], dst_stride1[i], top_bsize, subsize,
7232 dry_run, 0);
7233 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
7234 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col,
7235 mi_row + hbs, mi_col, mi_row_top, mi_col_top, i,
7236 dst_buf2[i], dst_stride2[i], top_bsize, subsize,
7237 dry_run, 0);
7238 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7239 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
7240 mi_row + hbs, mi_col + hbs, mi_row_top,
7241 mi_col_top, i, dst_buf3[i], dst_stride3[i],
7242 top_bsize, subsize, dry_run, 0);
7243
7244 if (bsize < top_bsize) {
7245 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7246 mi_row, mi_col, mi_row_top, mi_col_top, i, dst_buf[i],
7247 dst_stride[i]);
7248 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7249 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
7250 mi_col + hbs, mi_row, mi_col + hbs, mi_row_top,
7251 mi_col_top, i, dst_buf1[i], dst_stride1[i]);
7252 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
7253 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
7254 mi_col, mi_row + hbs, mi_col, mi_row_top, mi_col_top,
7255 i, dst_buf2[i], dst_stride2[i]);
7256 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7257 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
7258 mi_col + hbs, mi_row + hbs, mi_col + hbs, mi_row_top,
7259 mi_col_top, i, dst_buf3[i], dst_stride3[i]);
7260 }
7261 }
7262 }
7263 #endif
7264 } else {
7265 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
7266 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
7267 dst_stride, pc_tree->split[0]);
7268 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7269 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
7270 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
7271 dst_stride1, pc_tree->split[1]);
7272 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
7273 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
7274 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
7275 dst_stride2, pc_tree->split[2]);
7276 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
7277 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
7278 mi_row_top, mi_col_top, dry_run, subsize,
7279 top_bsize, dst_buf3, dst_stride3,
7280 pc_tree->split[3]);
7281 }
7282 for (i = 0; i < MAX_MB_PLANE; i++) {
7283 #if CONFIG_CB4X4
7284 const struct macroblockd_plane *pd = &xd->plane[i];
7285 int handle_chroma_sub8x8 = need_handle_chroma_sub8x8(
7286 subsize, pd->subsampling_x, pd->subsampling_y);
7287 if (handle_chroma_sub8x8) continue; // Skip <4x4 chroma smoothing
7288 #else
7289 if (bsize == BLOCK_8X8 && i != 0)
7290 continue; // Skip <4x4 chroma smoothing
7291 #endif
7292
7293 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
7294 av1_build_masked_inter_predictor_complex(
7295 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
7296 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7297 PARTITION_VERT, i);
7298 if (mi_row + hbs < cm->mi_rows) {
7299 av1_build_masked_inter_predictor_complex(
7300 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
7301 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7302 PARTITION_VERT, i);
7303 av1_build_masked_inter_predictor_complex(
7304 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
7305 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7306 PARTITION_HORZ, i);
7307 }
7308 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
7309 av1_build_masked_inter_predictor_complex(
7310 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
7311 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7312 PARTITION_HORZ, i);
7313 }
7314 }
7315 break;
7316 #if CONFIG_EXT_PARTITION_TYPES
7317 #if CONFIG_EXT_PARTITION_TYPES_AB
7318 #error HORZ/VERT_A/B partitions not yet updated in superres code
7319 #endif
7320 case PARTITION_HORZ_A:
7321 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7322 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
7323 bsize2, dry_run, 0, 0);
7324 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
7325 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
7326
7327 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
7328 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
7329 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
7330 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
7331 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
7332
7333 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
7334 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
7335 top_bsize, subsize, dry_run, 0, 0);
7336 if (bsize < top_bsize)
7337 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
7338 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
7339 else
7340 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
7341 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
7342
7343 for (i = 0; i < MAX_MB_PLANE; i++) {
7344 xd->plane[i].dst.buf = dst_buf[i];
7345 xd->plane[i].dst.stride = dst_stride[i];
7346 av1_build_masked_inter_predictor_complex(
7347 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
7348 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
7349 i);
7350 }
7351 for (i = 0; i < MAX_MB_PLANE; i++) {
7352 av1_build_masked_inter_predictor_complex(
7353 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
7354 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
7355 i);
7356 }
7357
7358 break;
7359 case PARTITION_VERT_A:
7360
7361 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7362 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
7363 bsize2, dry_run, 0, 0);
7364 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
7365 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
7366
7367 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
7368 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
7369 top_bsize, bsize2, dry_run, 0, 0);
7370 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
7371 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
7372
7373 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
7374 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
7375 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
7376 if (bsize < top_bsize)
7377 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
7378 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
7379 else
7380 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
7381 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
7382
7383 for (i = 0; i < MAX_MB_PLANE; i++) {
7384 xd->plane[i].dst.buf = dst_buf[i];
7385 xd->plane[i].dst.stride = dst_stride[i];
7386 av1_build_masked_inter_predictor_complex(
7387 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
7388 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
7389 i);
7390 }
7391 for (i = 0; i < MAX_MB_PLANE; i++) {
7392 av1_build_masked_inter_predictor_complex(
7393 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
7394 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
7395 i);
7396 }
7397 break;
7398 case PARTITION_HORZ_B:
7399
7400 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7401 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
7402 subsize, dry_run, 0, 0);
7403 if (bsize < top_bsize)
7404 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7405 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
7406 else
7407 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7408 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
7409
7410 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
7411 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
7412 top_bsize, bsize2, dry_run, 0, 0);
7413 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
7414 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
7415
7416 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
7417 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
7418 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
7419 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
7420 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
7421 dst_stride2);
7422
7423 for (i = 0; i < MAX_MB_PLANE; i++) {
7424 xd->plane[i].dst.buf = dst_buf1[i];
7425 xd->plane[i].dst.stride = dst_stride1[i];
7426 av1_build_masked_inter_predictor_complex(
7427 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
7428 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7429 PARTITION_VERT, i);
7430 }
7431 for (i = 0; i < MAX_MB_PLANE; i++) {
7432 xd->plane[i].dst.buf = dst_buf[i];
7433 xd->plane[i].dst.stride = dst_stride[i];
7434 av1_build_masked_inter_predictor_complex(
7435 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
7436 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
7437 i);
7438 }
7439 break;
7440 case PARTITION_VERT_B:
7441
7442 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
7443 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
7444 subsize, dry_run, 0, 0);
7445 if (bsize < top_bsize)
7446 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7447 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
7448 else
7449 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
7450 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
7451
7452 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
7453 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
7454 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
7455 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
7456 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
7457
7458 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
7459 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
7460 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
7461 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
7462 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
7463 dst_stride2);
7464
7465 for (i = 0; i < MAX_MB_PLANE; i++) {
7466 xd->plane[i].dst.buf = dst_buf1[i];
7467 xd->plane[i].dst.stride = dst_stride1[i];
7468 av1_build_masked_inter_predictor_complex(
7469 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
7470 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
7471 PARTITION_HORZ, i);
7472 }
7473 for (i = 0; i < MAX_MB_PLANE; i++) {
7474 xd->plane[i].dst.buf = dst_buf[i];
7475 xd->plane[i].dst.stride = dst_stride[i];
7476 av1_build_masked_inter_predictor_complex(
7477 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
7478 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
7479 i);
7480 }
7481 break;
7482 #endif // CONFIG_EXT_PARTITION_TYPES
7483 default: assert(0);
7484 }
7485
7486 #if CONFIG_EXT_PARTITION_TYPES
7487 if (bsize < top_bsize)
7488 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
7489 #else
7490 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
7491 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
7492 #endif // CONFIG_EXT_PARTITION_TYPES
7493 }
7494
rd_supertx_sb(const AV1_COMP * const cpi,ThreadData * td,const TileInfo * const tile,int mi_row,int mi_col,BLOCK_SIZE bsize,int * tmp_rate,int64_t * tmp_dist,TX_TYPE * best_tx,PC_TREE * pc_tree)7495 static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
7496 const TileInfo *const tile, int mi_row, int mi_col,
7497 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
7498 TX_TYPE *best_tx, PC_TREE *pc_tree) {
7499 const AV1_COMMON *const cm = &cpi->common;
7500 MACROBLOCK *const x = &td->mb;
7501 MACROBLOCKD *const xd = &x->e_mbd;
7502 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
7503 base_rate = *tmp_rate;
7504 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
7505 uint8_t *dst_buf[3];
7506 int dst_stride[3];
7507 TX_SIZE tx_size;
7508 MB_MODE_INFO *mbmi;
7509 TX_TYPE tx_type, best_tx_nostx;
7510 int tmp_rate_tx = 0, skip_tx = 0;
7511 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
7512
7513 set_skip_context(xd, mi_row, mi_col);
7514 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
7515 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
7516 av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
7517 mi_col);
7518 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
7519 dst_buf[plane] = xd->plane[plane].dst.buf;
7520 dst_stride[plane] = xd->plane[plane].dst.stride;
7521 }
7522 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
7523 bsize, dst_buf, dst_stride, pc_tree);
7524
7525 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
7526 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
7527
7528 mbmi = &xd->mi[0]->mbmi;
7529 best_tx_nostx = mbmi->tx_type;
7530
7531 *best_tx = DCT_DCT;
7532
7533 // chroma
7534 skippable_uv = 1;
7535 rate_uv = 0;
7536 dist_uv = 0;
7537 sse_uv = 0;
7538 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
7539 #if CONFIG_VAR_TX
7540 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
7541 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
7542 const struct macroblockd_plane *const pd = &xd->plane[plane];
7543 RD_STATS this_rd_stats;
7544 av1_init_rd_stats(&this_rd_stats);
7545
7546 tx_size = max_txsize_lookup[bsize];
7547 tx_size =
7548 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
7549 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
7550
7551 av1_subtract_plane(x, bsize, plane);
7552 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
7553 get_plane_block_size(bsize, pd), &ctxa[0], &ctxl[0],
7554 &this_rd_stats);
7555
7556 this_rate = this_rd_stats.rate;
7557 this_dist = this_rd_stats.dist;
7558 pnsse = this_rd_stats.sse;
7559 pnskip = this_rd_stats.skip;
7560 #else
7561 tx_size = max_txsize_lookup[bsize];
7562 tx_size =
7563 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
7564 av1_subtract_plane(x, bsize, plane);
7565 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
7566 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
7567 #endif // CONFIG_VAR_TX
7568
7569 rate_uv += this_rate;
7570 dist_uv += this_dist;
7571 sse_uv += pnsse;
7572 skippable_uv &= pnskip;
7573 }
7574
7575 // luma
7576 tx_size = max_txsize_lookup[bsize];
7577 av1_subtract_plane(x, bsize, 0);
7578 #if CONFIG_EXT_TX
7579 int ext_tx_set = get_ext_tx_set(tx_size, bsize, 1, cm->reduced_tx_set_used);
7580 const TxSetType tx_set_type =
7581 get_ext_tx_set_type(tx_size, bsize, 1, cm->reduced_tx_set_used);
7582 #endif // CONFIG_EXT_TX
7583 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
7584 #if CONFIG_VAR_TX
7585 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
7586 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
7587 const struct macroblockd_plane *const pd = &xd->plane[0];
7588 RD_STATS this_rd_stats;
7589 #endif // CONFIG_VAR_TX
7590
7591 #if CONFIG_EXT_TX
7592 if (!av1_ext_tx_used[tx_set_type][tx_type]) continue;
7593 #else
7594 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
7595 #endif // CONFIG_EXT_TX
7596 mbmi->tx_type = tx_type;
7597
7598 #if CONFIG_VAR_TX
7599 av1_init_rd_stats(&this_rd_stats);
7600 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
7601 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, &ctxa[0], &ctxl[0],
7602 &this_rd_stats);
7603
7604 this_rate = this_rd_stats.rate;
7605 this_dist = this_rd_stats.dist;
7606 pnsse = this_rd_stats.sse;
7607 pnskip = this_rd_stats.skip;
7608 #else
7609 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
7610 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
7611 #endif // CONFIG_VAR_TX
7612
7613 #if CONFIG_EXT_TX
7614 if (get_ext_tx_types(tx_size, bsize, 1, cm->reduced_tx_set_used) > 1 &&
7615 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
7616 if (ext_tx_set > 0)
7617 this_rate +=
7618 x->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
7619 }
7620 #else
7621 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
7622 this_rate != INT_MAX) {
7623 this_rate += x->inter_tx_type_costs[tx_size][mbmi->tx_type];
7624 }
7625 #endif // CONFIG_EXT_TX
7626 *tmp_rate = rate_uv + this_rate;
7627 *tmp_dist = dist_uv + this_dist;
7628 sse = sse_uv + pnsse;
7629 skippable = skippable_uv && pnskip;
7630 if (skippable) {
7631 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7632 x->skip = 1;
7633 } else {
7634 if (RDCOST(x->rdmult, *tmp_rate, *tmp_dist) < RDCOST(x->rdmult, 0, sse)) {
7635 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
7636 x->skip = 0;
7637 } else {
7638 *tmp_dist = sse;
7639 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
7640 x->skip = 1;
7641 }
7642 }
7643 *tmp_rate += base_rate;
7644 rd_tx = RDCOST(x->rdmult, *tmp_rate, *tmp_dist);
7645 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
7646 *best_tx = tx_type;
7647 bestrd_tx = rd_tx;
7648 tmp_rate_tx = *tmp_rate;
7649 tmp_dist_tx = *tmp_dist;
7650 skip_tx = x->skip;
7651 }
7652 }
7653 *tmp_rate = tmp_rate_tx;
7654 *tmp_dist = tmp_dist_tx;
7655 x->skip = skip_tx;
7656 #if CONFIG_VAR_TX
7657 for (plane = 0; plane < 1; ++plane)
7658 memset(x->blk_skip[plane], x->skip,
7659 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
7660 #endif // CONFIG_VAR_TX
7661 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
7662 }
7663 #endif // CONFIG_SUPERTX
7664