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