blob: 2331bd474b789dc9f3ef61f07cc55d98a3f85bd0 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./av1_rtcd.h"
17#include "./aom_dsp_rtcd.h"
18#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "aom_ports/system_state.h"
24
25#include "av1/common/common.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconintra.h"
33#include "av1/common/reconinter.h"
34#include "av1/common/seg_common.h"
35#include "av1/common/tile_common.h"
36
37#include "av1/encoder/aq_complexity.h"
38#include "av1/encoder/aq_cyclicrefresh.h"
39#include "av1/encoder/aq_variance.h"
40#if CONFIG_SUPERTX
41#include "av1/encoder/cost.h"
42#endif
Yue Chen69f18e12016-09-08 14:48:15 -070043#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -070044#include "av1/common/warped_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070045#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
46#if CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/encoder/global_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070048#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070049#include "av1/encoder/encodeframe.h"
50#include "av1/encoder/encodemb.h"
51#include "av1/encoder/encodemv.h"
52#include "av1/encoder/ethread.h"
53#include "av1/encoder/extend.h"
54#include "av1/encoder/rd.h"
55#include "av1/encoder/rdopt.h"
56#include "av1/encoder/segmentation.h"
57#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070058#if CONFIG_PVQ
Yushin Cho70669122016-12-08 09:53:14 -100059#include "av1/common/pvq.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070060#include "av1/encoder/pvq_encoder.h"
61#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070062#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070063#define IF_HBD(...) __VA_ARGS__
64#else
65#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070066#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070067
Urvang Joshi52648442016-10-13 17:27:51 -070068static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
69 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
70 int mi_col, BLOCK_SIZE bsize,
71 PICK_MODE_CONTEXT *ctx, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070072
73#if CONFIG_SUPERTX
74static int check_intra_b(PICK_MODE_CONTEXT *ctx);
75
Urvang Joshi52648442016-10-13 17:27:51 -070076static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
77 int mi_row, int mi_col, BLOCK_SIZE bsize,
78 PC_TREE *pc_tree);
79static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070080#if CONFIG_EXT_INTER
81 int mi_row_ori, int mi_col_ori,
82#endif // CONFIG_EXT_INTER
83 int mi_row_pred, int mi_col_pred,
84 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
85static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
86 PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070087static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 const TileInfo *const tile, int mi_row,
89 int mi_col, int mi_row_ori, int mi_col_ori,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070090 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
92 int dst_stride[3], PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070093static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070094 const TileInfo *const tile, int mi_row,
95 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070096 RUN_TYPE dry_run, PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070097static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070098 const TileInfo *const tile, int mi_row, int mi_col,
99 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
100 TX_TYPE *best_tx, PC_TREE *pc_tree);
101#endif // CONFIG_SUPERTX
102
103// This is used as a reference when computing the source variance for the
104// purposes of activity masking.
105// Eventually this should be replaced by custom no-reference routines,
106// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700107static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700108 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
109 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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,
113#if CONFIG_EXT_PARTITION
114 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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
119#endif // CONFIG_EXT_PARTITION
120};
121
Yaowu Xuf883b422016-08-30 14:01:10 -0700122#if CONFIG_AOM_HIGHBITDEPTH
123static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
125 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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,
129#if CONFIG_EXT_PARTITION
130 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
131 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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
135#endif // CONFIG_EXT_PARTITION
136};
137
Yaowu Xuf883b422016-08-30 14:01:10 -0700138static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700139 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
140 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
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#if CONFIG_EXT_PARTITION
148 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
149 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
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#endif // CONFIG_EXT_PARTITION
157};
158
Yaowu Xuf883b422016-08-30 14:01:10 -0700159static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
161 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
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,
170#if CONFIG_EXT_PARTITION
171 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
172 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
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
181#endif // CONFIG_EXT_PARTITION
182};
Yaowu Xuf883b422016-08-30 14:01:10 -0700183#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700184
Urvang Joshi52648442016-10-13 17:27:51 -0700185unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700186 const struct buf_2d *ref,
187 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700188 unsigned int sse;
189 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700190 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700191 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
192}
193
Yaowu Xuf883b422016-08-30 14:01:10 -0700194#if CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700195unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700196 const struct buf_2d *ref,
197 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198 unsigned int var, sse;
199 switch (bd) {
200 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700201 var =
202 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
203 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 break;
205 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700206 var =
207 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
208 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700209 break;
210 case 8:
211 default:
212 var =
213 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700214 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700215 break;
216 }
217 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
218}
Yaowu Xuf883b422016-08-30 14:01:10 -0700219#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700220
Urvang Joshi52648442016-10-13 17:27:51 -0700221static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 const struct buf_2d *ref,
223 int mi_row, int mi_col,
224 BLOCK_SIZE bs) {
225 unsigned int sse, var;
226 uint8_t *last_y;
227 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
228
229 assert(last != NULL);
230 last_y =
231 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
232 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
233 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
234}
235
Yaowu Xuf883b422016-08-30 14:01:10 -0700236static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
237 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700238 unsigned int var = get_sby_perpixel_diff_variance(
239 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
240 if (var < 8)
241 return BLOCK_64X64;
242 else if (var < 128)
243 return BLOCK_32X32;
244 else if (var < 2048)
245 return BLOCK_16X16;
246 else
247 return BLOCK_8X8;
248}
249
250// Lighter version of set_offsets that only sets the mode info
251// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700252static void set_mode_info_offsets(const AV1_COMP *const cpi,
253 MACROBLOCK *const x, MACROBLOCKD *const xd,
254 int mi_row, int mi_col) {
255 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256 const int idx_str = xd->mi_stride * mi_row + mi_col;
257 xd->mi = cm->mi_grid_visible + idx_str;
258 xd->mi[0] = cm->mi + idx_str;
259 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
260}
261
Urvang Joshi52648442016-10-13 17:27:51 -0700262static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263 const TileInfo *const tile,
264 MACROBLOCK *const x, int mi_row,
265 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700266 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800268 const int mi_width = mi_size_wide[bsize];
269 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700270
271 set_skip_context(xd, mi_row, mi_col);
272
273 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
274
275#if CONFIG_VAR_TX
276 xd->above_txfm_context = cm->above_txfm_context + mi_col;
277 xd->left_txfm_context =
278 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
279 xd->max_tx_size = max_txsize_lookup[bsize];
280#endif
281
282 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700283 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700284
285 // Set up limit values for MV components.
286 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700287 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
288 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
289 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
290 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700291
Jingning Hanfaad0e12016-12-07 10:54:57 -0800292 set_plane_n4(xd, mi_width, mi_height);
Jingning Hana6923f72016-07-15 08:50:14 -0700293
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294 // Set up distance of MB to edge of frame in 1/8th pel units.
295 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800296#if CONFIG_DEPENDENT_HORZTILES
297 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
298 cm->mi_cols, cm->dependent_horz_tiles);
299#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
301 cm->mi_cols);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800302#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700303
304 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700305 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306
307 // R/D setup.
308 x->rddiv = cpi->rd.RDDIV;
309 x->rdmult = cpi->rd.RDMULT;
310
Yaowu Xuf883b422016-08-30 14:01:10 -0700311 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 xd->tile = *tile;
313}
314
Urvang Joshi52648442016-10-13 17:27:51 -0700315static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700316 MACROBLOCK *const x, int mi_row, int mi_col,
317 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700318 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700319 MACROBLOCKD *const xd = &x->e_mbd;
320 MB_MODE_INFO *mbmi;
321 const struct segmentation *const seg = &cm->seg;
322
323 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
324
325 mbmi = &xd->mi[0]->mbmi;
326
327 // Setup segment ID.
328 if (seg->enabled) {
329 if (!cpi->vaq_refresh) {
330 const uint8_t *const map =
331 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
332 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
333 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700334 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700335 } else {
336 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700337 }
338
339#if CONFIG_SUPERTX
340 mbmi->segment_id_supertx = MAX_SEGMENTS;
341#endif // CONFIG_SUPERTX
342}
343
344#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700345static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 const TileInfo *const tile, int mi_row,
347 int mi_col, BLOCK_SIZE bsize) {
348 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700349 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800351 const int mi_width = mi_size_wide[bsize];
352 const int mi_height = mi_size_high[bsize];
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800353#if CONFIG_DEPENDENT_HORZTILES
354 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col, cm->dependent_horz_tiles);
355#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700356 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800357#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700358
359 // Set up distance of MB to edge of frame in 1/8th pel units.
360 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
361 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
362 cm->mi_cols);
363}
364
Urvang Joshi52648442016-10-13 17:27:51 -0700365static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 const TileInfo *const tile, int mi_row_pred,
367 int mi_col_pred, int mi_row_ori, int mi_col_ori,
368 BLOCK_SIZE bsize_pred) {
369 // Used in supertx
370 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
371 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
372 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700373 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700374 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800375 const int mi_width = mi_size_wide[bsize_pred];
376 const int mi_height = mi_size_high[bsize_pred];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700377
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800378#if CONFIG_DEPENDENT_HORZTILES
379 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori,
380 cm->dependent_horz_tiles);
381#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700382 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800383#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700384
385 // Set up limit values for MV components.
386 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700387 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
388 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
389 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
390 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700391
Jingning Hanfeb517c2016-12-21 16:02:07 -0800392// Set up distance of MB to edge of frame in 1/8th pel units.
393#if !CONFIG_CB4X4
Jingning Han5b7706a2016-12-21 09:55:10 -0800394 assert(!(mi_col_pred & (mi_width - mi_size_wide[BLOCK_8X8])) &&
395 !(mi_row_pred & (mi_height - mi_size_high[BLOCK_8X8])));
Jingning Hanfeb517c2016-12-21 16:02:07 -0800396#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
398 cm->mi_rows, cm->mi_cols);
399 xd->up_available = (mi_row_ori > tile->mi_row_start);
400 xd->left_available = (mi_col_ori > tile->mi_col_start);
401
402 // R/D setup.
403 x->rddiv = cpi->rd.RDDIV;
404 x->rdmult = cpi->rd.RDMULT;
405}
406
Yaowu Xuf883b422016-08-30 14:01:10 -0700407static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 MACROBLOCK *const x, const int mi_row,
409 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700410 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700411 const struct segmentation *seg = &cm->seg;
Jingning Han5b7706a2016-12-21 09:55:10 -0800412 const int miw = AOMMIN(mi_size_wide[bsize], cm->mi_cols - mi_col);
413 const int mih = AOMMIN(mi_size_high[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414 const int mi_offset = mi_row * cm->mi_stride + mi_col;
415 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
416 int r, c;
417 int seg_id_supertx = MAX_SEGMENTS;
418
419 if (!seg->enabled) {
420 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421 } else {
422 // Find the minimum segment_id
423 for (r = 0; r < mih; r++)
424 for (c = 0; c < miw; c++)
425 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700426 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
428
429 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700430 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700431 }
432
433 // Assign the the segment_id back to segment_id_supertx
434 for (r = 0; r < mih; r++)
435 for (c = 0; c < miw; c++)
436 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
437}
438#endif // CONFIG_SUPERTX
439
Yaowu Xuf883b422016-08-30 14:01:10 -0700440static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 MACROBLOCKD *const xd, int mi_row, int mi_col,
442 BLOCK_SIZE bsize) {
443 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
444 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
445 xd->mi[0]->mbmi.sb_type = bsize;
446 }
447}
448
Yaowu Xuf883b422016-08-30 14:01:10 -0700449static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700450 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
451 int mi_col, const int64_t *const threshold,
452 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700453 AV1_COMMON *const cm = &cpi->common;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800454 const int hbw = mi_size_wide[vt->bsize] / 2;
455 const int hbh = mi_size_high[vt->bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700456 const int has_cols = mi_col + hbw < cm->mi_cols;
457 const int has_rows = mi_row + hbh < cm->mi_rows;
458
459 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
460
461 assert(vt->bsize >= BLOCK_8X8);
462
463 assert(hbh == hbw);
464
465 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
466 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
467 return;
468 }
469
470 if (vt->force_split || (!has_cols && !has_rows)) goto split;
471
472 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
473 // variance is below threshold, otherwise split will be selected.
474 // No check for vert/horiz split as too few samples for variance.
475 if (vt->bsize == bsize_min[0]) {
476 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
477 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
478 return;
479 } else {
480 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
481 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
482 if (vt->bsize > BLOCK_8X8) {
483 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
484 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
485 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
486 }
487 return;
488 }
489 } else if (vt->bsize > bsize_min[0]) {
490 // For key frame: take split for bsize above 32X32 or very high variance.
491 if (cm->frame_type == KEY_FRAME &&
492 (vt->bsize > BLOCK_32X32 ||
493 vt->variances.none.variance > (threshold[0] << 4))) {
494 goto split;
495 }
496 // If variance is low, take the bsize (no split).
497 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
498 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
499 return;
500 }
501
502 // Check vertical split.
503 if (has_rows) {
504 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
505 if (vt->variances.vert[0].variance < threshold[0] &&
506 vt->variances.vert[1].variance < threshold[0] &&
507 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
508 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
509 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
510 return;
511 }
512 }
513 // Check horizontal split.
514 if (has_cols) {
515 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
516 if (vt->variances.horz[0].variance < threshold[0] &&
517 vt->variances.horz[1].variance < threshold[0] &&
518 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
519 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
520 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
521 return;
522 }
523 }
524 }
525
526split : {
527 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
528 bsize_min + 1);
529 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
530 threshold + 1, bsize_min + 1);
531 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
532 threshold + 1, bsize_min + 1);
533 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
534 threshold + 1, bsize_min + 1);
535 return;
536}
537}
538
539// Set the variance split thresholds for following the block sizes:
540// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
541// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
542// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700543static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
544 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700545 const int is_key_frame = (cm->frame_type == KEY_FRAME);
546 const int threshold_multiplier = is_key_frame ? 20 : 1;
547 const int64_t threshold_base =
548 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
549 if (is_key_frame) {
550 thresholds[1] = threshold_base;
551 thresholds[2] = threshold_base >> 2;
552 thresholds[3] = threshold_base >> 2;
553 thresholds[4] = threshold_base << 2;
554 } else {
555 thresholds[2] = threshold_base;
556 if (cm->width <= 352 && cm->height <= 288) {
557 thresholds[1] = threshold_base >> 2;
558 thresholds[3] = threshold_base << 3;
559 } else {
560 thresholds[1] = threshold_base;
561 thresholds[2] = (5 * threshold_base) >> 2;
562 if (cm->width >= 1920 && cm->height >= 1080)
563 thresholds[2] = (7 * threshold_base) >> 2;
564 thresholds[3] = threshold_base << cpi->oxcf.speed;
565 }
566 }
567 thresholds[0] = INT64_MIN;
568}
569
Yaowu Xuf883b422016-08-30 14:01:10 -0700570void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
571 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700572 SPEED_FEATURES *const sf = &cpi->sf;
573 const int is_key_frame = (cm->frame_type == KEY_FRAME);
574 if (sf->partition_search_type != VAR_BASED_PARTITION &&
575 sf->partition_search_type != REFERENCE_PARTITION) {
576 return;
577 } else {
578 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
579 // The thresholds below are not changed locally.
580 if (is_key_frame) {
581 cpi->vbp_threshold_sad = 0;
582 cpi->vbp_bsize_min = BLOCK_8X8;
583 } else {
584 if (cm->width <= 352 && cm->height <= 288)
585 cpi->vbp_threshold_sad = 100;
586 else
587 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
588 ? (cpi->y_dequant[q][1] << 1)
589 : 1000;
590 cpi->vbp_bsize_min = BLOCK_16X16;
591 }
592 cpi->vbp_threshold_minmax = 15 + (q >> 3);
593 }
594}
595
596// Compute the minmax over the 8x8 subblocks.
597static int compute_minmax_8x8(const uint8_t *src, int src_stride,
598 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700599#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 int highbd,
601#endif
602 int pixels_wide, int pixels_high) {
603 int k;
604 int minmax_max = 0;
605 int minmax_min = 255;
606 // Loop over the 4 8x8 subblocks.
607 for (k = 0; k < 4; k++) {
608 const int x8_idx = ((k & 1) << 3);
609 const int y8_idx = ((k >> 1) << 3);
610 int min = 0;
611 int max = 0;
612 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
613 const int src_offset = y8_idx * src_stride + x8_idx;
614 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700615#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700616 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700617 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618 ref_stride, &min, &max);
619 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700620 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621 ref_stride, &min, &max);
622 }
623#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700624 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700625 &min, &max);
626#endif
627 if ((max - min) > minmax_max) minmax_max = (max - min);
628 if ((max - min) < minmax_min) minmax_min = (max - min);
629 }
630 }
631 return (minmax_max - minmax_min);
632}
633
Yaowu Xuf883b422016-08-30 14:01:10 -0700634#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635static INLINE int avg_4x4(const uint8_t *const src, const int stride,
636 const int highbd) {
637 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700640 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 }
642}
643#else
644static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700645 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646}
647#endif
648
Yaowu Xuf883b422016-08-30 14:01:10 -0700649#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700650static INLINE int avg_8x8(const uint8_t *const src, const int stride,
651 const int highbd) {
652 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700653 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700654 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700655 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700656 }
657}
658#else
659static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700660 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700661}
662#endif
663
664static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700665#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 const int highbd,
667#endif
668 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
669 const int width, const int height,
670 const uint8_t *const src, const int src_stride,
671 const uint8_t *const ref, const int ref_stride) {
672 assert(bsize >= leaf_size);
673
674 vt->bsize = bsize;
675
676 vt->force_split = 0;
677
678 vt->src = src;
679 vt->src_stride = src_stride;
680 vt->ref = ref;
681 vt->ref_stride = ref_stride;
682
683 vt->width = width;
684 vt->height = height;
685
Yaowu Xuf883b422016-08-30 14:01:10 -0700686#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689
690 if (bsize > leaf_size) {
691 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800692 const int px = block_size_wide[subsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700693
694 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700695#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700697#endif // CONFIG_AOM_HIGHBITDEPTH
698 subsize, leaf_size, AOMMIN(px, width),
699 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700701#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700703#endif // CONFIG_AOM_HIGHBITDEPTH
704 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705 src + px, src_stride, ref + px, ref_stride);
706 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700707#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700708 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700709#endif // CONFIG_AOM_HIGHBITDEPTH
710 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 src + px * src_stride, src_stride, ref + px * ref_stride,
712 ref_stride);
713 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700714#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700715 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700716#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717 subsize, leaf_size, width - px, height - px,
718 src + px * src_stride + px, src_stride,
719 ref + px * ref_stride + px, ref_stride);
720 }
721}
722
723// Fill the variance tree based on averaging pixel values (sub-sampling), at
724// the leaf node size.
725static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
726 if (vt->bsize > leaf_size) {
727 fill_variance_tree(vt->split[0], leaf_size);
728 fill_variance_tree(vt->split[1], leaf_size);
729 fill_variance_tree(vt->split[2], leaf_size);
730 fill_variance_tree(vt->split[3], leaf_size);
731 fill_variance_node(vt);
732 } else if (vt->width <= 0 || vt->height <= 0) {
733 fill_variance(0, 0, 0, &vt->variances.none);
734 } else {
735 unsigned int sse = 0;
736 int sum = 0;
737 int src_avg;
738 int ref_avg;
739 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
740 if (leaf_size == BLOCK_4X4) {
741 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
742 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
743 } else {
744 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
745 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
746 }
747 sum = src_avg - ref_avg;
748 sse = sum * sum;
749 fill_variance(sse, sum, 0, &vt->variances.none);
750 }
751}
752
753static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
754 if (vt->bsize >= BLOCK_8X8) {
755 if (vt->bsize == BLOCK_16X16) {
756 if (vt->variances.none.variance <= threshold)
757 return;
758 else
759 vt->force_split = 0;
760 }
761
762 refine_variance_tree(vt->split[0], threshold);
763 refine_variance_tree(vt->split[1], threshold);
764 refine_variance_tree(vt->split[2], threshold);
765 refine_variance_tree(vt->split[3], threshold);
766
767 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
768 } else if (vt->width <= 0 || vt->height <= 0) {
769 fill_variance(0, 0, 0, &vt->variances.none);
770 } else {
771 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
772 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
773 const int sum = src_avg - ref_avg;
774 const unsigned int sse = sum * sum;
775 assert(vt->bsize == BLOCK_4X4);
776 fill_variance(sse, sum, 0, &vt->variances.none);
777 }
778}
779
780static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
781 if (vt->bsize == BLOCK_32X32) {
782 vt->force_split = vt->variances.none.variance > threshold;
783 } else {
784 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
785 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
786 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
787 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
788 }
789 return vt->force_split;
790}
791
Yaowu Xuf883b422016-08-30 14:01:10 -0700792static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700793 const int segment_id, const int64_t *const thresholds) {
794 if (vt->bsize == BLOCK_16X16) {
795 vt->force_split = vt->variances.none.variance > thresholds[0];
796 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
797 !cyclic_refresh_segment_id_boosted(segment_id)) {
798 // We have some nominal amount of 16x16 variance (based on average),
799 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
800 // force split to 8x8 block for this 16x16 block.
801 int minmax =
802 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700803#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700804 vt->highbd,
805#endif
806 vt->width, vt->height);
807 vt->force_split = minmax > cpi->vbp_threshold_minmax;
808 }
809 } else {
810 vt->force_split |=
811 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
812 vt->force_split |=
813 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
814 vt->force_split |=
815 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
816 vt->force_split |=
817 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
818
819 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
820 vt->force_split = vt->variances.none.variance > thresholds[0];
821 }
822 }
823
824 return vt->force_split;
825}
826
827// This function chooses partitioning based on the variance between source and
828// reconstructed last (or golden), where variance is computed for down-sampled
829// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700830static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831 const TileInfo *const tile, MACROBLOCK *const x,
832 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700833 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700834 MACROBLOCKD *const xd = &x->e_mbd;
835 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700836#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700837 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700838#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700839 const uint8_t *src;
840 const uint8_t *ref;
841 int src_stride;
842 int ref_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800843 int pixels_wide = MI_SIZE * mi_size_wide[cm->sb_size];
844 int pixels_high = MI_SIZE * mi_size_high[cm->sb_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700845 int64_t thresholds[5] = {
846 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
847 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
848 };
849 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
850 cpi->vbp_bsize_min, BLOCK_8X8 };
851 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
852 const int64_t *const thre = thresholds + start_level;
853 const BLOCK_SIZE *const bmin = bsize_min + start_level;
854
855 const int is_key_frame = (cm->frame_type == KEY_FRAME);
856 const int low_res = (cm->width <= 352 && cm->height <= 288);
857
858 int segment_id = CR_SEGMENT_ID_BASE;
859
860 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
861 const uint8_t *const map =
862 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
863 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
864
865 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700866 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867 set_vbp_thresholds(cpi, thresholds, q);
868 }
869 }
870
871 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
872
873 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
874 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
875
876 src = x->plane[0].src.buf;
877 src_stride = x->plane[0].src.stride;
878
879 if (!is_key_frame) {
880 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700881 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
882 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
883 unsigned int y_sad, y_sad_g;
884
885 const int hbs = cm->mib_size / 2;
886 const int split_vert = mi_col + hbs >= cm->mi_cols;
887 const int split_horz = mi_row + hbs >= cm->mi_rows;
888 BLOCK_SIZE bsize;
889
890 if (split_vert && split_horz)
891 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
892 else if (split_vert)
893 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
894 else if (split_horz)
895 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
896 else
897 bsize = cm->sb_size;
898
899 assert(yv12 != NULL);
900
901 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700902 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
903 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904 y_sad_g = cpi->fn_ptr[bsize].sdf(
905 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
906 xd->plane[0].pre[0].stride);
907 } else {
908 y_sad_g = UINT_MAX;
909 }
910
Yaowu Xuf883b422016-08-30 14:01:10 -0700911 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
912 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700913 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -0500914 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 mbmi->sb_type = cm->sb_size;
916 mbmi->mv[0].as_int = 0;
917#if CONFIG_DUAL_FILTER
918 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
919#else
920 mbmi->interp_filter = BILINEAR;
921#endif
922
Yaowu Xuf883b422016-08-30 14:01:10 -0700923 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924
925 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700926 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
927 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 mbmi->ref_frame[0] = GOLDEN_FRAME;
929 mbmi->mv[0].as_int = 0;
930 y_sad = y_sad_g;
931 } else {
932 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
933 }
934
David Barkerac37fa32016-12-02 12:30:21 +0000935 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700936
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 ref = xd->plane[0].dst.buf;
938 ref_stride = xd->plane[0].dst.stride;
939
940 // If the y_sad is very small, take the largest partition and exit.
941 // Don't check on boosted segment for now, as largest is suppressed there.
942 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
943 if (!split_vert && !split_horz) {
944 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
945 return;
946 }
947 }
948 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700949 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700950 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700951#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
953 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700954 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
955 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700957 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958 }
959 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700960#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700961 }
962
963 init_variance_tree(
964 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700965#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700967#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700968 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
969 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
970
971 // Fill in the entire tree of variances and compute splits.
972 if (is_key_frame) {
973 fill_variance_tree(vt, BLOCK_4X4);
974 check_split_key_frame(vt, thre[1]);
975 } else {
976 fill_variance_tree(vt, BLOCK_8X8);
977 check_split(cpi, vt, segment_id, thre);
978 if (low_res) {
979 refine_variance_tree(vt, thre[1] << 1);
980 }
981 }
982
983 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
984 mi_row + cm->mib_size > cm->mi_rows;
985
986 // Now go through the entire structure, splitting every block size until
987 // we get to one that's got a variance lower than our threshold.
988 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
989}
990
991#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700992static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700993 MB_MODE_INFO *mbmi) {
994 int dir;
995 for (dir = 0; dir < 2; ++dir) {
996 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
Emil Keyder01770b32017-01-20 18:03:11 -0500997 (mbmi->ref_frame[1] == NONE_FRAME ||
Yaowu Xuc27fc142016-08-22 16:08:15 -0700998 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
999 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
1000 ? EIGHTTAP_REGULAR
1001 : cm->interp_filter;
1002 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
1003 }
1004}
1005
1006static void update_filter_type_count(FRAME_COUNTS *counts,
1007 const MACROBLOCKD *xd,
1008 const MB_MODE_INFO *mbmi) {
1009 int dir;
1010 for (dir = 0; dir < 2; ++dir) {
1011 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
1012 (mbmi->ref_frame[1] > INTRA_FRAME &&
1013 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001014 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1016 }
1017 }
1018}
1019#endif
1020#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001021static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001022 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08001023 if (mode == ZEROMV
1024#if CONFIG_EXT_INTER
1025 || mode == ZERO_ZEROMV
1026#endif
1027 ) {
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001028 const int num_4x4s = bsize >= BLOCK_8X8
1029 ? num_4x4_blocks_wide_lookup[bsize] *
1030 num_4x4_blocks_high_lookup[bsize]
1031 : 1;
Sarah Parkerc2d38712017-01-24 15:15:41 -08001032 int ref;
1033 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
1034 ++cpi->global_motion_used[mbmi->ref_frame[ref]][0];
1035 cpi->global_motion_used[mbmi->ref_frame[ref]][1] += num_4x4s;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001036 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001037 }
1038}
1039#endif // CONFIG_GLOBAL_MOTION
1040
Jingning Han4470af12017-03-06 15:34:41 -08001041static void reset_tx_size(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
1042 const TX_MODE tx_mode) {
1043 if (xd->lossless[mbmi->segment_id]) {
1044 mbmi->tx_size = TX_4X4;
1045 } else if (tx_mode != TX_MODE_SELECT) {
1046 mbmi->tx_size =
1047 tx_size_from_tx_mode(mbmi->sb_type, tx_mode, is_inter_block(mbmi));
1048 }
1049}
1050
Urvang Joshi52648442016-10-13 17:27:51 -07001051static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1052 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1053 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001055 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 RD_COUNTS *const rdc = &td->rd_counts;
1057 MACROBLOCK *const x = &td->mb;
1058 MACROBLOCKD *const xd = &x->e_mbd;
1059 struct macroblock_plane *const p = x->plane;
1060 struct macroblockd_plane *const pd = xd->plane;
1061 MODE_INFO *mi = &ctx->mic;
1062 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1063 MODE_INFO *mi_addr = xd->mi[0];
1064 const struct segmentation *const seg = &cm->seg;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001065 const int bw = mi_size_wide[mi->mbmi.sb_type];
1066 const int bh = mi_size_high[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001067 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1068 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001069 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1070 int w, h;
1071
1072 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001073 const int mi_width = mi_size_wide[bsize];
1074 const int mi_height = mi_size_high[bsize];
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001075 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001076
1077#if CONFIG_REF_MV
1078 int8_t rf_type;
1079#endif
1080
1081#if !CONFIG_SUPERTX
1082 assert(mi->mbmi.sb_type == bsize);
1083#endif
1084
1085 *mi_addr = *mi;
1086 *x->mbmi_ext = ctx->mbmi_ext;
1087
1088#if CONFIG_DUAL_FILTER
1089 reset_intmv_filter_type(cm, xd, mbmi);
1090#endif
1091
1092#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001093 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001094 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1095 (mbmi->sb_type >= BLOCK_8X8 || unify_bsize) && mbmi->mode == NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1097 int_mv this_mv =
1098 (i == 0)
1099 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1100 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001101 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1102 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001103 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1104 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001105 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001106 }
1107 }
1108#endif
1109
1110 // If segmentation in use
1111 if (seg->enabled) {
1112 // For in frame complexity AQ copy the segment id from the segment map.
1113 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1114 const uint8_t *const map =
1115 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1116 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
Jingning Han4470af12017-03-06 15:34:41 -08001117 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001118 }
1119 // Else for cyclic refresh mode update the segment map, set the segment id
1120 // and then update the quantizer.
1121 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001122 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1123 bsize, ctx->rate, ctx->dist, x->skip);
Jingning Han4470af12017-03-06 15:34:41 -08001124 reset_tx_size(xd, &mi_addr->mbmi, cm->tx_mode);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125 }
1126 }
1127
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001128 for (i = 0; i < MAX_MB_PLANE; ++i) {
1129 p[i].coeff = ctx->coeff[i];
1130 p[i].qcoeff = ctx->qcoeff[i];
1131 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001132#if CONFIG_PVQ
1133 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1134#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001135 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 }
Urvang Joshib100db72016-10-12 16:28:56 -07001137#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001139#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140
1141 // Restore the coding context of the MB to that that was in place
1142 // when the mode was picked for it
1143 for (y = 0; y < mi_height; y++)
1144 for (x_idx = 0; x_idx < mi_width; x_idx++)
1145 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1146 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1147 xd->mi[x_idx + y * mis] = mi_addr;
1148 }
1149
Arild Fuldseth07441162016-08-15 15:07:52 +02001150#if CONFIG_DELTA_Q
1151 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001152 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001153#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001154 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001155 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001156#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001157
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001158 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001159 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1160 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1161 }
1162
1163 x->skip = ctx->skip;
1164
1165#if CONFIG_VAR_TX
1166 for (i = 0; i < 1; ++i)
1167 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1168 sizeof(uint8_t) * ctx->num_4x4_blk);
1169#endif
1170
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001171 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001172
1173#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001174 {
1175 unsigned int *const mode_chosen_counts =
1176 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1177 if (frame_is_intra_only(cm)) {
1178 static const int kf_mode_index[] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -07001179 THR_DC /*DC_PRED*/,
1180 THR_V_PRED /*V_PRED*/,
1181 THR_H_PRED /*H_PRED*/,
1182 THR_D45_PRED /*D45_PRED*/,
1183 THR_D135_PRED /*D135_PRED*/,
1184 THR_D117_PRED /*D117_PRED*/,
1185 THR_D153_PRED /*D153_PRED*/,
1186 THR_D207_PRED /*D207_PRED*/,
1187 THR_D63_PRED /*D63_PRED*/,
1188#if CONFIG_ALT_INTRA
1189 THR_SMOOTH, /*SMOOTH_PRED*/
1190#endif // CONFIG_ALT_INTRA
1191 THR_TM /*TM_PRED*/,
Urvang Joshi52648442016-10-13 17:27:51 -07001192 };
1193 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1194 } else {
1195 // Note how often each mode chosen as best
1196 ++mode_chosen_counts[ctx->best_mode_index];
1197 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198 }
1199#endif
1200 if (!frame_is_intra_only(cm)) {
1201 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001202 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001203#if CONFIG_GLOBAL_MOTION
1204 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001205 // TODO(sarahparker): global motion stats need to be handled per-tile
1206 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001207 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001208 } else {
1209 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1210 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1211 int idx, idy;
1212 for (idy = 0; idy < 2; idy += num_4x4_h) {
1213 for (idx = 0; idx < 2; idx += num_4x4_w) {
1214 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001215 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
James Zernaf322e12016-10-22 12:43:15 -07001216 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217 }
1218 }
1219 }
1220#endif // CONFIG_GLOBAL_MOTION
1221 if (cm->interp_filter == SWITCHABLE
Yue Chen69f18e12016-09-08 14:48:15 -07001222#if CONFIG_WARPED_MOTION
1223 && mbmi->motion_mode != WARPED_CAUSAL
1224#endif // CONFIG_WARPED_MOTION
Yue Chen19e7aa82016-11-30 14:05:39 -08001225#if CONFIG_GLOBAL_MOTION
1226 && !is_nontrans_global_motion(xd)
1227#endif // CONFIG_GLOBAL_MOTION
1228 ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229#if CONFIG_DUAL_FILTER
1230 update_filter_type_count(td->counts, xd, mbmi);
1231#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001232 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1233 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001234#endif
1235 }
1236 }
1237
1238 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1239 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1240 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1241 }
1242
1243 for (h = 0; h < y_mis; ++h) {
1244 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1245 for (w = 0; w < x_mis; ++w) {
1246 MV_REF *const mv = frame_mv + w;
1247 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1248 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1249 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1250 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1251 }
1252 }
1253}
1254
1255#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001256static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001257 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001258 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001259 int y, x_idx;
1260#if CONFIG_VAR_TX || CONFIG_REF_MV
1261 int i;
1262#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001263 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 RD_COUNTS *const rdc = &td->rd_counts;
1265 MACROBLOCK *const x = &td->mb;
1266 MACROBLOCKD *const xd = &x->e_mbd;
1267 MODE_INFO *mi = &ctx->mic;
1268 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1269 MODE_INFO *mi_addr = xd->mi[0];
1270 const struct segmentation *const seg = &cm->seg;
1271 const int mis = cm->mi_stride;
Jingning Han5b7706a2016-12-21 09:55:10 -08001272 const int mi_width = mi_size_wide[bsize];
1273 const int mi_height = mi_size_high[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001274 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1275 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001276 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1277 int w, h;
1278
1279#if CONFIG_REF_MV
1280 int8_t rf_type;
1281#endif
1282
1283 *mi_addr = *mi;
1284 *x->mbmi_ext = ctx->mbmi_ext;
1285 assert(is_inter_block(mbmi));
1286 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1287
1288#if CONFIG_DUAL_FILTER
1289 reset_intmv_filter_type(cm, xd, mbmi);
1290#endif
1291
1292#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001293 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Han38b1bc42016-12-22 15:51:04 -08001294 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1295#if !CONFIG_CB4X4
1296 mbmi->sb_type >= BLOCK_8X8 &&
1297#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001298 mbmi->mode == NEWMV) {
1299 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1300 int_mv this_mv =
1301 (i == 0)
1302 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1303 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001304 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1305 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001306 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1307 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1308 mbmi->pred_mv[i] = this_mv;
1309 }
1310 }
1311#endif
1312
1313 // If segmentation in use
1314 if (seg->enabled) {
1315 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001316 const int energy =
1317 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1318 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1320 // For cyclic refresh mode, now update the segment map
1321 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001322 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1323 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001324 } else {
1325 // Otherwise just set the segment id based on the current segment map
1326 const uint8_t *const map =
1327 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1328 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1329 }
1330 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1331 }
1332
1333 // Restore the coding context of the MB to that that was in place
1334 // when the mode was picked for it
1335 for (y = 0; y < mi_height; y++)
1336 for (x_idx = 0; x_idx < mi_width; x_idx++)
1337 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1338 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1339 xd->mi[x_idx + y * mis] = mi_addr;
1340 }
1341
Jingning Han38b1bc42016-12-22 15:51:04 -08001342#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001343 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1344 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1345 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1346 }
Jingning Han38b1bc42016-12-22 15:51:04 -08001347#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348
1349 x->skip = ctx->skip;
1350
1351#if CONFIG_VAR_TX
1352 for (i = 0; i < 1; ++i)
1353 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1354 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001355
1356 if (!is_inter_block(mbmi) || mbmi->skip)
1357 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001358#endif // CONFIG_VAR_TX
1359
1360#if CONFIG_VAR_TX
1361 {
1362 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001363 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1364 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001365 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001366 mbmi->inter_tx_size[0][0] = mtx;
1367 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1368 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1369 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370 }
1371#endif // CONFIG_VAR_TX
1372 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001373 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001374
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001375 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001376
1377 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001378 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001379
David Barker03bd2102016-11-17 14:55:04 +00001380#if CONFIG_GLOBAL_MOTION
1381 if (is_inter_block(mbmi)) {
1382 if (bsize >= BLOCK_8X8) {
1383 // TODO(sarahparker): global motion stats need to be handled per-tile
1384 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001385 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
David Barker03bd2102016-11-17 14:55:04 +00001386 } else {
1387 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1388 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1389 int idx, idy;
1390 for (idy = 0; idy < 2; idy += num_4x4_h) {
1391 for (idx = 0; idx < 2; idx += num_4x4_w) {
1392 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001393 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
David Barker03bd2102016-11-17 14:55:04 +00001394 (AV1_COMP *)cpi);
1395 }
1396 }
1397 }
1398 }
1399#endif // CONFIG_GLOBAL_MOTION
1400
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401 if (cm->interp_filter == SWITCHABLE
Yue Chen19e7aa82016-11-30 14:05:39 -08001402#if CONFIG_GLOBAL_MOTION
1403 && !is_nontrans_global_motion(xd)
1404#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405 ) {
1406#if CONFIG_DUAL_FILTER
1407 update_filter_type_count(td->counts, xd, mbmi);
1408#else
James Zern9ca190c2016-10-22 12:42:43 -07001409 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1410 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001411#endif
1412 }
1413
1414 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1415 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1416 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1417 }
1418
1419 for (h = 0; h < y_mis; ++h) {
1420 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1421 for (w = 0; w < x_mis; ++w) {
1422 MV_REF *const mv = frame_mv + w;
1423 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1424 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1425 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1426 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1427 }
1428 }
1429}
1430
Urvang Joshi52648442016-10-13 17:27:51 -07001431static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432 const TileInfo *const tile, int mi_row,
1433 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001434 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001435 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436 MACROBLOCK *const x = &td->mb;
1437 MACROBLOCKD *const xd = &x->e_mbd;
1438 struct macroblock_plane *const p = x->plane;
1439 struct macroblockd_plane *const pd = xd->plane;
Jingning Han5b7706a2016-12-21 09:55:10 -08001440 int hbs = mi_size_wide[bsize] / 2;
Jingning Hanfeb517c2016-12-21 16:02:07 -08001441#if CONFIG_CB4X4
1442 const int unify_bsize = 1;
1443#else
1444 const int unify_bsize = 0;
1445#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001446 PARTITION_TYPE partition = pc_tree->partitioning;
1447 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1448 int i;
1449#if CONFIG_EXT_PARTITION_TYPES
1450 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1451#endif
1452 PICK_MODE_CONTEXT *pmc = NULL;
1453
1454 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1455
1456 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001457 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001458
1459 switch (partition) {
1460 case PARTITION_NONE:
1461 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1462 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001463 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464 break;
1465 case PARTITION_VERT:
1466 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1467 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001468 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001469 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001470 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1471 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001472 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001473 }
1474 pmc = &pc_tree->vertical_supertx;
1475 break;
1476 case PARTITION_HORZ:
1477 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1478 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001479 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001480 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001481 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1482 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001483 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001484 }
1485 pmc = &pc_tree->horizontal_supertx;
1486 break;
1487 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001488 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001489 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1490 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001491 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001492 } else {
1493 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001494 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1495 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001496 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1497 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001498 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001499 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1500 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001501 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001502 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1503 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001504 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001505 }
1506 pmc = &pc_tree->split_supertx;
1507 break;
1508#if CONFIG_EXT_PARTITION_TYPES
1509 case PARTITION_HORZ_A:
1510 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1511 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001512 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001513 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1514 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001515 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001516 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1517 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001518 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001519 pmc = &pc_tree->horizontala_supertx;
1520 break;
1521 case PARTITION_HORZ_B:
1522 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1523 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001524 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001525 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1526 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001527 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001528 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1529 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001530 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001531 pmc = &pc_tree->horizontalb_supertx;
1532 break;
1533 case PARTITION_VERT_A:
1534 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1535 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001536 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001537 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1538 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001539 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001540 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1541 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001542 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001543 pmc = &pc_tree->verticala_supertx;
1544 break;
1545 case PARTITION_VERT_B:
1546 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1547 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001548 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001549 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1550 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001551 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001552 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1553 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001554 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001555 pmc = &pc_tree->verticalb_supertx;
1556 break;
1557#endif // CONFIG_EXT_PARTITION_TYPES
1558 default: assert(0);
1559 }
1560
1561 for (i = 0; i < MAX_MB_PLANE; ++i) {
1562 if (pmc != NULL) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001563 p[i].coeff = pmc->coeff[i];
1564 p[i].qcoeff = pmc->qcoeff[i];
1565 pd[i].dqcoeff = pmc->dqcoeff[i];
1566 p[i].eobs = pmc->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001567 } else {
1568 // These should never be used
1569 p[i].coeff = NULL;
1570 p[i].qcoeff = NULL;
1571 pd[i].dqcoeff = NULL;
1572 p[i].eobs = NULL;
1573 }
1574 }
1575}
1576
1577static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1578 int best_tx, TX_SIZE supertx_size) {
1579 MACROBLOCK *const x = &td->mb;
1580#if CONFIG_VAR_TX
1581 int i;
1582
1583 for (i = 0; i < 1; ++i)
1584 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1585 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001586 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001587#endif // CONFIG_VAR_TX
1588 ctx->mic.mbmi.tx_size = supertx_size;
1589 ctx->skip = x->skip;
1590 ctx->mic.mbmi.tx_type = best_tx;
1591}
1592
Urvang Joshi52648442016-10-13 17:27:51 -07001593static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1594 int mi_row, int mi_col, BLOCK_SIZE bsize,
1595 int best_tx, TX_SIZE supertx_size,
1596 PC_TREE *pc_tree) {
1597 const AV1_COMMON *const cm = &cpi->common;
Jingning Han5b7706a2016-12-21 09:55:10 -08001598 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001599 PARTITION_TYPE partition = pc_tree->partitioning;
1600 BLOCK_SIZE subsize = get_subsize(bsize, partition);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001601#if CONFIG_CB4X4
1602 const int unify_bsize = 1;
1603#else
1604 const int unify_bsize = 0;
1605#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001606#if CONFIG_EXT_PARTITION_TYPES
1607 int i;
1608#endif
1609
1610 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1611
1612 switch (partition) {
1613 case PARTITION_NONE:
1614 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1615 break;
1616 case PARTITION_VERT:
1617 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001618 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001619 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1620 break;
1621 case PARTITION_HORZ:
1622 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001623 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001624 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1625 supertx_size);
1626 break;
1627 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001628 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001629 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1630 } else {
1631 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1632 supertx_size, pc_tree->split[0]);
1633 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1634 supertx_size, pc_tree->split[1]);
1635 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1636 supertx_size, pc_tree->split[2]);
1637 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1638 best_tx, supertx_size, pc_tree->split[3]);
1639 }
1640 break;
1641#if CONFIG_EXT_PARTITION_TYPES
1642 case PARTITION_HORZ_A:
1643 for (i = 0; i < 3; i++)
1644 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1645 supertx_size);
1646 break;
1647 case PARTITION_HORZ_B:
1648 for (i = 0; i < 3; i++)
1649 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1650 supertx_size);
1651 break;
1652 case PARTITION_VERT_A:
1653 for (i = 0; i < 3; i++)
1654 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1655 break;
1656 case PARTITION_VERT_B:
1657 for (i = 0; i < 3; i++)
1658 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1659 break;
1660#endif // CONFIG_EXT_PARTITION_TYPES
1661 default: assert(0);
1662 }
1663}
1664#endif // CONFIG_SUPERTX
1665
Yue Chenf27b1602017-01-13 11:11:43 -08001666#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
1667static void set_mode_info_b(const AV1_COMP *const cpi,
1668 const TileInfo *const tile, ThreadData *td,
1669 int mi_row, int mi_col, BLOCK_SIZE bsize,
1670 PICK_MODE_CONTEXT *ctx) {
1671 MACROBLOCK *const x = &td->mb;
1672 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1673 update_state(cpi, td, ctx, mi_row, mi_col, bsize, 1);
1674}
1675
1676static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
1677 const TileInfo *const tile, TOKENEXTRA **tp,
1678 int mi_row, int mi_col, BLOCK_SIZE bsize,
1679 PC_TREE *pc_tree) {
1680 const AV1_COMMON *const cm = &cpi->common;
Jingning Han91f01fd2017-01-18 17:16:40 -08001681 const int hbs = mi_size_wide[bsize] / 2;
Yue Chenf27b1602017-01-13 11:11:43 -08001682 const PARTITION_TYPE partition = pc_tree->partitioning;
1683 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1684#if CONFIG_EXT_PARTITION_TYPES
1685 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1686#endif
1687#if CONFIG_CB4X4
1688 const int unify_bsize = 1;
1689#else
1690 const int unify_bsize = 0;
1691 assert(bsize >= BLOCK_8X8);
1692#endif
1693
1694 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1695
1696 switch (partition) {
1697 case PARTITION_NONE:
1698 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize, &pc_tree->none);
1699 break;
1700 case PARTITION_VERT:
1701 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1702 &pc_tree->vertical[0]);
1703 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
1704 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1705 &pc_tree->vertical[1]);
1706 }
1707 break;
1708 case PARTITION_HORZ:
1709 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1710 &pc_tree->horizontal[0]);
1711 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
1712 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1713 &pc_tree->horizontal[1]);
1714 }
1715 break;
1716 case PARTITION_SPLIT:
1717 if (bsize == BLOCK_8X8 && !unify_bsize) {
1718 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1719 pc_tree->leaf_split[0]);
1720 } else {
1721 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col, subsize,
1722 pc_tree->split[0]);
1723 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, subsize,
1724 pc_tree->split[1]);
1725 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, subsize,
1726 pc_tree->split[2]);
1727 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, subsize,
1728 pc_tree->split[3]);
1729 }
1730 break;
1731#if CONFIG_EXT_PARTITION_TYPES
1732 case PARTITION_HORZ_A:
1733 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1734 &pc_tree->horizontala[0]);
1735 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1736 &pc_tree->horizontala[1]);
1737 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1738 &pc_tree->horizontala[2]);
1739 break;
1740 case PARTITION_HORZ_B:
1741 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1742 &pc_tree->horizontalb[0]);
1743 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1744 &pc_tree->horizontalb[1]);
1745 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1746 &pc_tree->horizontalb[2]);
1747 break;
1748 case PARTITION_VERT_A:
1749 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1750 &pc_tree->verticala[0]);
1751 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1752 &pc_tree->verticala[1]);
1753 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1754 &pc_tree->verticala[2]);
1755 break;
1756 case PARTITION_VERT_B:
1757 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1758 &pc_tree->verticalb[0]);
1759 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1760 &pc_tree->verticalb[1]);
1761 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1762 &pc_tree->verticalb[2]);
1763 break;
1764#endif // CONFIG_EXT_PARTITION_TYPES
1765 default: assert(0 && "Invalid partition type."); break;
1766 }
1767}
1768#endif
1769
Yaowu Xuf883b422016-08-30 14:01:10 -07001770void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1771 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001772 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1773 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1774 src->uv_crop_width };
1775 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1776 src->uv_crop_height };
1777 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1778 int i;
1779
1780 // Set current frame pointer.
1781 x->e_mbd.cur_buf = src;
1782
1783 for (i = 0; i < MAX_MB_PLANE; i++)
1784 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1785 strides[i], mi_row, mi_col, NULL,
1786 x->e_mbd.plane[i].subsampling_x,
1787 x->e_mbd.plane[i].subsampling_y);
1788}
1789
Urvang Joshi52648442016-10-13 17:27:51 -07001790static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001791 int8_t segment_id) {
1792 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001793 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001794 av1_init_plane_quantizers(cpi, x, segment_id);
1795 aom_clear_system_state();
1796 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1797 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001798}
1799
Urvang Joshi52648442016-10-13 17:27:51 -07001800static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001801 MACROBLOCK *const x, int mi_row, int mi_col,
1802 RD_COST *rd_cost,
1803#if CONFIG_SUPERTX
1804 int *totalrate_nocoef,
1805#endif
1806#if CONFIG_EXT_PARTITION_TYPES
1807 PARTITION_TYPE partition,
1808#endif
1809 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1810 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001811 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001812 TileInfo *const tile_info = &tile_data->tile_info;
1813 MACROBLOCKD *const xd = &x->e_mbd;
1814 MB_MODE_INFO *mbmi;
1815 struct macroblock_plane *const p = x->plane;
1816 struct macroblockd_plane *const pd = xd->plane;
1817 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1818 int i, orig_rdmult;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001819 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820
Yaowu Xuf883b422016-08-30 14:01:10 -07001821 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001822
Yushin Cho77bba8d2016-11-04 16:36:56 -07001823#if CONFIG_PVQ
1824 x->pvq_speed = 1;
1825 x->pvq_coded = 0;
1826#endif
1827
Yaowu Xuc27fc142016-08-22 16:08:15 -07001828 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1829 mbmi = &xd->mi[0]->mbmi;
1830 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001831#if CONFIG_RD_DEBUG
1832 mbmi->mi_row = mi_row;
1833 mbmi->mi_col = mi_col;
1834#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001835#if CONFIG_SUPERTX
1836 // We set tx_size here as skip blocks would otherwise not set it.
1837 // tx_size needs to be set at this point as supertx_enable in
1838 // write_modes_sb is computed based on this, and if the garbage in memory
1839 // just happens to be the supertx_size, then the packer will code this
1840 // block as a supertx block, even if rdopt did not pick it as such.
1841 mbmi->tx_size = max_txsize_lookup[bsize];
1842#endif
1843#if CONFIG_EXT_PARTITION_TYPES
1844 mbmi->partition = partition;
1845#endif
1846
1847 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001848 p[i].coeff = ctx->coeff[i];
1849 p[i].qcoeff = ctx->qcoeff[i];
1850 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001851#if CONFIG_PVQ
1852 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1853#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001854 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001855 }
1856
Urvang Joshib100db72016-10-12 16:28:56 -07001857#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001859#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001860
Yaowu Xuc27fc142016-08-22 16:08:15 -07001861 ctx->skippable = 0;
1862 ctx->pred_pixel_ready = 0;
1863
1864 // Set to zero to make sure we do not use the previous encoded frame stats
1865 mbmi->skip = 0;
1866
Jingning Han8efdbc82017-02-19 14:40:03 -08001867#if CONFIG_CB4X4
1868 x->skip_chroma_rd =
1869 (bsize < BLOCK_8X8) && !is_chroma_reference(mi_row, mi_col);
1870#endif
1871
Yaowu Xuf883b422016-08-30 14:01:10 -07001872#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001874 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 cpi, &x->plane[0].src, bsize, xd->bd);
1876 } else {
1877 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001878 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001879 }
1880#else
1881 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001882 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1883#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001884
1885 // Save rdmult before it might be changed, so it can be restored later.
1886 orig_rdmult = x->rdmult;
1887
1888 if (aq_mode == VARIANCE_AQ) {
1889 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001890 const int energy =
1891 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1892 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001893 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001894 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001895 }
1896 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1897 } else if (aq_mode == COMPLEXITY_AQ) {
1898 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1899 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1900 // If segment is boosted, use rdmult for that segment.
1901 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001902 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 }
1904
1905 // Find best coding mode & reconstruct the MB so it is available
1906 // as a predictor for MBs that follow in the SB
1907 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001908 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001909#if CONFIG_SUPERTX
1910 *totalrate_nocoef = 0;
1911#endif // CONFIG_SUPERTX
1912 } else {
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001913 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
David Barker45390c12017-02-20 14:44:40 +00001915 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, mi_row, mi_col,
1916 rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917#if CONFIG_SUPERTX
1918 *totalrate_nocoef = rd_cost->rate;
1919#endif // CONFIG_SUPERTX
1920 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001921 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001922#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001923 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001925 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001926#if CONFIG_SUPERTX
1927 assert(*totalrate_nocoef >= 0);
1928#endif // CONFIG_SUPERTX
1929 }
1930 } else {
1931 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1932 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1933 rd_cost->rate = INT_MAX;
1934 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001935 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1936 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001937#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001938 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001939#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001940 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001941#if CONFIG_SUPERTX
1942 assert(*totalrate_nocoef >= 0);
1943#endif // CONFIG_SUPERTX
1944 }
1945 }
1946 }
1947
1948 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1949 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1950 (bsize >= BLOCK_16X16) &&
1951 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1952 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001953 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001954 }
1955
1956 x->rdmult = orig_rdmult;
1957
1958 // TODO(jingning) The rate-distortion optimization flow needs to be
1959 // refactored to provide proper exit/return handle.
1960 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1961
1962 ctx->rate = rd_cost->rate;
1963 ctx->dist = rd_cost->dist;
1964}
1965
1966#if CONFIG_REF_MV
1967static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1968#if CONFIG_EXT_INTER
1969 int is_compound,
1970#endif // CONFIG_EXT_INTER
1971 int16_t mode_context) {
1972 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1973#if CONFIG_EXT_INTER
1974 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1975 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1976#else
1977 if (mode == NEWMV) {
1978#endif // CONFIG_EXT_INTER
1979 ++counts->newmv_mode[mode_ctx][0];
1980 return;
1981 } else {
1982 ++counts->newmv_mode[mode_ctx][1];
1983
1984 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1985 return;
1986 }
1987
1988 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1989 if (mode == ZEROMV) {
1990 ++counts->zeromv_mode[mode_ctx][0];
1991 return;
1992 } else {
1993 ++counts->zeromv_mode[mode_ctx][1];
1994 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1995
1996 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1997 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1998 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1999
2000 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
2001 }
2002 }
2003}
2004#endif
2005
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002006static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
2007 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008#if CONFIG_SUPERTX
2009 ,
2010 int supertx_enabled
2011#endif
2012 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01002013#if CONFIG_DELTA_Q
2014 MACROBLOCK *x = &td->mb;
2015 MACROBLOCKD *const xd = &x->e_mbd;
2016#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002017 const MACROBLOCK *x = &td->mb;
2018 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01002019#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002020 const MODE_INFO *const mi = xd->mi[0];
2021 const MB_MODE_INFO *const mbmi = &mi->mbmi;
2022 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
2023 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002024 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002025
Thomas Daviesf6936102016-09-05 16:51:31 +01002026#if CONFIG_DELTA_Q
2027 // delta quant applies to both intra and inter
2028 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
2029
2030 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
2031 super_block_upper_left) {
2032 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
2033 const int absdq = abs(dq);
2034 int i;
2035 for (i = 0; i < absdq; ++i) {
2036 td->counts->delta_q[i][1]++;
2037 }
2038 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
2039 xd->prev_qindex = mbmi->current_q_index;
2040 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002041#else
2042 (void)mi_row;
2043 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01002044#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002045 if (!frame_is_intra_only(cm)) {
2046 FRAME_COUNTS *const counts = td->counts;
2047 const int inter_block = is_inter_block(mbmi);
2048 const int seg_ref_active =
2049 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
2050 if (!seg_ref_active) {
2051#if CONFIG_SUPERTX
2052 if (!supertx_enabled)
2053#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07002054 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055 // If the segment reference feature is enabled we have only a single
2056 // reference frame allowed for the segment so exclude it from
2057 // the reference frame counts used to work out probabilities.
2058 if (inter_block) {
2059 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
2060#if CONFIG_EXT_REFS
2061 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
2062#endif // CONFIG_EXT_REFS
2063
Jingning Hanc41a5492017-02-24 11:18:52 -08002064 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
2065#if !SUB8X8_COMP_REF
2066 if (mbmi->sb_type >= BLOCK_8X8)
2067 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
2068 [has_second_ref(mbmi)]++;
2069#else
clang-format67948d32016-09-07 22:40:40 -07002070 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
2071 [has_second_ref(mbmi)]++;
Jingning Hanc41a5492017-02-24 11:18:52 -08002072#endif
2073 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002074
2075 if (has_second_ref(mbmi)) {
2076#if CONFIG_EXT_REFS
2077 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
2078
Yaowu Xuf883b422016-08-30 14:01:10 -07002079 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002080 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07002081 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
2082 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 } else {
clang-format67948d32016-09-07 22:40:40 -07002084 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
2085 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086 }
2087
clang-format67948d32016-09-07 22:40:40 -07002088 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
2089 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090#else
clang-format67948d32016-09-07 22:40:40 -07002091 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
2092 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002093#endif // CONFIG_EXT_REFS
2094 } else {
2095#if CONFIG_EXT_REFS
2096 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
2097
Yaowu Xuf883b422016-08-30 14:01:10 -07002098 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002099 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07002100 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
2101 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002102 } else {
2103 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format55ce9e02017-02-15 22:27:12 -08002104 counts
2105 ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002106 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07002107 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
2108 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109 } else {
clang-format67948d32016-09-07 22:40:40 -07002110 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
2111 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002112 }
2113 }
2114#else
clang-format67948d32016-09-07 22:40:40 -07002115 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
2116 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002117 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07002118 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
2119 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002120 }
2121#endif // CONFIG_EXT_REFS
2122 }
2123
2124#if CONFIG_EXT_INTER
2125 if (cm->reference_mode != COMPOUND_REFERENCE &&
2126#if CONFIG_SUPERTX
2127 !supertx_enabled &&
2128#endif
2129 is_interintra_allowed(mbmi)) {
2130 const int bsize_group = size_group_lookup[bsize];
2131 if (mbmi->ref_frame[1] == INTRA_FRAME) {
2132 counts->interintra[bsize_group][1]++;
2133 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
2134 if (is_interintra_wedge_used(bsize))
2135 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
2136 } else {
2137 counts->interintra[bsize_group][0]++;
2138 }
2139 }
2140#endif // CONFIG_EXT_INTER
2141
Yue Chencb60b182016-10-13 15:18:22 -07002142#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002143#if CONFIG_SUPERTX
2144 if (!supertx_enabled)
2145#endif // CONFIG_SUPERTX
2146#if CONFIG_EXT_INTER
2147 if (mbmi->ref_frame[1] != INTRA_FRAME)
2148#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07002149#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
2150 {
2151 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -07002152 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
Yue Chen69f18e12016-09-08 14:48:15 -07002153 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
2154 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
2155 }
2156#else
2157 if (motion_mode_allowed(mbmi) > SIMPLE_TRANSLATION)
2158 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
2159#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07002160#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002161
2162#if CONFIG_EXT_INTER
2163 if (cm->reference_mode != SINGLE_REFERENCE &&
Sarah Parker6fdc8532016-11-16 17:47:13 -08002164 is_inter_compound_mode(mbmi->mode)
Yue Chencb60b182016-10-13 15:18:22 -07002165#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002166 && mbmi->motion_mode == SIMPLE_TRANSLATION
Yue Chencb60b182016-10-13 15:18:22 -07002167#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002168 ) {
2169 counts->compound_interinter[bsize]
2170 [mbmi->interinter_compound_data.type]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002171 }
2172#endif // CONFIG_EXT_INTER
2173 }
2174 }
2175
2176 if (inter_block &&
2177 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08002178 int16_t mode_ctx;
2179#if !CONFIG_REF_MV
2180 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
2181#endif
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002182 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002183 const PREDICTION_MODE mode = mbmi->mode;
2184#if CONFIG_REF_MV
2185#if CONFIG_EXT_INTER
2186 if (has_second_ref(mbmi)) {
2187 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
2188 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2189 } else {
2190#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002191 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2192 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002193 update_inter_mode_stats(counts, mode,
2194#if CONFIG_EXT_INTER
2195 has_second_ref(mbmi),
2196#endif // CONFIG_EXT_INTER
2197 mode_ctx);
2198
2199 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002200 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002201 int idx;
2202
2203 for (idx = 0; idx < 2; ++idx) {
2204 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2205 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002206 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002207 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
2208
2209 if (mbmi->ref_mv_idx == idx) break;
2210 }
2211 }
2212 }
2213
2214 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002215 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002216 int idx;
2217
2218 for (idx = 1; idx < 3; ++idx) {
2219 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2220 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002221 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002222 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2223
2224 if (mbmi->ref_mv_idx == idx - 1) break;
2225 }
2226 }
2227 }
2228#if CONFIG_EXT_INTER
2229 }
2230#endif // CONFIG_EXT_INTER
2231#else
2232#if CONFIG_EXT_INTER
2233 if (is_inter_compound_mode(mode))
2234 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2235 else
2236#endif // CONFIG_EXT_INTER
2237 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2238#endif
2239 } else {
2240 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2241 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2242 int idx, idy;
2243 for (idy = 0; idy < 2; idy += num_4x4_h) {
2244 for (idx = 0; idx < 2; idx += num_4x4_w) {
2245 const int j = idy * 2 + idx;
2246 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2247#if CONFIG_REF_MV
2248#if CONFIG_EXT_INTER
2249 if (has_second_ref(mbmi)) {
2250 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002251 ++counts->inter_compound_mode[mode_ctx]
2252 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002253 } else {
2254#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002255 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2256 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002257 update_inter_mode_stats(counts, b_mode,
2258#if CONFIG_EXT_INTER
2259 has_second_ref(mbmi),
2260#endif // CONFIG_EXT_INTER
2261 mode_ctx);
2262#if CONFIG_EXT_INTER
2263 }
2264#endif // CONFIG_EXT_INTER
2265#else
2266#if CONFIG_EXT_INTER
2267 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002268 ++counts->inter_compound_mode[mode_ctx]
2269 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002270 else
2271#endif // CONFIG_EXT_INTER
2272 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2273#endif
2274 }
2275 }
2276 }
2277 }
2278 }
2279}
2280
2281typedef struct {
2282 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2283 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2284 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2285 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2286#if CONFIG_VAR_TX
2287 TXFM_CONTEXT *p_ta;
2288 TXFM_CONTEXT *p_tl;
2289 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2290 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2291#endif
2292} RD_SEARCH_MACROBLOCK_CONTEXT;
2293
2294static void restore_context(MACROBLOCK *x,
2295 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002296 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002297#if CONFIG_PVQ
2298 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002299#endif
2300 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002301 MACROBLOCKD *xd = &x->e_mbd;
2302 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002303 const int num_4x4_blocks_wide =
2304 block_size_wide[bsize] >> tx_size_wide_log2[0];
2305 const int num_4x4_blocks_high =
2306 block_size_high[bsize] >> tx_size_high_log2[0];
2307 int mi_width = mi_size_wide[bsize];
2308 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002309 for (p = 0; p < MAX_MB_PLANE; p++) {
2310 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2311 ctx->a + num_4x4_blocks_wide * p,
2312 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2313 xd->plane[p].subsampling_x);
2314 memcpy(xd->left_context[p] +
2315 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2316 ctx->l + num_4x4_blocks_high * p,
2317 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2318 xd->plane[p].subsampling_y);
2319 }
2320 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2321 sizeof(*xd->above_seg_context) * mi_width);
2322 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2323 sizeof(xd->left_seg_context[0]) * mi_height);
2324#if CONFIG_VAR_TX
2325 xd->above_txfm_context = ctx->p_ta;
2326 xd->left_txfm_context = ctx->p_tl;
2327 memcpy(xd->above_txfm_context, ctx->ta,
2328 sizeof(*xd->above_txfm_context) * mi_width);
2329 memcpy(xd->left_txfm_context, ctx->tl,
2330 sizeof(*xd->left_txfm_context) * mi_height);
2331#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002332#if CONFIG_PVQ
2333 od_encode_rollback(&x->daala_enc, rdo_buf);
2334#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002335}
2336
2337static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002338 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002339#if CONFIG_PVQ
2340 od_rollback_buffer *rdo_buf,
2341#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002342 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002343 const MACROBLOCKD *xd = &x->e_mbd;
2344 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002345 const int num_4x4_blocks_wide =
2346 block_size_wide[bsize] >> tx_size_wide_log2[0];
2347 const int num_4x4_blocks_high =
2348 block_size_high[bsize] >> tx_size_high_log2[0];
2349 int mi_width = mi_size_wide[bsize];
2350 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351
2352 // buffer the above/left context information of the block in search.
2353 for (p = 0; p < MAX_MB_PLANE; ++p) {
2354 memcpy(ctx->a + num_4x4_blocks_wide * p,
2355 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2356 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2357 xd->plane[p].subsampling_x);
2358 memcpy(ctx->l + num_4x4_blocks_high * p,
2359 xd->left_context[p] +
2360 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2361 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2362 xd->plane[p].subsampling_y);
2363 }
2364 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2365 sizeof(*xd->above_seg_context) * mi_width);
2366 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2367 sizeof(xd->left_seg_context[0]) * mi_height);
2368#if CONFIG_VAR_TX
2369 memcpy(ctx->ta, xd->above_txfm_context,
2370 sizeof(*xd->above_txfm_context) * mi_width);
2371 memcpy(ctx->tl, xd->left_txfm_context,
2372 sizeof(*xd->left_txfm_context) * mi_height);
2373 ctx->p_ta = xd->above_txfm_context;
2374 ctx->p_tl = xd->left_txfm_context;
2375#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002376#if CONFIG_PVQ
2377 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2378#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002379}
2380
Urvang Joshi52648442016-10-13 17:27:51 -07002381static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2382 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2383 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002384#if CONFIG_EXT_PARTITION_TYPES
2385 PARTITION_TYPE partition,
2386#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002387 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002388 MACROBLOCK *const x = &td->mb;
Yue Chenf27b1602017-01-13 11:11:43 -08002389#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2390 MACROBLOCKD *xd = &x->e_mbd;
2391 MB_MODE_INFO *mbmi;
2392 int check_ncobmc;
2393#endif
2394
Yaowu Xuc27fc142016-08-22 16:08:15 -07002395 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2396#if CONFIG_EXT_PARTITION_TYPES
2397 x->e_mbd.mi[0]->mbmi.partition = partition;
2398#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002399 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
Yue Chenf27b1602017-01-13 11:11:43 -08002400#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2401 mbmi = &xd->mi[0]->mbmi;
2402 check_ncobmc =
2403 is_inter_block(mbmi) && motion_mode_allowed(mbmi) >= OBMC_CAUSAL;
2404 if (!dry_run && check_ncobmc) {
2405 av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
2406 av1_setup_dst_planes(x->e_mbd.plane, get_frame_new_buffer(&cpi->common),
2407 mi_row, mi_col);
2408 }
2409#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002410 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002411
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002412 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002414 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002415#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002416 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417#endif
2418 }
2419}
2420
Urvang Joshi52648442016-10-13 17:27:51 -07002421static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2422 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2423 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2424 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002425 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002426 MACROBLOCK *const x = &td->mb;
2427 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse55c6bde2017-01-12 15:55:31 -08002428 const int hbs = mi_size_wide[bsize] / 2;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002429 const int is_partition_root = bsize >= BLOCK_8X8;
2430 const int ctx = is_partition_root
Alex Converse55c6bde2017-01-12 15:55:31 -08002431 ? partition_plane_context(xd, mi_row, mi_col,
2432#if CONFIG_UNPOISON_PARTITION_CTX
2433 mi_row + hbs < cm->mi_rows,
2434 mi_col + hbs < cm->mi_cols,
2435#endif
2436 bsize)
2437 : -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002438 const PARTITION_TYPE partition = pc_tree->partitioning;
2439 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2440#if CONFIG_EXT_PARTITION_TYPES
2441 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2442#endif
2443
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002444#if CONFIG_CB4X4
2445 const int unify_bsize = 1;
2446#else
2447 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448 assert(bsize >= BLOCK_8X8);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002449#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450
2451 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2452
Alex Converse55c6bde2017-01-12 15:55:31 -08002453 if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002454
2455#if CONFIG_SUPERTX
2456 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2457 partition != PARTITION_NONE && !xd->lossless[0]) {
2458 int supertx_enabled;
2459 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2460 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2461 if (supertx_enabled) {
Jingning Han5b7706a2016-12-21 09:55:10 -08002462 const int mi_width = mi_size_wide[bsize];
2463 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002464 int x_idx, y_idx, i;
2465 uint8_t *dst_buf[3];
2466 int dst_stride[3];
2467 set_skip_context(xd, mi_row, mi_col);
2468 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002469 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2470 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002471
Yaowu Xuf883b422016-08-30 14:01:10 -07002472 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002473 for (i = 0; i < MAX_MB_PLANE; i++) {
2474 dst_buf[i] = xd->plane[i].dst.buf;
2475 dst_stride[i] = xd->plane[i].dst.stride;
2476 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002477 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2478 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002479
2480 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2481 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2482
2483 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002484 int this_rate = 0;
Angie Chiangff6d8902016-10-21 11:02:09 -07002485 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002486 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2487 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002488 } else {
2489 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002490 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 reset_skip_context(xd, bsize);
2492 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002493 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494 for (y_idx = 0; y_idx < mi_height; y_idx++)
2495 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2496 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2497 x_idx &&
2498 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2499 y_idx) {
2500 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2501 xd->mi[0]->mbmi.skip;
2502 }
2503 }
2504 td->counts->supertx[partition_supertx_context_lookup[partition]]
2505 [supertx_size][1]++;
2506 td->counts->supertx_size[supertx_size]++;
2507#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002508 if (get_ext_tx_types(supertx_size, bsize, 1, cm->reduced_tx_set_used) >
2509 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510 !xd->mi[0]->mbmi.skip) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08002511 const int eset =
2512 get_ext_tx_set(supertx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002513 if (eset > 0) {
clang-format55ce9e02017-02-15 22:27:12 -08002514 ++td->counts
2515 ->inter_ext_tx[eset][supertx_size][xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002516 }
2517 }
2518#else
2519 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2520 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2521 }
2522#endif // CONFIG_EXT_TX
2523 }
2524#if CONFIG_EXT_PARTITION_TYPES
2525 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2526 partition);
2527#else
2528 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2529 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2530#endif
2531#if CONFIG_VAR_TX
Yaowu Xu52a17632016-11-17 15:48:21 -08002532 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2533 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002534#endif // CONFIG_VAR_TX
2535 return;
2536 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002537 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002538 td->counts->supertx[partition_supertx_context_lookup[partition]]
2539 [supertx_size][0]++;
2540 }
2541 }
2542 }
2543#endif // CONFIG_SUPERTX
2544
2545 switch (partition) {
2546 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002547 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548#if CONFIG_EXT_PARTITION_TYPES
2549 partition,
2550#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002551 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002552 break;
2553 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002554 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002555#if CONFIG_EXT_PARTITION_TYPES
2556 partition,
2557#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002558 &pc_tree->vertical[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002559 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002560 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002561#if CONFIG_EXT_PARTITION_TYPES
2562 partition,
2563#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002564 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002565 }
2566 break;
2567 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002568 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569#if CONFIG_EXT_PARTITION_TYPES
2570 partition,
2571#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002572 &pc_tree->horizontal[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002573 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002574 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575#if CONFIG_EXT_PARTITION_TYPES
2576 partition,
2577#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002578 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002579 }
2580 break;
2581 case PARTITION_SPLIT:
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002582 if (bsize == BLOCK_8X8 && !unify_bsize) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002583 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002584#if CONFIG_EXT_PARTITION_TYPES
2585 partition,
2586#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002587 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002589 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2590 pc_tree->split[0], rate);
2591 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2592 pc_tree->split[1], rate);
2593 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2594 pc_tree->split[2], rate);
2595 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2596 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002597 }
2598 break;
2599#if CONFIG_EXT_PARTITION_TYPES
2600 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002601 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2602 &pc_tree->horizontala[0], rate);
2603 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2604 partition, &pc_tree->horizontala[1], rate);
2605 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2606 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002607 break;
2608 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002609 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2610 &pc_tree->horizontalb[0], rate);
2611 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2612 partition, &pc_tree->horizontalb[1], rate);
2613 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2614 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615 break;
2616 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002617 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2618 &pc_tree->verticala[0], rate);
2619 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2620 partition, &pc_tree->verticala[1], rate);
2621 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2622 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002623
2624 break;
2625 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002626 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2627 &pc_tree->verticalb[0], rate);
2628 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2629 partition, &pc_tree->verticalb[1], rate);
2630 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2631 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002632 break;
2633#endif // CONFIG_EXT_PARTITION_TYPES
2634 default: assert(0 && "Invalid partition type."); break;
2635 }
2636
2637#if CONFIG_EXT_PARTITION_TYPES
2638 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2639#else
2640 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2641 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2642#endif // CONFIG_EXT_PARTITION_TYPES
2643}
2644
2645// Check to see if the given partition size is allowed for a specified number
2646// of mi block rows and columns remaining in the image.
2647// If not then return the largest allowed partition size
2648static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2649 int cols_left, int *bh, int *bw) {
2650 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002651 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002652 } else {
2653 for (; bsize > 0; bsize -= 3) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08002654 *bh = mi_size_high[bsize];
2655 *bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002656 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2657 break;
2658 }
2659 }
2660 }
2661 return bsize;
2662}
2663
Yaowu Xuf883b422016-08-30 14:01:10 -07002664static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002665 int bh_in, int bw_in,
2666 int mi_rows_remaining,
2667 int mi_cols_remaining, BLOCK_SIZE bsize,
2668 MODE_INFO **mib) {
2669 int bh = bh_in;
2670 int r, c;
2671 for (r = 0; r < cm->mib_size; r += bh) {
2672 int bw = bw_in;
2673 for (c = 0; c < cm->mib_size; c += bw) {
2674 const int index = r * cm->mi_stride + c;
2675 mib[index] = mi + index;
2676 mib[index]->mbmi.sb_type = find_partition_size(
2677 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2678 }
2679 }
2680}
2681
2682// This function attempts to set all mode info entries in a given superblock
2683// to the same block partition size.
2684// However, at the bottom and right borders of the image the requested size
2685// may not be allowed in which case this code attempts to choose the largest
2686// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002687static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002688 MODE_INFO **mib, int mi_row, int mi_col,
2689 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002690 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002691 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2692 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2693 int block_row, block_col;
2694 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002695 int bh = mi_size_high[bsize];
2696 int bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002697
2698 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2699
2700 // Apply the requested partition size to the SB if it is all "in image"
2701 if ((mi_cols_remaining >= cm->mib_size) &&
2702 (mi_rows_remaining >= cm->mib_size)) {
2703 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2704 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2705 int index = block_row * cm->mi_stride + block_col;
2706 mib[index] = mi_upper_left + index;
2707 mib[index]->mbmi.sb_type = bsize;
2708 }
2709 }
2710 } else {
2711 // Else this is a partial SB.
2712 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2713 mi_cols_remaining, bsize, mib);
2714 }
2715}
2716
Yaowu Xuf883b422016-08-30 14:01:10 -07002717static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002718 TileDataEnc *tile_data, MODE_INFO **mib,
2719 TOKENEXTRA **tp, int mi_row, int mi_col,
2720 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2721#if CONFIG_SUPERTX
2722 int *rate_nocoef,
2723#endif
2724 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002725 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002726 TileInfo *const tile_info = &tile_data->tile_info;
2727 MACROBLOCK *const x = &td->mb;
2728 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002729 const int bs = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002730 const int hbs = bs / 2;
2731 int i;
Alex Converse55c6bde2017-01-12 15:55:31 -08002732 const int pl = partition_plane_context(xd, mi_row, mi_col,
2733#if CONFIG_UNPOISON_PARTITION_CTX
2734 mi_row + hbs < cm->mi_rows,
2735 mi_col + hbs < cm->mi_cols,
2736#endif
2737 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002738 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2739 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2740 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2741 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2742 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2743 int splits_below = 0;
2744 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2745 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002746 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747#if CONFIG_SUPERTX
2748 int last_part_rate_nocoef = INT_MAX;
2749 int none_rate_nocoef = INT_MAX;
2750 int chosen_rate_nocoef = INT_MAX;
2751#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002752#if CONFIG_PVQ
2753 od_rollback_buffer pre_rdo_buf;
2754#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002755 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2756
2757 assert(num_4x4_blocks_wide_lookup[bsize] ==
2758 num_4x4_blocks_high_lookup[bsize]);
2759
Yaowu Xuf883b422016-08-30 14:01:10 -07002760 av1_rd_cost_reset(&last_part_rdc);
2761 av1_rd_cost_reset(&none_rdc);
2762 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002763
2764 pc_tree->partitioning = partition;
2765
2766#if CONFIG_VAR_TX
2767 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2768 xd->left_txfm_context =
2769 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2770#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002771#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002772 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002773#else
2774 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2775#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002776
2777 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2778 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002779 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002780 }
2781
2782 if (do_partition_search &&
2783 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2784 cpi->sf.adjust_partitioning_from_last_frame) {
2785 // Check if any of the sub blocks are further split.
2786 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2787 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2788 splits_below = 1;
2789 for (i = 0; i < 4; i++) {
2790 int jj = i >> 1, ii = i & 0x01;
2791 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2792 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2793 splits_below = 0;
2794 }
2795 }
2796 }
2797
2798 // If partition is not none try none unless each of the 4 splits are split
2799 // even further..
2800 if (partition != PARTITION_NONE && !splits_below &&
2801 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2802 pc_tree->partitioning = PARTITION_NONE;
2803 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2804#if CONFIG_SUPERTX
2805 &none_rate_nocoef,
2806#endif
2807#if CONFIG_EXT_PARTITION_TYPES
2808 PARTITION_NONE,
2809#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002810 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002811
2812 if (none_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08002813 none_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
2814 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002815 none_rdc.rdcost =
2816 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2817#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08002818 none_rate_nocoef +=
2819 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
2820 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002821#endif
2822 }
2823
Yushin Cho77bba8d2016-11-04 16:36:56 -07002824#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002826#else
2827 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2828#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829 mib[0]->mbmi.sb_type = bs_type;
2830 pc_tree->partitioning = partition;
2831 }
2832 }
2833
2834 switch (partition) {
2835 case PARTITION_NONE:
2836 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2837#if CONFIG_SUPERTX
2838 &last_part_rate_nocoef,
2839#endif
2840#if CONFIG_EXT_PARTITION_TYPES
2841 PARTITION_NONE,
2842#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002843 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 break;
2845 case PARTITION_HORZ:
2846 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2847#if CONFIG_SUPERTX
2848 &last_part_rate_nocoef,
2849#endif
2850#if CONFIG_EXT_PARTITION_TYPES
2851 PARTITION_HORZ,
2852#endif
2853 subsize, &pc_tree->horizontal[0], INT64_MAX);
2854 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2855 mi_row + hbs < cm->mi_rows) {
2856 RD_COST tmp_rdc;
2857#if CONFIG_SUPERTX
2858 int rt_nocoef = 0;
2859#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002860 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002861 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002862 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002863 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002864 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002865 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2866#if CONFIG_SUPERTX
2867 &rt_nocoef,
2868#endif
2869#if CONFIG_EXT_PARTITION_TYPES
2870 PARTITION_HORZ,
2871#endif
2872 subsize, &pc_tree->horizontal[1], INT64_MAX);
2873 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002874 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002875#if CONFIG_SUPERTX
2876 last_part_rate_nocoef = INT_MAX;
2877#endif
2878 break;
2879 }
2880 last_part_rdc.rate += tmp_rdc.rate;
2881 last_part_rdc.dist += tmp_rdc.dist;
2882 last_part_rdc.rdcost += tmp_rdc.rdcost;
2883#if CONFIG_SUPERTX
2884 last_part_rate_nocoef += rt_nocoef;
2885#endif
2886 }
2887 break;
2888 case PARTITION_VERT:
2889 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2890#if CONFIG_SUPERTX
2891 &last_part_rate_nocoef,
2892#endif
2893#if CONFIG_EXT_PARTITION_TYPES
2894 PARTITION_VERT,
2895#endif
2896 subsize, &pc_tree->vertical[0], INT64_MAX);
2897 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2898 mi_col + hbs < cm->mi_cols) {
2899 RD_COST tmp_rdc;
2900#if CONFIG_SUPERTX
2901 int rt_nocoef = 0;
2902#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002903 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002904 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002905 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002906 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002907 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002908 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2909#if CONFIG_SUPERTX
2910 &rt_nocoef,
2911#endif
2912#if CONFIG_EXT_PARTITION_TYPES
2913 PARTITION_VERT,
2914#endif
2915 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2916 INT64_MAX);
2917 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002918 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002919#if CONFIG_SUPERTX
2920 last_part_rate_nocoef = INT_MAX;
2921#endif
2922 break;
2923 }
2924 last_part_rdc.rate += tmp_rdc.rate;
2925 last_part_rdc.dist += tmp_rdc.dist;
2926 last_part_rdc.rdcost += tmp_rdc.rdcost;
2927#if CONFIG_SUPERTX
2928 last_part_rate_nocoef += rt_nocoef;
2929#endif
2930 }
2931 break;
2932 case PARTITION_SPLIT:
2933 if (bsize == BLOCK_8X8) {
2934 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2935#if CONFIG_SUPERTX
2936 &last_part_rate_nocoef,
2937#endif
2938#if CONFIG_EXT_PARTITION_TYPES
2939 PARTITION_SPLIT,
2940#endif
2941 subsize, pc_tree->leaf_split[0], INT64_MAX);
2942 break;
2943 }
2944 last_part_rdc.rate = 0;
2945 last_part_rdc.dist = 0;
2946 last_part_rdc.rdcost = 0;
2947#if CONFIG_SUPERTX
2948 last_part_rate_nocoef = 0;
2949#endif
2950 for (i = 0; i < 4; i++) {
2951 int x_idx = (i & 1) * hbs;
2952 int y_idx = (i >> 1) * hbs;
2953 int jj = i >> 1, ii = i & 0x01;
2954 RD_COST tmp_rdc;
2955#if CONFIG_SUPERTX
2956 int rt_nocoef;
2957#endif
2958 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2959 continue;
2960
Yaowu Xuf883b422016-08-30 14:01:10 -07002961 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002962 rd_use_partition(cpi, td, tile_data,
2963 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2964 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2965 &tmp_rdc.dist,
2966#if CONFIG_SUPERTX
2967 &rt_nocoef,
2968#endif
2969 i != 3, pc_tree->split[i]);
2970 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002971 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002972#if CONFIG_SUPERTX
2973 last_part_rate_nocoef = INT_MAX;
2974#endif
2975 break;
2976 }
2977 last_part_rdc.rate += tmp_rdc.rate;
2978 last_part_rdc.dist += tmp_rdc.dist;
2979#if CONFIG_SUPERTX
2980 last_part_rate_nocoef += rt_nocoef;
2981#endif
2982 }
2983 break;
2984#if CONFIG_EXT_PARTITION_TYPES
2985 case PARTITION_VERT_A:
2986 case PARTITION_VERT_B:
2987 case PARTITION_HORZ_A:
2988 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2989#endif // CONFIG_EXT_PARTITION_TYPES
2990 default: assert(0); break;
2991 }
2992
2993 if (last_part_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08002994 last_part_rdc.rate +=
2995 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002996 last_part_rdc.rdcost =
2997 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2998#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08002999 last_part_rate_nocoef +=
3000 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001#endif
3002 }
3003
3004 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
3005 cpi->sf.partition_search_type == SEARCH_PARTITION &&
3006 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
3007 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
3008 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
3009 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
3010 chosen_rdc.rate = 0;
3011 chosen_rdc.dist = 0;
3012#if CONFIG_SUPERTX
3013 chosen_rate_nocoef = 0;
3014#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003015#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003017#else
3018 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3019#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003020 pc_tree->partitioning = PARTITION_SPLIT;
3021
3022 // Split partition.
3023 for (i = 0; i < 4; i++) {
3024 int x_idx = (i & 1) * hbs;
3025 int y_idx = (i >> 1) * hbs;
3026 RD_COST tmp_rdc;
3027#if CONFIG_SUPERTX
3028 int rt_nocoef = 0;
3029#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003030#if CONFIG_PVQ
3031 od_rollback_buffer buf;
3032#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003033 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
3034 continue;
3035
Yushin Cho77bba8d2016-11-04 16:36:56 -07003036#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003037 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003038#else
3039 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
3040#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003041 pc_tree->split[i]->partitioning = PARTITION_NONE;
3042 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
3043 &tmp_rdc,
3044#if CONFIG_SUPERTX
3045 &rt_nocoef,
3046#endif
3047#if CONFIG_EXT_PARTITION_TYPES
3048 PARTITION_SPLIT,
3049#endif
3050 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
3051
Yushin Cho77bba8d2016-11-04 16:36:56 -07003052#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003053 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003054#else
3055 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
3056#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003057 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003058 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059#if CONFIG_SUPERTX
3060 chosen_rate_nocoef = INT_MAX;
3061#endif
3062 break;
3063 }
3064
3065 chosen_rdc.rate += tmp_rdc.rate;
3066 chosen_rdc.dist += tmp_rdc.dist;
3067#if CONFIG_SUPERTX
3068 chosen_rate_nocoef += rt_nocoef;
3069#endif
3070
3071 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003072 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
3073 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003074
Alex Converse55c6bde2017-01-12 15:55:31 -08003075 chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3076 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003077#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003078 chosen_rate_nocoef +=
3079 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3080 [PARTITION_SPLIT];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003081#endif
3082 }
3083 if (chosen_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08003084 chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3085 [PARTITION_SPLIT];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003086 chosen_rdc.rdcost =
3087 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
3088#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003089 chosen_rate_nocoef +=
3090 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3091 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092#endif
3093 }
3094 }
3095
3096 // If last_part is better set the partitioning to that.
3097 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
3098 mib[0]->mbmi.sb_type = bsize;
3099 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
3100 chosen_rdc = last_part_rdc;
3101#if CONFIG_SUPERTX
3102 chosen_rate_nocoef = last_part_rate_nocoef;
3103#endif
3104 }
3105 // If none was better set the partitioning to that.
3106 if (none_rdc.rdcost < chosen_rdc.rdcost) {
3107 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
3108 chosen_rdc = none_rdc;
3109#if CONFIG_SUPERTX
3110 chosen_rate_nocoef = none_rate_nocoef;
3111#endif
3112 }
3113
Yushin Cho77bba8d2016-11-04 16:36:56 -07003114#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003115 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003116#else
3117 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3118#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003119
3120 // We must have chosen a partitioning and encoding or we'll fail later on.
3121 // No other opportunities for success.
3122 if (bsize == cm->sb_size)
3123 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
3124
3125 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003126 if (bsize == cm->sb_size) {
3127 // NOTE: To get estimate for rate due to the tokens, use:
3128 // int rate_coeffs = 0;
3129 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
3130 // bsize, pc_tree, &rate_coeffs);
3131 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
3132 pc_tree, NULL);
3133 } else {
3134 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
3135 pc_tree, NULL);
3136 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003137 }
3138
3139 *rate = chosen_rdc.rate;
3140 *dist = chosen_rdc.dist;
3141#if CONFIG_SUPERTX
3142 *rate_nocoef = chosen_rate_nocoef;
3143#endif
3144}
3145
3146/* clang-format off */
3147static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003148#if CONFIG_CB4X4
3149 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3150#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003151 BLOCK_4X4, // 4x4
3152 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
3153 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
3154 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
3155 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
3156#if CONFIG_EXT_PARTITION
3157 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
3158#endif // CONFIG_EXT_PARTITION
3159};
3160
3161static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003162#if CONFIG_CB4X4
3163 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 2x2, 2x4, 4x2
3164#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003165 BLOCK_8X8, // 4x4
3166 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
3167 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
3168 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
3169 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
3170#if CONFIG_EXT_PARTITION
3171 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
3172#endif // CONFIG_EXT_PARTITION
3173};
3174
3175// Next square block size less or equal than current block size.
3176static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003177#if CONFIG_CB4X4
3178 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3179#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 BLOCK_4X4, // 4x4
3181 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
3182 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
3183 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
3184 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
3185#if CONFIG_EXT_PARTITION
3186 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
3187#endif // CONFIG_EXT_PARTITION
3188};
3189/* clang-format on */
3190
3191// Look at all the mode_info entries for blocks that are part of this
3192// partition and find the min and max values for sb_type.
3193// At the moment this is designed to work on a superblock but could be
3194// adjusted to use a size parameter.
3195//
3196// The min and max are assumed to have been initialized prior to calling this
3197// function so repeat calls can accumulate a min and max of more than one
3198// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07003199static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003200 MACROBLOCKD *xd, MODE_INFO **mib,
3201 BLOCK_SIZE *min_block_size,
3202 BLOCK_SIZE *max_block_size) {
3203 int i, j;
3204 int index = 0;
3205
3206 // Check the sb_type for each block that belongs to this region.
3207 for (i = 0; i < cm->mib_size; ++i) {
3208 for (j = 0; j < cm->mib_size; ++j) {
3209 MODE_INFO *mi = mib[index + j];
3210 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07003211 *min_block_size = AOMMIN(*min_block_size, sb_type);
3212 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003213 }
3214 index += xd->mi_stride;
3215 }
3216}
3217
3218// Look at neighboring blocks and set a min and max partition size based on
3219// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07003220static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221 MACROBLOCKD *const xd, int mi_row,
3222 int mi_col, BLOCK_SIZE *min_block_size,
3223 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003224 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003225 MODE_INFO **mi = xd->mi;
3226 const int left_in_image = xd->left_available && mi[-1];
3227 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3228 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3229 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3230 int bh, bw;
3231 BLOCK_SIZE min_size = BLOCK_4X4;
3232 BLOCK_SIZE max_size = BLOCK_LARGEST;
3233
3234 // Trap case where we do not have a prediction.
3235 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3236 // Default "min to max" and "max to min"
3237 min_size = BLOCK_LARGEST;
3238 max_size = BLOCK_4X4;
3239
3240 // NOTE: each call to get_sb_partition_size_range() uses the previous
3241 // passed in values for min and max as a starting point.
3242 // Find the min and max partition used in previous frame at this location
3243 if (cm->frame_type != KEY_FRAME) {
3244 MODE_INFO **prev_mi =
3245 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3246 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3247 }
3248 // Find the min and max partition sizes used in the left superblock
3249 if (left_in_image) {
3250 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3251 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3252 }
3253 // Find the min and max partition sizes used in the above suprblock.
3254 if (above_in_image) {
3255 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3256 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3257 }
3258
3259 // Adjust observed min and max for "relaxed" auto partition case.
3260 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3261 min_size = min_partition_size[min_size];
3262 max_size = max_partition_size[max_size];
3263 }
3264 }
3265
3266 // Check border cases where max and min from neighbors may not be legal.
3267 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3268 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07003269 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003270
3271 // Test for blocks at the edge of the active image.
3272 // This may be the actual edge of the image or where there are formatting
3273 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003274 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003275 min_size = BLOCK_4X4;
3276 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003277 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278 }
3279
3280 // When use_square_partition_only is true, make sure at least one square
3281 // partition is allowed by selecting the next smaller square size as
3282 // *min_block_size.
3283 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003284 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003285 }
3286
Yaowu Xuf883b422016-08-30 14:01:10 -07003287 *min_block_size = AOMMIN(min_size, cm->sb_size);
3288 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003289}
3290
3291// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003292static void set_partition_range(const AV1_COMMON *const cm,
3293 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003294 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003295 BLOCK_SIZE *const min_bs,
3296 BLOCK_SIZE *const max_bs) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08003297 const int mi_width = mi_size_wide[bsize];
3298 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003299 int idx, idy;
3300
Yaowu Xuc27fc142016-08-22 16:08:15 -07003301 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003302 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3303 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3304 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003305
3306 if (prev_mi) {
3307 for (idy = 0; idy < mi_height; ++idy) {
3308 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003309 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3310 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003311 min_size = AOMMIN(min_size, bs);
3312 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003313 }
3314 }
3315 }
3316
3317 if (xd->left_available) {
3318 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003319 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3320 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003321 min_size = AOMMIN(min_size, bs);
3322 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003323 }
3324 }
3325
3326 if (xd->up_available) {
3327 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003328 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3329 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003330 min_size = AOMMIN(min_size, bs);
3331 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332 }
3333 }
3334
3335 if (min_size == max_size) {
3336 min_size = min_partition_size[min_size];
3337 max_size = max_partition_size[max_size];
3338 }
3339
Yaowu Xuf883b422016-08-30 14:01:10 -07003340 *min_bs = AOMMIN(min_size, cm->sb_size);
3341 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003342}
3343
3344static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3345 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3346}
3347
3348static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3349 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3350}
3351
3352#if CONFIG_FP_MB_STATS
3353const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3354 0,
3355 10,
3356 10,
3357 30,
3358 40,
3359 40,
3360 60,
3361 80,
3362 80,
3363 90,
3364 100,
3365 100,
3366 120,
3367#if CONFIG_EXT_PARTITION
3368 // TODO(debargha): What are the correct numbers here?
3369 130,
3370 130,
3371 150
3372#endif // CONFIG_EXT_PARTITION
3373};
3374const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3375 0,
3376 3,
3377 3,
3378 7,
3379 15,
3380 15,
3381 30,
3382 40,
3383 40,
3384 60,
3385 80,
3386 80,
3387 120,
3388#if CONFIG_EXT_PARTITION
3389 // TODO(debargha): What are the correct numbers here?
3390 160,
3391 160,
3392 240
3393#endif // CONFIG_EXT_PARTITION
3394};
3395const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3396 1,
3397 1,
3398 1,
3399 1,
3400 1,
3401 1,
3402 1,
3403 1,
3404 1,
3405 1,
3406 4,
3407 4,
Yaowu Xu17fd2f22016-11-17 18:23:28 -08003408 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003409#if CONFIG_EXT_PARTITION
3410 // TODO(debargha): What are the correct numbers here?
3411 8,
3412 8,
3413 10
3414#endif // CONFIG_EXT_PARTITION
3415};
3416
3417typedef enum {
3418 MV_ZERO = 0,
3419 MV_LEFT = 1,
3420 MV_UP = 2,
3421 MV_RIGHT = 3,
3422 MV_DOWN = 4,
3423 MV_INVALID
3424} MOTION_DIRECTION;
3425
3426static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3427 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3428 return MV_ZERO;
3429 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3430 return MV_LEFT;
3431 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3432 return MV_RIGHT;
3433 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3434 return MV_UP;
3435 } else {
3436 return MV_DOWN;
3437 }
3438}
3439
3440static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3441 MOTION_DIRECTION that_mv) {
3442 if (this_mv == that_mv) {
3443 return 0;
3444 } else {
3445 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3446 }
3447}
3448#endif
3449
3450#if CONFIG_EXT_PARTITION_TYPES
3451static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003452 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3453 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3454 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3455 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003456#if CONFIG_SUPERTX
3457 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3458#endif
3459 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3460 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3461 MACROBLOCK *const x = &td->mb;
3462 MACROBLOCKD *const xd = &x->e_mbd;
3463 RD_COST this_rdc, sum_rdc;
3464#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003465 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003466 TileInfo *const tile_info = &tile_data->tile_info;
3467 int this_rate_nocoef, sum_rate_nocoef;
3468 int abort_flag;
3469 const int supertx_allowed = !frame_is_intra_only(cm) &&
3470 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3471 !xd->lossless[0];
3472#endif
3473 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3474
3475 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3476#if CONFIG_SUPERTX
3477 &sum_rate_nocoef,
3478#endif
3479#if CONFIG_EXT_PARTITION_TYPES
3480 partition,
3481#endif
3482 subsize0, &ctxs[0], best_rdc->rdcost);
3483#if CONFIG_SUPERTX
3484 abort_flag = sum_rdc.rdcost >= best_rd;
3485#endif
3486
3487#if CONFIG_SUPERTX
3488 if (sum_rdc.rdcost < INT64_MAX) {
3489#else
3490 if (sum_rdc.rdcost < best_rdc->rdcost) {
3491#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003492 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3493 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003494 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003495 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496
Urvang Joshi368fbc92016-10-17 16:31:34 -07003497 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003498
3499#if CONFIG_SUPERTX
3500 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3501 &this_rate_nocoef,
3502#if CONFIG_EXT_PARTITION_TYPES
3503 partition,
3504#endif
3505 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3506#else
3507 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3508#if CONFIG_EXT_PARTITION_TYPES
3509 partition,
3510#endif
3511 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3512#endif // CONFIG_SUPERTX
3513
3514 if (this_rdc.rate == INT_MAX) {
3515 sum_rdc.rdcost = INT64_MAX;
3516#if CONFIG_SUPERTX
3517 sum_rate_nocoef = INT_MAX;
3518#endif
3519 } else {
3520 sum_rdc.rate += this_rdc.rate;
3521 sum_rdc.dist += this_rdc.dist;
3522 sum_rdc.rdcost += this_rdc.rdcost;
3523#if CONFIG_SUPERTX
3524 sum_rate_nocoef += this_rate_nocoef;
3525#endif
3526 }
3527
3528#if CONFIG_SUPERTX
3529 if (sum_rdc.rdcost < INT64_MAX) {
3530#else
3531 if (sum_rdc.rdcost < best_rdc->rdcost) {
3532#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003533 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3534 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003535 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003536 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003537
Urvang Joshi368fbc92016-10-17 16:31:34 -07003538 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003539
3540#if CONFIG_SUPERTX
3541 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3542 &this_rate_nocoef,
3543#if CONFIG_EXT_PARTITION_TYPES
3544 partition,
3545#endif
3546 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3547#else
3548 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3549#if CONFIG_EXT_PARTITION_TYPES
3550 partition,
3551#endif
3552 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3553#endif // CONFIG_SUPERTX
3554
3555 if (this_rdc.rate == INT_MAX) {
3556 sum_rdc.rdcost = INT64_MAX;
3557#if CONFIG_SUPERTX
3558 sum_rate_nocoef = INT_MAX;
3559#endif
3560 } else {
3561 sum_rdc.rate += this_rdc.rate;
3562 sum_rdc.dist += this_rdc.dist;
3563 sum_rdc.rdcost += this_rdc.rdcost;
3564#if CONFIG_SUPERTX
3565 sum_rate_nocoef += this_rate_nocoef;
3566#endif
3567 }
3568
3569#if CONFIG_SUPERTX
3570 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3571 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3572 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3573 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003574 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003575 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3576 [supertx_size],
3577 0);
3578 sum_rdc.rdcost =
3579 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3580
3581 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3582 TX_TYPE best_tx = DCT_DCT;
3583 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3584
3585 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3586
3587 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3588 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3589
Yaowu Xuf883b422016-08-30 14:01:10 -07003590 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003591 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3592 [supertx_size],
3593 1);
3594 tmp_rdc.rdcost =
3595 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3596 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3597 sum_rdc = tmp_rdc;
3598 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3599 supertx_size, pc_tree);
3600 }
3601 }
3602
3603 pc_tree->partitioning = best_partition;
3604 }
3605#endif // CONFIG_SUPERTX
3606
3607 if (sum_rdc.rdcost < best_rdc->rdcost) {
Alex Converse55c6bde2017-01-12 15:55:31 -08003608 int pl = partition_plane_context(xd, mi_row, mi_col,
3609#if CONFIG_UNPOISON_PARTITION_CTX
3610 has_rows, has_cols,
3611#endif
3612 bsize);
3613 sum_rdc.rate +=
3614 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003615 sum_rdc.rdcost =
3616 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3617#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003618 sum_rate_nocoef +=
3619 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620#endif
3621 if (sum_rdc.rdcost < best_rdc->rdcost) {
3622#if CONFIG_SUPERTX
3623 *best_rate_nocoef = sum_rate_nocoef;
3624 assert(*best_rate_nocoef >= 0);
3625#endif
3626 *best_rdc = sum_rdc;
3627 pc_tree->partitioning = partition;
3628 }
3629 }
3630 }
3631 }
3632}
3633#endif // CONFIG_EXT_PARTITION_TYPES
3634
3635// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3636// unlikely to be selected depending on previous rate-distortion optimization
3637// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003638static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003639 TileDataEnc *tile_data, TOKENEXTRA **tp,
3640 int mi_row, int mi_col, BLOCK_SIZE bsize,
3641 RD_COST *rd_cost,
3642#if CONFIG_SUPERTX
3643 int *rate_nocoef,
3644#endif
3645 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003646 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003647 TileInfo *const tile_info = &tile_data->tile_info;
3648 MACROBLOCK *const x = &td->mb;
3649 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08003650 const int mi_step = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003651 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003652 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003653 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Alex Converse55c6bde2017-01-12 15:55:31 -08003654#if CONFIG_UNPOISON_PARTITION_CTX
3655 const int hbs = mi_size_wide[bsize] / 2;
3656 const int has_rows = mi_row + hbs < cm->mi_rows;
3657 const int has_cols = mi_col + hbs < cm->mi_cols;
3658#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003659 int tmp_partition_cost[PARTITION_TYPES];
Alex Converse55c6bde2017-01-12 15:55:31 -08003660#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003661 BLOCK_SIZE subsize;
3662 RD_COST this_rdc, sum_rdc, best_rdc;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003663 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3664 int do_square_split = bsize_at_least_8x8;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003665#if CONFIG_CB4X4
3666 const int unify_bsize = 1;
3667 const int pl = bsize_at_least_8x8
Alex Converse55c6bde2017-01-12 15:55:31 -08003668 ? partition_plane_context(xd, mi_row, mi_col,
3669#if CONFIG_UNPOISON_PARTITION_CTX
3670 has_rows, has_cols,
3671#endif
3672 bsize)
3673 : -1;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003674#else
3675 const int unify_bsize = 0;
Alex Converse55c6bde2017-01-12 15:55:31 -08003676 const int pl = partition_plane_context(xd, mi_row, mi_col,
3677#if CONFIG_UNPOISON_PARTITION_CTX
3678 has_rows, has_cols,
3679#endif
3680 bsize);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003681#endif // CONFIG_CB4X4
Alex Converse55c6bde2017-01-12 15:55:31 -08003682 const int *partition_cost =
3683 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003684#if CONFIG_SUPERTX
3685 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3686 int abort_flag;
3687 const int supertx_allowed = !frame_is_intra_only(cm) &&
3688 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3689 !xd->lossless[0];
3690#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003691
Urvang Joshi52648442016-10-13 17:27:51 -07003692 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003693#if CONFIG_EXT_PARTITION_TYPES
3694 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3695#endif
3696
3697 // Override skipping rectangular partition operations for edge blocks
3698 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3699 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3700 const int xss = x->e_mbd.plane[1].subsampling_x;
3701 const int yss = x->e_mbd.plane[1].subsampling_y;
3702
3703 BLOCK_SIZE min_size = x->min_partition_size;
3704 BLOCK_SIZE max_size = x->max_partition_size;
3705
3706#if CONFIG_FP_MB_STATS
3707 unsigned int src_diff_var = UINT_MAX;
3708 int none_complexity = 0;
3709#endif
3710
3711 int partition_none_allowed = !force_horz_split && !force_vert_split;
3712 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003713 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003715 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003716
3717#if CONFIG_PVQ
3718 od_rollback_buffer pre_rdo_buf;
3719#endif
3720
Yaowu Xuc27fc142016-08-22 16:08:15 -07003721 (void)*tp_orig;
3722
Alex Converse55c6bde2017-01-12 15:55:31 -08003723#if !CONFIG_UNPOISON_PARTITION_CTX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003724 if (force_horz_split || force_vert_split) {
3725 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3726
3727 if (!force_vert_split) { // force_horz_split only
3728 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3729 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003730 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003731 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003732 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003733 } else if (!force_horz_split) { // force_vert_split only
3734 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3735 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003736 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003737 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003738 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003739 } else { // force_ horz_split && force_vert_split horz_split
3740 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3741 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3742 tmp_partition_cost[PARTITION_SPLIT] = 0;
3743 }
3744
3745 partition_cost = tmp_partition_cost;
3746 }
Alex Converse55c6bde2017-01-12 15:55:31 -08003747#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003748
3749#if CONFIG_VAR_TX
3750#ifndef NDEBUG
3751 // Nothing should rely on the default value of this array (which is just
3752 // leftover from encoding the previous block. Setting it to magic number
3753 // when debugging.
3754 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3755#endif // NDEBUG
3756#endif // CONFIG_VAR_TX
3757
Jingning Hanc709e1f2016-12-06 14:48:09 -08003758 assert(mi_size_wide[bsize] == mi_size_high[bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003759
Yaowu Xuf883b422016-08-30 14:01:10 -07003760 av1_rd_cost_init(&this_rdc);
3761 av1_rd_cost_init(&sum_rdc);
3762 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003763 best_rdc.rdcost = best_rd;
3764
3765 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3766
3767 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003768 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003769
3770 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003771 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003772 ((pc_tree->index == 0 || pc_tree->index == 3) +
3773 get_chessboard_index(cm->current_video_frame)) &
3774 0x1;
3775
3776 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3777 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3778 }
3779
3780 // Determine partition types in search according to the speed features.
3781 // The threshold set here has to be of square block size.
3782 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003783 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3784 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3785 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3786 partition_none_allowed &= no_partition_allowed;
3787 partition_horz_allowed &= partition_allowed || force_horz_split;
3788 partition_vert_allowed &= partition_allowed || force_vert_split;
3789 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003790 }
3791 if (cpi->sf.use_square_partition_only) {
3792 partition_horz_allowed &= force_horz_split;
3793 partition_vert_allowed &= force_vert_split;
3794 }
3795
3796#if CONFIG_VAR_TX
3797 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3798 xd->left_txfm_context =
3799 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3800#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003801#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003802 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003803#else
3804 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3805#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003806
3807#if CONFIG_FP_MB_STATS
3808 if (cpi->use_fp_mb_stats) {
3809 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3810 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3811 mi_col, bsize);
3812 }
3813#endif
3814
3815#if CONFIG_FP_MB_STATS
3816 // Decide whether we shall split directly and skip searching NONE by using
3817 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003818 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 partition_none_allowed && src_diff_var > 4 &&
3820 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3821 int mb_row = mi_row >> 1;
3822 int mb_col = mi_col >> 1;
3823 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003824 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003825 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003826 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003827 int r, c;
3828
3829 // compute a complexity measure, basically measure inconsistency of motion
3830 // vectors obtained from the first pass in the current block
3831 for (r = mb_row; r < mb_row_end; r++) {
3832 for (c = mb_col; c < mb_col_end; c++) {
3833 const int mb_index = r * cm->mb_cols + c;
3834
3835 MOTION_DIRECTION this_mv;
3836 MOTION_DIRECTION right_mv;
3837 MOTION_DIRECTION bottom_mv;
3838
3839 this_mv =
3840 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3841
3842 // to its right
3843 if (c != mb_col_end - 1) {
3844 right_mv = get_motion_direction_fp(
3845 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3846 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3847 }
3848
3849 // to its bottom
3850 if (r != mb_row_end - 1) {
3851 bottom_mv = get_motion_direction_fp(
3852 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3853 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3854 }
3855
3856 // do not count its left and top neighbors to avoid double counting
3857 }
3858 }
3859
3860 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3861 partition_none_allowed = 0;
3862 }
3863 }
3864#endif
3865
3866 // PARTITION_NONE
3867 if (partition_none_allowed) {
3868 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3869#if CONFIG_SUPERTX
3870 &this_rate_nocoef,
3871#endif
3872#if CONFIG_EXT_PARTITION_TYPES
3873 PARTITION_NONE,
3874#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003875 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003876 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003877 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878 this_rdc.rate += partition_cost[PARTITION_NONE];
3879 this_rdc.rdcost =
3880 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3881#if CONFIG_SUPERTX
3882 this_rate_nocoef += partition_cost[PARTITION_NONE];
3883#endif
3884 }
3885
3886 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003887 // Adjust dist breakout threshold according to the partition size.
3888 const int64_t dist_breakout_thr =
3889 cpi->sf.partition_search_breakout_dist_thr >>
3890 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3891 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3892 const int rate_breakout_thr =
3893 cpi->sf.partition_search_breakout_rate_thr *
3894 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895
3896 best_rdc = this_rdc;
3897#if CONFIG_SUPERTX
3898 best_rate_nocoef = this_rate_nocoef;
3899 assert(best_rate_nocoef >= 0);
3900#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003901 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003902
3903 // If all y, u, v transform blocks in this partition are skippable, and
3904 // the dist & rate are within the thresholds, the partition search is
3905 // terminated for current branch of the partition search tree.
3906 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3907 // early termination at that speed.
3908 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003909 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003911 do_square_split = 0;
3912 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003913 }
3914
3915#if CONFIG_FP_MB_STATS
3916 // Check if every 16x16 first pass block statistics has zero
3917 // motion and the corresponding first pass residue is small enough.
3918 // If that is the case, check the difference variance between the
3919 // current frame and the last frame. If the variance is small enough,
3920 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003921 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003922 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3923 int mb_row = mi_row >> 1;
3924 int mb_col = mi_col >> 1;
3925 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003926 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003927 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003928 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929 int r, c;
3930
3931 int skip = 1;
3932 for (r = mb_row; r < mb_row_end; r++) {
3933 for (c = mb_col; c < mb_col_end; c++) {
3934 const int mb_index = r * cm->mb_cols + c;
3935 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3936 FPMB_MOTION_ZERO_MASK) ||
3937 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3938 FPMB_ERROR_SMALL_MASK)) {
3939 skip = 0;
3940 break;
3941 }
3942 }
3943 if (skip == 0) {
3944 break;
3945 }
3946 }
3947 if (skip) {
3948 if (src_diff_var == UINT_MAX) {
3949 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3950 src_diff_var = get_sby_perpixel_diff_variance(
3951 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3952 }
3953 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003954 do_square_split = 0;
3955 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003956 }
3957 }
3958 }
3959#endif
3960 }
3961 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003962#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003963 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003964#else
3965 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3966#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003967 }
3968
3969 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003970 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003971
3972 // PARTITION_SPLIT
3973 // TODO(jingning): use the motion vectors given by the above search as
3974 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003975 if (do_square_split) {
3976 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003977 subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003978 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979#if CONFIG_DUAL_FILTER
3980 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3981 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003982 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003983#else
3984 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3985 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003986 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003987#endif
3988#if CONFIG_SUPERTX
3989 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3990 &sum_rate_nocoef,
3991#if CONFIG_EXT_PARTITION_TYPES
3992 PARTITION_SPLIT,
3993#endif
3994 subsize, pc_tree->leaf_split[0], INT64_MAX);
3995#else
3996 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3997#if CONFIG_EXT_PARTITION_TYPES
3998 PARTITION_SPLIT,
3999#endif
4000 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
4001#endif // CONFIG_SUPERTX
4002 if (sum_rdc.rate == INT_MAX) {
4003 sum_rdc.rdcost = INT64_MAX;
4004#if CONFIG_SUPERTX
4005 sum_rate_nocoef = INT_MAX;
4006#endif
4007 }
4008#if CONFIG_SUPERTX
4009 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
4010 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4011 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4012
4013 pc_tree->partitioning = PARTITION_SPLIT;
4014
clang-format55ce9e02017-02-15 22:27:12 -08004015 sum_rdc.rate += av1_cost_bit(
4016 cm->fc->supertx_prob[partition_supertx_context_lookup
4017 [PARTITION_SPLIT]][supertx_size],
4018 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004019 sum_rdc.rdcost =
4020 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4021
4022 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
4023 TX_TYPE best_tx = DCT_DCT;
4024 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4025
4026 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4027
4028 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
4029 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
4030
Yaowu Xuf883b422016-08-30 14:01:10 -07004031 tmp_rdc.rate += av1_cost_bit(
clang-format55ce9e02017-02-15 22:27:12 -08004032 cm->fc->supertx_prob[partition_supertx_context_lookup
4033 [PARTITION_SPLIT]][supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004034 1);
4035 tmp_rdc.rdcost =
4036 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4037 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4038 sum_rdc = tmp_rdc;
4039 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4040 supertx_size, pc_tree);
4041 }
4042 }
4043
4044 pc_tree->partitioning = best_partition;
4045 }
4046#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004047 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004048 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07004049 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004050#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004051 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004052#else
Urvang Joshi52648442016-10-13 17:27:51 -07004053 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004055 const int x_idx = (idx & 1) * mi_step;
4056 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004057
4058 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
4059 continue;
4060
Urvang Joshi454280d2016-10-14 16:51:44 -07004061 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004062
Urvang Joshi52648442016-10-13 17:27:51 -07004063 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004064#if CONFIG_SUPERTX
4065 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
4066 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07004067 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004068#else
Urvang Joshi52648442016-10-13 17:27:51 -07004069 rd_pick_partition(
4070 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
4071 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004072#endif // CONFIG_SUPERTX
4073
4074 if (this_rdc.rate == INT_MAX) {
4075 sum_rdc.rdcost = INT64_MAX;
4076#if CONFIG_SUPERTX
4077 sum_rate_nocoef = INT_MAX;
4078#endif // CONFIG_SUPERTX
4079 break;
4080 } else {
4081 sum_rdc.rate += this_rdc.rate;
4082 sum_rdc.dist += this_rdc.dist;
4083 sum_rdc.rdcost += this_rdc.rdcost;
4084#if CONFIG_SUPERTX
4085 sum_rate_nocoef += this_rate_nocoef;
4086#endif // CONFIG_SUPERTX
4087 }
4088 }
Urvang Joshi52648442016-10-13 17:27:51 -07004089 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004091 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4093 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4094
4095 pc_tree->partitioning = PARTITION_SPLIT;
4096
clang-format55ce9e02017-02-15 22:27:12 -08004097 sum_rdc.rate += av1_cost_bit(
4098 cm->fc->supertx_prob[partition_supertx_context_lookup
4099 [PARTITION_SPLIT]][supertx_size],
4100 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004101 sum_rdc.rdcost =
4102 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4103
4104 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4105 TX_TYPE best_tx = DCT_DCT;
4106 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4107
4108 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4109
4110 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
4111 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
4112
Yaowu Xuf883b422016-08-30 14:01:10 -07004113 tmp_rdc.rate += av1_cost_bit(
clang-format55ce9e02017-02-15 22:27:12 -08004114 cm->fc->supertx_prob[partition_supertx_context_lookup
4115 [PARTITION_SPLIT]][supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004116 1);
4117 tmp_rdc.rdcost =
4118 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4119 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4120 sum_rdc = tmp_rdc;
4121 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4122 supertx_size, pc_tree);
4123 }
4124 }
4125
4126 pc_tree->partitioning = best_partition;
4127 }
4128#endif // CONFIG_SUPERTX
4129 }
4130
Urvang Joshi52648442016-10-13 17:27:51 -07004131 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004132 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
4133 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4134#if CONFIG_SUPERTX
4135 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
4136#endif // CONFIG_SUPERTX
4137
4138 if (sum_rdc.rdcost < best_rdc.rdcost) {
4139 best_rdc = sum_rdc;
4140#if CONFIG_SUPERTX
4141 best_rate_nocoef = sum_rate_nocoef;
4142 assert(best_rate_nocoef >= 0);
4143#endif // CONFIG_SUPERTX
4144 pc_tree->partitioning = PARTITION_SPLIT;
4145 }
Urvang Joshi52648442016-10-13 17:27:51 -07004146 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 // skip rectangular partition test when larger block size
4148 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07004149 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004150 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004151#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004152 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004153#else
4154 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4155#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 } // if (do_split)
4157
4158 // PARTITION_HORZ
4159 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004160 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004161 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07004162 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004163#if CONFIG_DUAL_FILTER
4164 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4165 partition_none_allowed)
4166 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004167 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168#else
4169 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4170 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004171 pc_tree->horizontal[0].pred_interp_filter =
4172 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173#endif
4174 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4175#if CONFIG_SUPERTX
4176 &sum_rate_nocoef,
4177#endif // CONFIG_SUPERTX
4178#if CONFIG_EXT_PARTITION_TYPES
4179 PARTITION_HORZ,
4180#endif
4181 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
4182
4183#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08004184 abort_flag =
4185 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4186 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004187 if (sum_rdc.rdcost < INT64_MAX &&
4188#else
4189 if (sum_rdc.rdcost < best_rdc.rdcost &&
4190#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004191 !force_horz_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07004192 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
4193 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004194 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07004195 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004196
Urvang Joshi454280d2016-10-14 16:51:44 -07004197 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004198
4199#if CONFIG_DUAL_FILTER
4200 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4201 partition_none_allowed)
4202 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004203 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004204#else
4205 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4206 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004207 pc_tree->horizontal[1].pred_interp_filter =
4208 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004209#endif
4210#if CONFIG_SUPERTX
4211 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4212 &this_rate_nocoef,
4213#if CONFIG_EXT_PARTITION_TYPES
4214 PARTITION_HORZ,
4215#endif
4216 subsize, &pc_tree->horizontal[1], INT64_MAX);
4217#else
4218 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4219#if CONFIG_EXT_PARTITION_TYPES
4220 PARTITION_HORZ,
4221#endif
4222 subsize, &pc_tree->horizontal[1],
4223 best_rdc.rdcost - sum_rdc.rdcost);
4224#endif // CONFIG_SUPERTX
4225 if (this_rdc.rate == INT_MAX) {
4226 sum_rdc.rdcost = INT64_MAX;
4227#if CONFIG_SUPERTX
4228 sum_rate_nocoef = INT_MAX;
4229#endif // CONFIG_SUPERTX
4230 } else {
4231 sum_rdc.rate += this_rdc.rate;
4232 sum_rdc.dist += this_rdc.dist;
4233 sum_rdc.rdcost += this_rdc.rdcost;
4234#if CONFIG_SUPERTX
4235 sum_rate_nocoef += this_rate_nocoef;
4236#endif // CONFIG_SUPERTX
4237 }
4238 }
4239
4240#if CONFIG_SUPERTX
4241 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4242 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4243 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4244
4245 pc_tree->partitioning = PARTITION_HORZ;
4246
Yaowu Xuf883b422016-08-30 14:01:10 -07004247 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004248 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4249 [supertx_size],
4250 0);
4251 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4252
4253 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4254 TX_TYPE best_tx = DCT_DCT;
4255 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4256
4257 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4258
4259 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4260 &tmp_rdc.dist, &best_tx, pc_tree);
4261
Yaowu Xuf883b422016-08-30 14:01:10 -07004262 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004263 cm->fc
4264 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4265 [supertx_size],
4266 1);
4267 tmp_rdc.rdcost =
4268 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4269 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4270 sum_rdc = tmp_rdc;
4271 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4272 supertx_size, pc_tree);
4273 }
4274 }
4275
4276 pc_tree->partitioning = best_partition;
4277 }
4278#endif // CONFIG_SUPERTX
4279
4280 if (sum_rdc.rdcost < best_rdc.rdcost) {
4281 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4282 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4283#if CONFIG_SUPERTX
4284 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4285#endif // CONFIG_SUPERTX
4286 if (sum_rdc.rdcost < best_rdc.rdcost) {
4287 best_rdc = sum_rdc;
4288#if CONFIG_SUPERTX
4289 best_rate_nocoef = sum_rate_nocoef;
4290 assert(best_rate_nocoef >= 0);
4291#endif // CONFIG_SUPERTX
4292 pc_tree->partitioning = PARTITION_HORZ;
4293 }
4294 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004295#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004296 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004297#else
4298 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4299#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004300 }
4301
4302 // PARTITION_VERT
4303 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004304 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004305 subsize = get_subsize(bsize, PARTITION_VERT);
4306
Urvang Joshi454280d2016-10-14 16:51:44 -07004307 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004308
4309#if CONFIG_DUAL_FILTER
4310 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4311 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004312 pc_tree->vertical[0].pred_interp_filter =
4313 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004314#else
4315 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4316 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004317 pc_tree->vertical[0].pred_interp_filter =
4318 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004319#endif
4320 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4321#if CONFIG_SUPERTX
4322 &sum_rate_nocoef,
4323#endif // CONFIG_SUPERTX
4324#if CONFIG_EXT_PARTITION_TYPES
4325 PARTITION_VERT,
4326#endif
4327 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4328#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08004329 abort_flag =
4330 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4331 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004332 if (sum_rdc.rdcost < INT64_MAX &&
4333#else
4334 if (sum_rdc.rdcost < best_rdc.rdcost &&
4335#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004336 !force_vert_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004337 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4338 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4339 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004340
Urvang Joshi454280d2016-10-14 16:51:44 -07004341 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004342
4343#if CONFIG_DUAL_FILTER
4344 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4345 partition_none_allowed)
4346 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004347 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348#else
4349 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4350 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004351 pc_tree->vertical[1].pred_interp_filter =
4352 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004353#endif
4354#if CONFIG_SUPERTX
4355 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4356 &this_rate_nocoef,
4357#if CONFIG_EXT_PARTITION_TYPES
4358 PARTITION_VERT,
4359#endif
4360 subsize, &pc_tree->vertical[1],
4361 INT64_MAX - sum_rdc.rdcost);
4362#else
4363 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4364#if CONFIG_EXT_PARTITION_TYPES
4365 PARTITION_VERT,
4366#endif
4367 subsize, &pc_tree->vertical[1],
4368 best_rdc.rdcost - sum_rdc.rdcost);
4369#endif // CONFIG_SUPERTX
4370 if (this_rdc.rate == INT_MAX) {
4371 sum_rdc.rdcost = INT64_MAX;
4372#if CONFIG_SUPERTX
4373 sum_rate_nocoef = INT_MAX;
4374#endif // CONFIG_SUPERTX
4375 } else {
4376 sum_rdc.rate += this_rdc.rate;
4377 sum_rdc.dist += this_rdc.dist;
4378 sum_rdc.rdcost += this_rdc.rdcost;
4379#if CONFIG_SUPERTX
4380 sum_rate_nocoef += this_rate_nocoef;
4381#endif // CONFIG_SUPERTX
4382 }
4383 }
4384#if CONFIG_SUPERTX
4385 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4386 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4387 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4388
4389 pc_tree->partitioning = PARTITION_VERT;
4390
Yaowu Xuf883b422016-08-30 14:01:10 -07004391 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004392 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4393 [supertx_size],
4394 0);
4395 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4396
4397 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4398 TX_TYPE best_tx = DCT_DCT;
4399 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4400
4401 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4402
4403 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4404 &tmp_rdc.dist, &best_tx, pc_tree);
4405
Yaowu Xuf883b422016-08-30 14:01:10 -07004406 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407 cm->fc
4408 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4409 [supertx_size],
4410 1);
4411 tmp_rdc.rdcost =
4412 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4413 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4414 sum_rdc = tmp_rdc;
4415 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4416 supertx_size, pc_tree);
4417 }
4418 }
4419
4420 pc_tree->partitioning = best_partition;
4421 }
4422#endif // CONFIG_SUPERTX
4423
4424 if (sum_rdc.rdcost < best_rdc.rdcost) {
4425 sum_rdc.rate += partition_cost[PARTITION_VERT];
4426 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4427#if CONFIG_SUPERTX
4428 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4429#endif // CONFIG_SUPERTX
4430 if (sum_rdc.rdcost < best_rdc.rdcost) {
4431 best_rdc = sum_rdc;
4432#if CONFIG_SUPERTX
4433 best_rate_nocoef = sum_rate_nocoef;
4434 assert(best_rate_nocoef >= 0);
4435#endif // CONFIG_SUPERTX
4436 pc_tree->partitioning = PARTITION_VERT;
4437 }
4438 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004439#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004441#else
4442 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4443#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004444 }
4445
4446#if CONFIG_EXT_PARTITION_TYPES
4447 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004448 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004449 partition_none_allowed) {
4450 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4451 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004452 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004453 PARTITION_HORZ_A,
4454#if CONFIG_SUPERTX
4455 best_rd, &best_rate_nocoef, &x_ctx,
4456#endif
4457 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4458 mi_row + mi_step, mi_col, subsize);
4459 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4460 }
4461 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004462 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004463 partition_none_allowed) {
4464 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4465 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004466 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004467 PARTITION_HORZ_B,
4468#if CONFIG_SUPERTX
4469 best_rd, &best_rate_nocoef, &x_ctx,
4470#endif
4471 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4472 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4473 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4474 }
4475 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004476 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004477 partition_none_allowed) {
4478 subsize = get_subsize(bsize, PARTITION_VERT_A);
4479 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004480 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004481 PARTITION_VERT_A,
4482#if CONFIG_SUPERTX
4483 best_rd, &best_rate_nocoef, &x_ctx,
4484#endif
4485 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4486 mi_row, mi_col + mi_step, subsize);
4487 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4488 }
4489 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004490 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004491 partition_none_allowed) {
4492 subsize = get_subsize(bsize, PARTITION_VERT_B);
4493 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004494 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004495 PARTITION_VERT_B,
4496#if CONFIG_SUPERTX
4497 best_rd, &best_rate_nocoef, &x_ctx,
4498#endif
4499 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4500 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4501 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4502 }
4503#endif // CONFIG_EXT_PARTITION_TYPES
4504
4505 // TODO(jbb): This code added so that we avoid static analysis
4506 // warning related to the fact that best_rd isn't used after this
4507 // point. This code should be refactored so that the duplicate
4508 // checks occur in some sub function and thus are used...
4509 (void)best_rd;
4510 *rd_cost = best_rdc;
4511#if CONFIG_SUPERTX
4512 *rate_nocoef = best_rate_nocoef;
4513#endif // CONFIG_SUPERTX
4514
4515 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4516 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004517 if (bsize == cm->sb_size) {
Yue Chenf27b1602017-01-13 11:11:43 -08004518#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
4519 set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
4520#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004521 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4522 pc_tree, NULL);
4523 } else {
4524 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4525 pc_tree, NULL);
4526 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004527 }
4528
4529 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004530#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004531 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004532#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533 assert(best_rdc.rate < INT_MAX);
4534 assert(best_rdc.dist < INT64_MAX);
4535 } else {
4536 assert(tp_orig == *tp);
4537 }
4538}
4539
Yaowu Xuf883b422016-08-30 14:01:10 -07004540static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004541 TileDataEnc *tile_data, int mi_row,
4542 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004543 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004544 const TileInfo *const tile_info = &tile_data->tile_info;
4545 MACROBLOCK *const x = &td->mb;
4546 MACROBLOCKD *const xd = &x->e_mbd;
4547 SPEED_FEATURES *const sf = &cpi->sf;
4548 int mi_col;
4549#if CONFIG_EXT_PARTITION
4550 const int leaf_nodes = 256;
4551#else
4552 const int leaf_nodes = 64;
4553#endif // CONFIG_EXT_PARTITION
4554
4555 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004556 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004557
Thomas Daviesf6936102016-09-05 16:51:31 +01004558#if CONFIG_DELTA_Q
4559 // Reset delta for every tile
4560 if (cm->delta_q_present_flag)
4561 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4562#endif
4563
Yaowu Xuc27fc142016-08-22 16:08:15 -07004564 // Code each SB in the row
4565 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4566 mi_col += cm->mib_size) {
4567 const struct segmentation *const seg = &cm->seg;
4568 int dummy_rate;
4569 int64_t dummy_dist;
4570 RD_COST dummy_rdc;
4571#if CONFIG_SUPERTX
4572 int dummy_rate_nocoef;
4573#endif // CONFIG_SUPERTX
4574 int i;
4575 int seg_skip = 0;
4576
4577 const int idx_str = cm->mi_stride * mi_row + mi_col;
4578 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4579 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4580
Ryan Lei9b02b0e2017-01-30 15:52:20 -08004581 av1_update_boundary_info(cm, tile_info, mi_row, mi_col);
4582
Yaowu Xuc27fc142016-08-22 16:08:15 -07004583 if (sf->adaptive_pred_interp_filter) {
4584 for (i = 0; i < leaf_nodes; ++i)
4585 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4586
4587 for (i = 0; i < leaf_nodes; ++i) {
4588 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4589 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4590 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4591 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4592 }
4593 }
4594
Yaowu Xuf883b422016-08-30 14:01:10 -07004595 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004596 pc_root->index = 0;
4597
4598 if (seg->enabled) {
4599 const uint8_t *const map =
4600 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4601 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4602 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4603 }
4604
Arild Fuldseth07441162016-08-15 15:07:52 +02004605#if CONFIG_DELTA_Q
4606 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004607 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004608 int sb_row = mi_row >> 3;
4609 int sb_col = mi_col >> 3;
4610 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4611 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004612
4613 // Ensure divisibility of delta_qindex by delta_q_res
4614 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4615 int qmask = ~(cm->delta_q_res - 1);
4616 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4617 cm->delta_q_res, 256 - cm->delta_q_res);
4618 current_qindex =
4619 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4620 cm->base_qindex;
4621
Arild Fuldseth07441162016-08-15 15:07:52 +02004622 xd->delta_qindex = current_qindex - cm->base_qindex;
4623 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4624 xd->mi[0]->mbmi.current_q_index = current_qindex;
4625 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004626 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004627 }
4628#endif
4629
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630 x->source_variance = UINT_MAX;
4631 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4632 BLOCK_SIZE bsize;
4633 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4634 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4635 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4636 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4637 &dummy_rate, &dummy_dist,
4638#if CONFIG_SUPERTX
4639 &dummy_rate_nocoef,
4640#endif // CONFIG_SUPERTX
4641 1, pc_root);
4642 } else if (cpi->partition_search_skippable_frame) {
4643 BLOCK_SIZE bsize;
4644 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4645 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4646 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4647 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4648 &dummy_rate, &dummy_dist,
4649#if CONFIG_SUPERTX
4650 &dummy_rate_nocoef,
4651#endif // CONFIG_SUPERTX
4652 1, pc_root);
4653 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4654 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4655 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4656 &dummy_rate, &dummy_dist,
4657#if CONFIG_SUPERTX
4658 &dummy_rate_nocoef,
4659#endif // CONFIG_SUPERTX
4660 1, pc_root);
4661 } else {
4662 // If required set upper and lower partition size limits
4663 if (sf->auto_min_max_partition_size) {
4664 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4665 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4666 &x->min_partition_size, &x->max_partition_size);
4667 }
4668 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4669 &dummy_rdc,
4670#if CONFIG_SUPERTX
4671 &dummy_rate_nocoef,
4672#endif // CONFIG_SUPERTX
4673 INT64_MAX, pc_root);
4674 }
4675 }
hui su0d103572017-03-01 17:58:01 -08004676#if CONFIG_SUBFRAME_PROB_UPDATE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004677 if (cm->do_subframe_update &&
4678 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
hui su0161a932017-01-24 14:12:11 -08004679 const int mi_rows_per_update =
4680 MI_SIZE * AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1);
4681 if ((mi_row + MI_SIZE) % mi_rows_per_update == 0 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004682 mi_row + MI_SIZE < cm->mi_rows &&
4683 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4684 TX_SIZE t;
4685 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4686
Yaowu Xu6b763c92017-01-23 12:13:37 -08004687 for (t = 0; t < TX_SIZES; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004688 av1_full_to_model_counts(cpi->td.counts->coef[t],
4689 cpi->td.rd_counts.coef_counts[t]);
4690 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004691 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004692 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4693 cm->fc->coef_probs);
4694 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4695 cpi->td.rd_counts.coef_counts);
4696 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4697 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004698 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004699 }
4700 }
hui su0d103572017-03-01 17:58:01 -08004701#endif // CONFIG_SUBFRAME_PROB_UPDATE
Yaowu Xuc27fc142016-08-22 16:08:15 -07004702}
4703
Yaowu Xuf883b422016-08-30 14:01:10 -07004704static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004705 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004706 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004707 MACROBLOCKD *const xd = &x->e_mbd;
4708
4709 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004710 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004711
Yaowu Xuf883b422016-08-30 14:01:10 -07004712 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004713}
4714
Zoe Liub05e5d12017-02-07 14:32:53 -08004715#if !CONFIG_REF_ADAPT
Yaowu Xuf883b422016-08-30 14:01:10 -07004716static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004717 const int ref_flags = cpi->ref_frame_flags;
4718
4719 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4720 return 0;
4721 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004722 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004723#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004724 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4725 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004726#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004727 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728 }
4729}
Zoe Liub05e5d12017-02-07 14:32:53 -08004730#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07004731
4732#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004733static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004734 int mi_row, mi_col;
4735 const int mis = cm->mi_stride;
4736 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4737
4738 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4739 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4740 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4741 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4742 }
4743 }
4744}
4745#endif
4746
Yaowu Xuf883b422016-08-30 14:01:10 -07004747static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004748 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4749#if CONFIG_EXT_REFS
4750 // We will not update the golden frame with an internal overlay frame
4751 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4752 cpi->rc.is_src_frame_ext_arf)
4753#else
4754 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4755#endif
4756 return ALTREF_FRAME;
4757 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4758 return GOLDEN_FRAME;
4759 else
4760 // TODO(zoeliu): To investigate whether a frame_type other than
4761 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4762 return LAST_FRAME;
4763}
4764
Yaowu Xuf883b422016-08-30 14:01:10 -07004765static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yue Cheneeacc4c2017-01-17 17:29:17 -08004766 int i, all_lossless = 1;
4767
4768 if (cpi->common.seg.enabled) {
4769 for (i = 0; i < MAX_SEGMENTS; ++i) {
4770 if (!xd->lossless[i]) {
4771 all_lossless = 0;
4772 break;
4773 }
4774 }
4775 } else {
4776 all_lossless = xd->lossless[0];
4777 }
4778 if (all_lossless) return ONLY_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004779 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004780 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004781 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4782 cpi->sf.tx_size_search_method == USE_TX_8X8)
4783 return TX_MODE_SELECT;
4784 else
4785 return cpi->common.tx_mode;
4786}
4787
Yaowu Xuf883b422016-08-30 14:01:10 -07004788void av1_init_tile_data(AV1_COMP *cpi) {
4789 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004790 const int tile_cols = cm->tile_cols;
4791 const int tile_rows = cm->tile_rows;
4792 int tile_col, tile_row;
4793 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4794 unsigned int tile_tok = 0;
4795
4796 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004797 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4798 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004799 sizeof(*cpi->tile_data)));
4800 cpi->allocated_tiles = tile_cols * tile_rows;
4801
4802 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4803 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4804 TileDataEnc *const tile_data =
4805 &cpi->tile_data[tile_row * tile_cols + tile_col];
4806 int i, j;
4807 for (i = 0; i < BLOCK_SIZES; ++i) {
4808 for (j = 0; j < MAX_MODES; ++j) {
4809 tile_data->thresh_freq_fact[i][j] = 32;
4810 tile_data->mode_map[i][j] = j;
4811 }
4812 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004813#if CONFIG_PVQ
4814 // This will be dynamically increased as more pvq block is encoded.
4815 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004816 CHECK_MEM_ERROR(
4817 cm, tile_data->pvq_q.buf,
4818 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004819 tile_data->pvq_q.curr_pos = 0;
4820#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004821 }
4822 }
4823
4824 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4825 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4826 TileInfo *const tile_info =
4827 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004828 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004829
4830 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4831 pre_tok = cpi->tile_tok[tile_row][tile_col];
4832 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004833#if CONFIG_PVQ
4834 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4835#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004836 }
4837 }
4838}
4839
Yaowu Xuf883b422016-08-30 14:01:10 -07004840void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4841 int tile_col) {
4842 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004843 TileDataEnc *const this_tile =
4844 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4845 const TileInfo *const tile_info = &this_tile->tile_info;
4846 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4847 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004848#if CONFIG_PVQ
4849 od_adapt_ctx *adapt;
4850#endif
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004851#if CONFIG_DEPENDENT_HORZTILES
Fangwen Fu73126c02017-02-08 22:37:47 -08004852#if CONFIG_TILE_GROUPS
4853 if ((!cm->dependent_horz_tiles) || (tile_row == 0) ||
4854 tile_info->tg_horz_boundary) {
4855#else
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004856 if ((!cm->dependent_horz_tiles) || (tile_row == 0)) {
Fangwen Fu73126c02017-02-08 22:37:47 -08004857#endif
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004858 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
4859 }
4860#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004861 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004862#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004863
4864 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004865 this_tile->m_search_count = 0; // Count of motion search hits.
4866 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4867 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4868 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869
Yushin Cho77bba8d2016-11-04 16:36:56 -07004870#if CONFIG_PVQ
4871 td->mb.pvq_q = &this_tile->pvq_q;
4872
Yushin Cho70669122016-12-08 09:53:14 -10004873 // TODO(yushin) : activity masking info needs be signaled by a bitstream
4874 td->mb.daala_enc.use_activity_masking = AV1_PVQ_ENABLE_ACTIVITY_MASKING;
4875
4876 if (td->mb.daala_enc.use_activity_masking)
4877 td->mb.daala_enc.qm = OD_HVS_QM; // Hard coded. Enc/dec required to sync.
4878 else
4879 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4880
Yushin Cho77bba8d2016-11-04 16:36:56 -07004881 {
4882 // FIXME: Multiple segments support
4883 int segment_id = 0;
4884 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4885 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4886 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4887 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4888 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4889 td->mb.daala_enc.pvq_norm_lambda =
4890 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4891 td->mb.daala_enc.pvq_norm_lambda_dc =
4892 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4893 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4894 }
4895 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4896 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
Yushin Cho70669122016-12-08 09:53:14 -10004897
4898 if (td->mb.daala_enc.use_activity_masking) {
4899 int pli;
4900 int use_masking = td->mb.daala_enc.use_activity_masking;
4901 int segment_id = 0;
4902 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4903
4904 for (pli = 0; pli < MAX_MB_PLANE; pli++) {
4905 int i;
4906 int q;
4907
4908 q = qindex;
4909 if (q <= OD_DEFAULT_QMS[use_masking][0][pli].interp_q << OD_COEFF_SHIFT) {
4910 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4911 &OD_DEFAULT_QMS[use_masking][0][pli], NULL);
4912 } else {
4913 i = 0;
4914 while (OD_DEFAULT_QMS[use_masking][i + 1][pli].qm_q4 != NULL &&
4915 q > OD_DEFAULT_QMS[use_masking][i + 1][pli].interp_q
4916 << OD_COEFF_SHIFT) {
4917 i++;
4918 }
4919 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4920 &OD_DEFAULT_QMS[use_masking][i][pli],
4921 &OD_DEFAULT_QMS[use_masking][i + 1][pli]);
4922 }
4923 }
4924 }
4925
Nathan E. Egge6675be02016-12-21 13:02:43 -05004926#if CONFIG_DAALA_EC
4927 od_ec_enc_init(&td->mb.daala_enc.w.ec, 65025);
4928#else
4929#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4930#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004931
4932 adapt = &td->mb.daala_enc.state.adapt;
Nathan E. Egge6675be02016-12-21 13:02:43 -05004933
4934#if CONFIG_DAALA_EC
4935 od_ec_enc_reset(&td->mb.daala_enc.w.ec);
4936#else
4937#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4938#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004939 od_adapt_ctx_reset(adapt, 0);
Yushin Chob39378e2017-02-21 09:39:22 -08004940#endif // #if CONFIG_PVQ
4941
4942#if CONFIG_EC_ADAPT
Thomas Daviesf77d4ad2017-01-10 18:55:42 +00004943 this_tile->tctx = *cm->fc;
4944 td->mb.e_mbd.tile_ctx = &this_tile->tctx;
Yushin Chob39378e2017-02-21 09:39:22 -08004945#endif // #if CONFIG_EC_ADAPT
Yushin Cho77bba8d2016-11-04 16:36:56 -07004946
Yaowu Xuc27fc142016-08-22 16:08:15 -07004947 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4948 mi_row += cm->mib_size) {
4949 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4950 }
4951
4952 cpi->tok_count[tile_row][tile_col] =
4953 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4954 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004955#if CONFIG_PVQ
Nathan E. Egge6675be02016-12-21 13:02:43 -05004956#if CONFIG_DAALA_EC
4957 od_ec_enc_clear(&td->mb.daala_enc.w.ec);
4958#else
4959#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4960#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004961
4962 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4963 // rewind current position so that bitstream can be written
4964 // from the 1st pvq block
4965 td->mb.pvq_q->curr_pos = 0;
4966
4967 td->mb.pvq_q = NULL;
4968#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004969}
4970
Yaowu Xuf883b422016-08-30 14:01:10 -07004971static void encode_tiles(AV1_COMP *cpi) {
4972 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004973 int tile_col, tile_row;
4974
Yaowu Xuf883b422016-08-30 14:01:10 -07004975 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004976
4977 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4978 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004979 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004980}
4981
4982#if CONFIG_FP_MB_STATS
4983static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004984 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004985 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4986 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4987
4988 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4989
4990 *this_frame_mb_stats = mb_stats_in;
4991
4992 return 1;
4993}
4994#endif
4995
Yaowu Xuf883b422016-08-30 14:01:10 -07004996static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004997 ThreadData *const td = &cpi->td;
4998 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004999 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005000 MACROBLOCKD *const xd = &x->e_mbd;
5001 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5002 int i;
5003
Yaowu Xuf883b422016-08-30 14:01:10 -07005004 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
5005 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Jingning Han24e0a182016-11-20 22:34:12 -08005006#if CONFIG_REF_MV
Dengca8d24d2016-10-17 14:06:35 +08005007 cm->setup_mi(cm);
5008#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005009
5010 xd->mi = cm->mi_grid_visible;
5011 xd->mi[0] = cm->mi;
5012
Yaowu Xuf883b422016-08-30 14:01:10 -07005013 av1_zero(*td->counts);
5014 av1_zero(rdc->coef_counts);
5015 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005016
5017#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07005018 av1_zero(cpi->global_motion_used);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08005019 if (cpi->common.frame_type == INTER_FRAME && cpi->Source &&
5020 !cpi->global_motion_search_done) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005021 YV12_BUFFER_CONFIG *ref_buf;
5022 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07005023 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08005024 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005025 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
5026 ref_buf = get_ref_frame_buffer(cpi, frame);
5027 if (ref_buf) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005028 TransformationType model;
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08005029 aom_clear_system_state();
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005030 for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
5031 if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
David Barker557ce7b2016-11-16 10:22:24 +00005032#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005033 cpi->common.bit_depth,
David Barker557ce7b2016-11-16 10:22:24 +00005034#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005035 params)) {
5036 convert_model_to_params(params, &cm->global_motion[frame]);
5037 if (cm->global_motion[frame].wmtype != IDENTITY) {
5038 erroradvantage = refine_integerized_param(
5039 &cm->global_motion[frame], cm->global_motion[frame].wmtype,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07005040#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005041 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07005042#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005043 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
5044 ref_buf->y_stride, cpi->Source->y_buffer,
5045 cpi->Source->y_width, cpi->Source->y_height,
5046 cpi->Source->y_stride, 3);
5047 if (erroradvantage >
5048 gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
5049 set_default_gmparams(&cm->global_motion[frame]);
5050 }
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08005051 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005052 }
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005053 if (cm->global_motion[frame].wmtype != IDENTITY) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005054 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08005055 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005056 }
5057 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08005058 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005059 }
5060#endif // CONFIG_GLOBAL_MOTION
5061
5062 for (i = 0; i < MAX_SEGMENTS; ++i) {
5063 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07005064 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005065 : cm->base_qindex;
5066 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
5067 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
Yue Cheneeacc4c2017-01-17 17:29:17 -08005068 xd->qindex[i] = qindex;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005069 }
5070
5071 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
5072
5073 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07005074 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075
Yaowu Xuf883b422016-08-30 14:01:10 -07005076 av1_initialize_rd_consts(cpi);
5077 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005078 init_encode_frame_mb_context(cpi);
Fangwen Fu8d164de2016-12-14 13:40:54 -08005079#if CONFIG_TEMPMV_SIGNALING
5080 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
5081 if (last_fb_buf_idx != INVALID_IDX) {
5082 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
5083 cm->use_prev_frame_mvs &= !cm->error_resilient_mode &&
5084 cm->width == cm->prev_frame->buf.y_width &&
5085 cm->height == cm->prev_frame->buf.y_height &&
5086 !cm->intra_only && !cm->prev_frame->intra_only;
5087 }
5088#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005089 cm->use_prev_frame_mvs =
5090 !cm->error_resilient_mode && cm->width == cm->last_width &&
5091 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Fangwen Fu8d164de2016-12-14 13:40:54 -08005092#endif
Thomas Daviesf6936102016-09-05 16:51:31 +01005093
5094#if CONFIG_DELTA_Q
5095 // Fix delta q resolution for the moment
5096 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
5097#endif
5098
Yaowu Xuc27fc142016-08-22 16:08:15 -07005099#if CONFIG_EXT_REFS
5100 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
5101 // show_exisiting_frame=1, nor can it take a frame not used as
5102 // a reference, it is probable that by the time it is being
5103 // referred to, the frame buffer it originally points to may
5104 // already get expired and have been reassigned to the current
5105 // newly coded frame. Hence, we need to check whether this is
5106 // the case, and if yes, we have 2 choices:
5107 // (1) Simply disable the use of previous frame mvs; or
5108 // (2) Have cm->prev_frame point to one reference frame buffer,
5109 // e.g. LAST_FRAME.
5110 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
5111 // Reassign the LAST_FRAME buffer to cm->prev_frame.
5112 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
5113 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
5114 }
5115#endif // CONFIG_EXT_REFS
5116
5117 // Special case: set prev_mi to NULL when the previous mode info
5118 // context cannot be used.
5119 cm->prev_mi =
5120 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
5121
5122#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005123 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005125 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126#endif
5127#endif
5128
5129 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
5130 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07005131 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005132
5133 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005134 struct aom_usec_timer emr_timer;
5135 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136
5137#if CONFIG_FP_MB_STATS
5138 if (cpi->use_fp_mb_stats) {
5139 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
5140 &cpi->twopass.this_frame_mb_stats);
5141 }
5142#endif
5143
5144 // If allowed, encoding tiles in parallel with one thread handling one tile.
5145 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
5146 // 1 tile rows, as it uses the single above_context et al arrays from
5147 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07005148 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
5149 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005150 else
5151 encode_tiles(cpi);
5152
Yaowu Xuf883b422016-08-30 14:01:10 -07005153 aom_usec_timer_mark(&emr_timer);
5154 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005155 }
5156
5157#if 0
5158 // Keep record of the total distortion this time around for future use
5159 cpi->last_frame_distortion = cpi->frame_distortion;
5160#endif
5161}
5162
Yaowu Xuf883b422016-08-30 14:01:10 -07005163void av1_encode_frame(AV1_COMP *cpi) {
5164 AV1_COMMON *const cm = &cpi->common;
Sarah Parkere68a3e42017-02-16 14:03:24 -08005165#if CONFIG_EXT_TX
5166 // Indicates whether or not to use a default reduced set for ext-tx
5167 // rather than the potential full set of 16 transforms
5168 cm->reduced_tx_set_used = 0;
5169#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005170
5171 // In the longer term the encoder should be generalized to match the
5172 // decoder such that we allow compound where one of the 3 buffers has a
5173 // different sign bias and that buffer is then the fixed ref. However, this
5174 // requires further work in the rd loop. For now the only supported encoder
5175 // side behavior is where the ALT ref buffer has opposite sign bias to
5176 // the other two.
5177 if (!frame_is_intra_only(cm)) {
5178 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5179 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
5180 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5181 cm->ref_frame_sign_bias[LAST_FRAME])) {
5182 cpi->allow_comp_inter_inter = 0;
5183 } else {
5184 cpi->allow_comp_inter_inter = 1;
5185
5186#if CONFIG_EXT_REFS
5187 cm->comp_fwd_ref[0] = LAST_FRAME;
5188 cm->comp_fwd_ref[1] = LAST2_FRAME;
5189 cm->comp_fwd_ref[2] = LAST3_FRAME;
5190 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
5191 cm->comp_bwd_ref[0] = BWDREF_FRAME;
5192 cm->comp_bwd_ref[1] = ALTREF_FRAME;
5193#else
5194 cm->comp_fixed_ref = ALTREF_FRAME;
5195 cm->comp_var_ref[0] = LAST_FRAME;
5196 cm->comp_var_ref[1] = GOLDEN_FRAME;
5197#endif // CONFIG_EXT_REFS
5198 }
5199 } else {
5200 cpi->allow_comp_inter_inter = 0;
5201 }
5202
5203 if (cpi->sf.frame_parameter_update) {
5204 int i;
5205 RD_OPT *const rd_opt = &cpi->rd;
5206 FRAME_COUNTS *counts = cpi->td.counts;
5207 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5208
5209 // This code does a single RD pass over the whole frame assuming
5210 // either compound, single or hybrid prediction as per whatever has
5211 // worked best for that type of frame in the past.
5212 // It also predicts whether another coding mode would have worked
5213 // better than this coding mode. If that is the case, it remembers
5214 // that for subsequent frames.
5215 // It does the same analysis for transform size selection also.
5216 //
5217 // TODO(zoeliu): To investigate whether a frame_type other than
5218 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
5219 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
5220 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
5221 const int is_alt_ref = frame_type == ALTREF_FRAME;
5222
Zoe Liub05e5d12017-02-07 14:32:53 -08005223/* prediction (compound, single or hybrid) mode selection */
5224#if CONFIG_REF_ADAPT
5225 // NOTE(zoeliu): "is_alt_ref" is true only for OVERLAY/INTNL_OVERLAY frames
5226 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5227 cm->reference_mode = SINGLE_REFERENCE;
5228 else
5229 cm->reference_mode = REFERENCE_MODE_SELECT;
5230#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5232 cm->reference_mode = SINGLE_REFERENCE;
5233 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
5234 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
5235 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
5236 cm->reference_mode = COMPOUND_REFERENCE;
5237 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
5238 cm->reference_mode = SINGLE_REFERENCE;
5239 else
5240 cm->reference_mode = REFERENCE_MODE_SELECT;
Zoe Liub05e5d12017-02-07 14:32:53 -08005241#endif // CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005242
5243#if CONFIG_DUAL_FILTER
5244 cm->interp_filter = SWITCHABLE;
5245#endif
5246
5247 encode_frame_internal(cpi);
5248
5249 for (i = 0; i < REFERENCE_MODES; ++i)
5250 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
5251
5252 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5253 int single_count_zero = 0;
5254 int comp_count_zero = 0;
5255
5256 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5257 single_count_zero += counts->comp_inter[i][0];
5258 comp_count_zero += counts->comp_inter[i][1];
5259 }
5260
5261 if (comp_count_zero == 0) {
5262 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005263 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08005264#if !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005265 } else if (single_count_zero == 0) {
5266 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005267 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08005268#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005269 }
5270 }
5271
Jingning Han9777afc2016-10-20 15:17:43 -07005272#if CONFIG_VAR_TX
5273 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005274 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Jingning Han9777afc2016-10-20 15:17:43 -07005275#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005276 if (cm->tx_mode == TX_MODE_SELECT) {
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005277#if CONFIG_TX64X64
5278 int count4x4 = 0;
5279 int count8x8_8x8p = 0, count8x8_lp = 0;
5280 int count16x16_16x16p = 0, count16x16_lp = 0;
5281 int count32x32_32x32p = 0, count32x32_lp = 0;
5282 int count64x64_64x64p = 0;
5283 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5284 // counts->tx_size[max_depth][context_idx][this_depth_level]
5285 count4x4 += counts->tx_size[0][i][0];
5286 count4x4 += counts->tx_size[1][i][0];
5287 count4x4 += counts->tx_size[2][i][0];
5288 count4x4 += counts->tx_size[3][i][0];
5289
5290 count8x8_8x8p += counts->tx_size[0][i][1];
5291 count8x8_lp += counts->tx_size[1][i][1];
5292 count8x8_lp += counts->tx_size[2][i][1];
5293 count8x8_lp += counts->tx_size[3][i][1];
5294
5295 count16x16_16x16p += counts->tx_size[1][i][2];
5296 count16x16_lp += counts->tx_size[2][i][2];
5297 count16x16_lp += counts->tx_size[3][i][2];
5298
5299 count32x32_32x32p += counts->tx_size[2][i][3];
5300 count32x32_lp += counts->tx_size[3][i][3];
5301
5302 count64x64_64x64p += counts->tx_size[3][i][4];
5303 }
5304#if CONFIG_EXT_TX && CONFIG_RECT_TX
5305 count4x4 += counts->tx_size_implied[0][TX_4X4];
5306 count4x4 += counts->tx_size_implied[1][TX_4X4];
5307 count4x4 += counts->tx_size_implied[2][TX_4X4];
5308 count4x4 += counts->tx_size_implied[3][TX_4X4];
5309 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5310 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5311 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5312 count8x8_lp += counts->tx_size_implied[4][TX_8X8];
5313 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5314 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5315 count16x16_lp += counts->tx_size_implied[4][TX_16X16];
5316 count32x32_32x32p += counts->tx_size_implied[3][TX_32X32];
5317 count32x32_lp += counts->tx_size_implied[4][TX_32X32];
Debargha Mukherjee5a488a62016-11-22 22:24:10 -08005318 count64x64_64x64p += counts->tx_size_implied[4][TX_64X64];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005319#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5320 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5321 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5322#if CONFIG_SUPERTX
5323 cm->counts.supertx_size[TX_16X16] == 0 &&
5324 cm->counts.supertx_size[TX_32X32] == 0 &&
5325 cm->counts.supertx_size[TX_64X64] == 0 &&
5326#endif
5327 count64x64_64x64p == 0) {
5328 cm->tx_mode = ALLOW_8X8;
5329 reset_skip_tx_size(cm, TX_8X8);
5330 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5331 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5332 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5333#if CONFIG_SUPERTX
5334 cm->counts.supertx_size[TX_8X8] == 0 &&
5335 cm->counts.supertx_size[TX_16X16] == 0 &&
5336 cm->counts.supertx_size[TX_32X32] == 0 &&
5337 cm->counts.supertx_size[TX_64X64] == 0 &&
5338#endif
5339 count64x64_64x64p == 0) {
5340 cm->tx_mode = ONLY_4X4;
5341 reset_skip_tx_size(cm, TX_4X4);
5342 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5343 count32x32_lp == 0) {
5344 cm->tx_mode = ALLOW_64X64;
5345 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5346#if CONFIG_SUPERTX
5347 cm->counts.supertx_size[TX_64X64] == 0 &&
5348#endif
5349 count64x64_64x64p == 0) {
5350 cm->tx_mode = ALLOW_32X32;
5351 reset_skip_tx_size(cm, TX_32X32);
5352 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5353 count32x32_32x32p == 0 &&
5354#if CONFIG_SUPERTX
5355 cm->counts.supertx_size[TX_32X32] == 0 &&
5356 cm->counts.supertx_size[TX_64X64] == 0 &&
5357#endif
5358 count64x64_64x64p == 0) {
5359 cm->tx_mode = ALLOW_16X16;
5360 reset_skip_tx_size(cm, TX_16X16);
5361 }
5362
5363#else // CONFIG_TX64X64
5364
Yaowu Xuc27fc142016-08-22 16:08:15 -07005365 int count4x4 = 0;
5366 int count8x8_lp = 0, count8x8_8x8p = 0;
5367 int count16x16_16x16p = 0, count16x16_lp = 0;
5368 int count32x32 = 0;
5369 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005370 // counts->tx_size[max_depth][context_idx][this_depth_level]
5371 count4x4 += counts->tx_size[0][i][0];
5372 count4x4 += counts->tx_size[1][i][0];
5373 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005374
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005375 count8x8_8x8p += counts->tx_size[0][i][1];
Jingning Han2adcfb12016-10-27 11:19:53 -07005376 count8x8_lp += counts->tx_size[1][i][1];
5377 count8x8_lp += counts->tx_size[2][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005378
Jingning Han2adcfb12016-10-27 11:19:53 -07005379 count16x16_16x16p += counts->tx_size[1][i][2];
5380 count16x16_lp += counts->tx_size[2][i][2];
5381 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005382 }
5383#if CONFIG_EXT_TX && CONFIG_RECT_TX
5384 count4x4 += counts->tx_size_implied[0][TX_4X4];
5385 count4x4 += counts->tx_size_implied[1][TX_4X4];
5386 count4x4 += counts->tx_size_implied[2][TX_4X4];
5387 count4x4 += counts->tx_size_implied[3][TX_4X4];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005388 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5390 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005391 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5392 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5393 count32x32 += counts->tx_size_implied[3][TX_32X32];
5394#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5395 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5396#if CONFIG_SUPERTX
5397 cm->counts.supertx_size[TX_16X16] == 0 &&
5398 cm->counts.supertx_size[TX_32X32] == 0 &&
5399#endif // CONFIG_SUPERTX
5400 count32x32 == 0) {
5401 cm->tx_mode = ALLOW_8X8;
5402 reset_skip_tx_size(cm, TX_8X8);
5403 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5404 count8x8_lp == 0 && count16x16_lp == 0 &&
5405#if CONFIG_SUPERTX
5406 cm->counts.supertx_size[TX_8X8] == 0 &&
5407 cm->counts.supertx_size[TX_16X16] == 0 &&
5408 cm->counts.supertx_size[TX_32X32] == 0 &&
5409#endif // CONFIG_SUPERTX
5410 count32x32 == 0) {
5411 cm->tx_mode = ONLY_4X4;
5412 reset_skip_tx_size(cm, TX_4X4);
5413 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5414 cm->tx_mode = ALLOW_32X32;
5415 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5416#if CONFIG_SUPERTX
5417 cm->counts.supertx_size[TX_32X32] == 0 &&
5418#endif // CONFIG_SUPERTX
5419 count4x4 == 0) {
5420 cm->tx_mode = ALLOW_16X16;
5421 reset_skip_tx_size(cm, TX_16X16);
5422 }
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005423#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07005424 }
5425#endif
5426 } else {
5427 encode_frame_internal(cpi);
5428 }
5429}
5430
5431static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5432 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
Jingning Han36fe3202017-02-20 22:31:49 -08005433 const int intraonly, const int mi_row,
5434 const int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005435 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5436 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5437 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005438 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005439
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005440 if (bsize < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005441 int idx, idy;
5442 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5443 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5444 for (idy = 0; idy < 2; idy += num_4x4_h)
5445 for (idx = 0; idx < 2; idx += num_4x4_w) {
5446 const int bidx = idy * 2 + idx;
5447 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5448 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005449 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5450 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005451 ++counts->kf_y_mode[a][l][bmode];
5452 } else {
5453 ++counts->y_mode[0][bmode];
5454 }
5455 }
5456 } else {
5457 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005458 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5459 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005460 ++counts->kf_y_mode[above][left][y_mode];
5461 } else {
5462 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5463 }
5464 }
5465
Jingning Han36fe3202017-02-20 22:31:49 -08005466#if CONFIG_CB4X4
5467 if (bsize < BLOCK_8X8 && !is_chroma_reference(mi_row, mi_col)) return;
5468#else
5469 (void)mi_row;
5470 (void)mi_col;
5471#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005472 ++counts->uv_mode[y_mode][uv_mode];
5473}
5474
5475#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005476static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005477 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005478 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005479 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5480 const int tx_row = blk_row >> 1;
5481 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005482 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5483 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005484 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005485 xd->left_txfm_context + tx_row,
5486 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005487 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5488
Yaowu Xuc27fc142016-08-22 16:08:15 -07005489 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5490
5491 if (tx_size == plane_tx_size) {
5492 ++counts->txfm_partition[ctx][0];
5493 mbmi->tx_size = tx_size;
5494 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005495 xd->left_txfm_context + tx_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005497 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5498 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005499 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005500
Yaowu Xuc27fc142016-08-22 16:08:15 -07005501 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005502 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503
5504 if (tx_size == TX_8X8) {
5505 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5506 mbmi->tx_size = TX_4X4;
5507 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005508 xd->left_txfm_context + tx_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005509 return;
5510 }
5511
5512 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005513 int offsetr = (i >> 1) * bs;
5514 int offsetc = (i & 0x01) * bs;
5515 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5516 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517 }
5518 }
5519}
5520
Jingning Han9777afc2016-10-20 15:17:43 -07005521static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5522 BLOCK_SIZE plane_bsize, int mi_row,
5523 int mi_col, FRAME_COUNTS *td_counts) {
5524 MACROBLOCKD *xd = &x->e_mbd;
Jingning Han9ca05b72017-01-03 14:41:36 -08005525 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
5526 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005527 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005528 const int bh = tx_size_high_unit[max_tx_size];
5529 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005530 int idx, idy;
5531
5532 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5533 xd->left_txfm_context =
5534 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5535
5536 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005537 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005538 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5539 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005540}
5541
5542static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5543 int blk_col) {
5544 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5545 const int tx_row = blk_row >> 1;
5546 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005547 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5548 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5550
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5552
5553 if (tx_size == plane_tx_size) {
5554 mbmi->tx_size = tx_size;
5555 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005556 xd->left_txfm_context + tx_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005557
5558 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005559 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5560 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005561 int i;
5562
5563 if (tx_size == TX_8X8) {
5564 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5565 mbmi->tx_size = TX_4X4;
5566 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005567 xd->left_txfm_context + tx_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568 return;
5569 }
5570
5571 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005572 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005573 int offsetr = (i >> 1) * bsl;
5574 int offsetc = (i & 0x01) * bsl;
5575 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005576 }
5577 }
5578}
5579
Urvang Joshi52648442016-10-13 17:27:51 -07005580static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5581 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5582 int mi_row, int mi_col) {
Jingning Han9ca05b72017-01-03 14:41:36 -08005583 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
5584 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005585 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005586 const int bh = tx_size_high_unit[max_tx_size];
5587 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005588 int idx, idy;
5589
5590 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5591 xd->left_txfm_context =
5592 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5593
5594 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005595 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005596 set_txfm_context(xd, max_tx_size, idy, idx);
5597}
5598#endif
5599
Urvang Joshi52648442016-10-13 17:27:51 -07005600static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5601 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5602 int mi_col, BLOCK_SIZE bsize,
5603 PICK_MODE_CONTEXT *ctx, int *rate) {
5604 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605 MACROBLOCK *const x = &td->mb;
5606 MACROBLOCKD *const xd = &x->e_mbd;
5607 MODE_INFO **mi_8x8 = xd->mi;
5608 MODE_INFO *mi = mi_8x8[0];
5609 MB_MODE_INFO *mbmi = &mi->mbmi;
5610 const int seg_skip =
5611 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5612 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08005613 const int mi_width = mi_size_wide[bsize];
5614 const int mi_height = mi_size_high[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005615 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005616#if CONFIG_CB4X4
5617 const int unify_bsize = 1;
5618 const BLOCK_SIZE block_size = bsize;
5619#else
5620 const int unify_bsize = 0;
5621 const BLOCK_SIZE block_size = AOMMAX(bsize, BLOCK_8X8);
5622#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005623
Yushin Cho77bba8d2016-11-04 16:36:56 -07005624#if CONFIG_PVQ
5625 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005626 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005627#endif
5628
Jingning Han94ea1aa2016-11-08 12:10:46 -08005629 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005630 int plane;
5631 mbmi->skip = 1;
5632 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Jingning Han18c53c82017-02-17 14:49:57 -08005633 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
5634 mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005635 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005636 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
Jingning Han36fe3202017-02-20 22:31:49 -08005637 frame_is_intra_only(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005638
hui su5db97432016-10-14 16:10:14 -07005639 // TODO(huisu): move this into sum_intra_stats().
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005640 if (!dry_run && (bsize >= BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005641 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005642 (void)counts;
5643#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005644 if (mbmi->mode == DC_PRED
5645#if CONFIG_PALETTE
5646 && mbmi->palette_mode_info.palette_size[0] == 0
5647#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005648 ) {
5649 const int use_filter_intra_mode =
5650 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5651 ++counts->filter_intra[0][use_filter_intra_mode];
5652 }
Urvang Joshib100db72016-10-12 16:28:56 -07005653 if (mbmi->uv_mode == DC_PRED
5654#if CONFIG_PALETTE
5655 && mbmi->palette_mode_info.palette_size[1] == 0
5656#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005657 ) {
5658 const int use_filter_intra_mode =
5659 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5660 ++counts->filter_intra[1][use_filter_intra_mode];
5661 }
5662#endif // CONFIG_FILTER_INTRA
5663#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08005664#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08005665 if (av1_is_directional_mode(mbmi->mode, bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005666 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005667 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -08005668 p_angle = mode_to_angle_map[mbmi->mode] +
5669 mbmi->angle_delta[0] * av1_get_angle_step(mbmi->sb_type, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005670 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005671 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5672 }
hui sueda3d762016-12-06 16:58:23 -08005673#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07005674#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005675 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005676
Urvang Joshib100db72016-10-12 16:28:56 -07005677#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005678 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005679 for (plane = 0; plane <= 1; ++plane) {
5680 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5681 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5682 xd->plane[plane].color_index_map[0];
Fangwen Fub3be9262017-03-06 15:34:28 -08005683 // TODO(huisu): this increases the use of token buffer. Needs stretch
5684 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005685 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005686 }
5687 }
5688 }
Urvang Joshib100db72016-10-12 16:28:56 -07005689#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005690#if CONFIG_VAR_TX
5691 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5692#endif
Jingning Han18c53c82017-02-17 14:49:57 -08005693 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005694 } else {
5695 int ref;
5696 const int is_compound = has_second_ref(mbmi);
5697
5698 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5699 for (ref = 0; ref < 1 + is_compound; ++ref) {
5700 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5701 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005702 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5703 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005704 }
Yue Chen69f18e12016-09-08 14:48:15 -07005705#if CONFIG_WARPED_MOTION
5706 if (mbmi->motion_mode == WARPED_CAUSAL) {
5707 int i;
Yue Chen69f18e12016-09-08 14:48:15 -07005708 for (i = 0; i < 3; ++i) {
5709 const struct macroblockd_plane *pd = &xd->plane[i];
5710
5711 av1_warp_plane(&mbmi->wm_params[0],
5712#if CONFIG_AOM_HIGHBITDEPTH
5713 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5714#endif // CONFIG_AOM_HIGHBITDEPTH
5715 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
5716 pd->pre[0].stride, pd->dst.buf,
5717 ((mi_col * MI_SIZE) >> pd->subsampling_x),
5718 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -08005719 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
5720 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
5721 pd->dst.stride, pd->subsampling_x, pd->subsampling_y, 16,
5722 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07005723 }
5724 } else {
5725#endif // CONFIG_WARPED_MOTION
5726 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005727 av1_build_inter_predictors_sby(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005728
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005729 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005730#if CONFIG_WARPED_MOTION
5731 }
5732#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005733
Yue Chencb60b182016-10-13 15:18:22 -07005734#if CONFIG_MOTION_VAR
5735 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chenf27b1602017-01-13 11:11:43 -08005736#if CONFIG_NCOBMC
5737 if (dry_run == OUTPUT_ENABLED)
5738 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
5739 else
5740#endif
5741 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005742 }
Yue Chencb60b182016-10-13 15:18:22 -07005743#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005744
Jingning Han18c53c82017-02-17 14:49:57 -08005745 av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005746#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005747 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Han9ca05b72017-01-03 14:41:36 -08005748 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size,
5749 rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005750#else
Jingning Han18c53c82017-02-17 14:49:57 -08005751 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005752#endif
5753 }
5754
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005755 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005756#if CONFIG_VAR_TX
5757 TX_SIZE tx_size =
5758 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5759#else
5760 TX_SIZE tx_size = mbmi->tx_size;
5761#endif
Jingning Han5d2ed972017-03-06 12:19:54 -08005762 if (cm->tx_mode == TX_MODE_SELECT && !xd->lossless[mbmi->segment_id] &&
Jingning Han3daa4fd2017-01-20 10:33:50 -08005763#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_RECT_TX)
Jingning Hancb512282017-02-10 14:21:35 -08005764#if CONFIG_RECT_TX
Jingning Han3daa4fd2017-01-20 10:33:50 -08005765 mbmi->sb_type > BLOCK_4X4 &&
Jingning Han581d1692017-01-05 16:03:54 -08005766#else
Jingning Hancb512282017-02-10 14:21:35 -08005767 (mbmi->sb_type >= BLOCK_8X8 ||
5768 (mbmi->sb_type > BLOCK_4X4 && is_inter)) &&
5769#endif
5770#else
Jingning Han581d1692017-01-05 16:03:54 -08005771 mbmi->sb_type >= BLOCK_8X8 &&
5772#endif
Jingning Han94ea1aa2016-11-08 12:10:46 -08005773 !(is_inter && (mbmi->skip || seg_skip))) {
Jingning Han581d1692017-01-05 16:03:54 -08005774#if CONFIG_VAR_TX
5775 if (is_inter) {
5776 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5777 } else {
5778 const int tx_size_ctx = get_tx_size_context(xd);
5779 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5780 : intra_tx_size_cat_lookup[bsize];
5781 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
5782 const int depth = tx_size_to_depth(coded_tx_size);
5783 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5784 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
5785 }
5786#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005787 const int tx_size_ctx = get_tx_size_context(xd);
5788 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5789 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005790 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005791 const int depth = tx_size_to_depth(coded_tx_size);
Jingning Han581d1692017-01-05 16:03:54 -08005792
5793 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5794#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005795#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005796 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005797#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005798 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005799 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005800 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005801 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005802 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005804 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005805 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005806 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005807 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005808 } else {
Urvang Joshifeb925f2016-12-05 10:37:29 -08005809#if CONFIG_EXT_TX && CONFIG_RECT_TX
5810 intra_tx_size = tx_size;
5811#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005812 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005813#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005814 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08005815#if CONFIG_EXT_TX && CONFIG_RECT_TX
5816 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
5817 [txsize_sqr_up_map[tx_size]];
5818#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819
Urvang Joshi454280d2016-10-14 16:51:44 -07005820 for (j = 0; j < mi_height; j++)
5821 for (i = 0; i < mi_width; i++)
5822 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005823 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005824
5825#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005826 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5827 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005828#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005829 }
Jingning Han9777afc2016-10-20 15:17:43 -07005830
Jingning Hane67b38a2016-11-04 10:30:00 -07005831 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005832 ++td->counts
5833 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005834#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08005835 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) >
5836 1 &&
5837 cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005838 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08005839 const int eset =
5840 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005841 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005842 if (is_inter) {
clang-format55ce9e02017-02-15 22:27:12 -08005843 ++td->counts
5844 ->inter_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005845 } else {
Urvang Joshifeb925f2016-12-05 10:37:29 -08005846 ++td->counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
5847 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005848 }
5849 }
5850 }
5851#else
Yaowu Xu7a08fe52017-02-13 18:49:29 -08005852 if (tx_size < TX_32X32 &&
5853 ((!cm->seg.enabled && cm->base_qindex > 0) ||
5854 (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
5855 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005856 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005857 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005858 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005859 } else {
clang-format55ce9e02017-02-15 22:27:12 -08005860 ++td->counts
5861 ->intra_ext_tx[tx_size][intra_mode_to_tx_type_context[mbmi->mode]]
5862 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863 }
5864 }
5865#endif // CONFIG_EXT_TX
5866 }
5867
5868#if CONFIG_VAR_TX
Jingning Han581d1692017-01-05 16:03:54 -08005869 if (cm->tx_mode == TX_MODE_SELECT &&
5870#if CONFIG_CB4X4
Jingning Han3daa4fd2017-01-20 10:33:50 -08005871 mbmi->sb_type > BLOCK_4X4 &&
Jingning Han581d1692017-01-05 16:03:54 -08005872#else
5873 mbmi->sb_type >= BLOCK_8X8 &&
5874#endif
5875 is_inter && !(mbmi->skip || seg_skip)) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005876 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005877 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005878 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005879 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005880 if (is_inter)
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005881 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005882 else
Jingning Han3daa4fd2017-01-20 10:33:50 -08005883 tx_size = (bsize > BLOCK_4X4) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005884 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005885 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005887#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005888}
5889
5890#if CONFIG_SUPERTX
5891static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5892 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5893#if CONFIG_EXT_INTER
5894 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5895#endif // CONFIG_EXT_INTER
5896 return 0;
5897}
5898
Urvang Joshi52648442016-10-13 17:27:51 -07005899static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5900 int mi_row, int mi_col, BLOCK_SIZE bsize,
5901 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005902 const AV1_COMMON *const cm = &cpi->common;
Jingning Han1856e432016-12-21 14:58:39 -08005903 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005904 const PARTITION_TYPE partition = pc_tree->partitioning;
5905 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5906#if CONFIG_EXT_PARTITION_TYPES
5907 int i;
5908#endif
Jingning Hanfeb517c2016-12-21 16:02:07 -08005909#if CONFIG_CB4X4
5910 const int unify_bsize = 1;
5911#else
5912 const int unify_bsize = 0;
5913#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005914
Jingning Hanfeb517c2016-12-21 16:02:07 -08005915#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005916 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08005917#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918
5919 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5920
5921 switch (partition) {
5922 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5923 case PARTITION_VERT:
5924 if (check_intra_b(&pc_tree->vertical[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005925 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5927 }
5928 break;
5929 case PARTITION_HORZ:
5930 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005931 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005932 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5933 }
5934 break;
5935 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08005936 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5938 } else {
5939 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5940 pc_tree->split[0]))
5941 return 1;
5942 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5943 pc_tree->split[1]))
5944 return 1;
5945 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5946 pc_tree->split[2]))
5947 return 1;
5948 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5949 pc_tree->split[3]))
5950 return 1;
5951 }
5952 break;
5953#if CONFIG_EXT_PARTITION_TYPES
5954 case PARTITION_HORZ_A:
5955 for (i = 0; i < 3; i++) {
5956 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5957 }
5958 break;
5959 case PARTITION_HORZ_B:
5960 for (i = 0; i < 3; i++) {
5961 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5962 }
5963 break;
5964 case PARTITION_VERT_A:
5965 for (i = 0; i < 3; i++) {
5966 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5967 }
5968 break;
5969 case PARTITION_VERT_B:
5970 for (i = 0; i < 3; i++) {
5971 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5972 }
5973 break;
5974#endif // CONFIG_EXT_PARTITION_TYPES
5975 default: assert(0);
5976 }
5977 return 0;
5978}
5979
5980static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5981 return ctx->mic.mbmi.tx_size == supertx_size;
5982}
5983
5984static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5985 PC_TREE *pc_tree) {
5986 PARTITION_TYPE partition;
5987 BLOCK_SIZE subsize;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005988#if CONFIG_CB4X4
5989 const int unify_bsize = 1;
5990#else
5991 const int unify_bsize = 0;
5992#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005993
5994 partition = pc_tree->partitioning;
5995 subsize = get_subsize(bsize, partition);
5996 switch (partition) {
5997 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5998 case PARTITION_VERT:
5999 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
6000 case PARTITION_HORZ:
6001 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
6002 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006003 if (bsize == BLOCK_8X8 && !unify_bsize)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006004 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
6005 else
6006 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
6007#if CONFIG_EXT_PARTITION_TYPES
6008 case PARTITION_HORZ_A:
6009 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
6010 case PARTITION_HORZ_B:
6011 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
6012 case PARTITION_VERT_A:
6013 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
6014 case PARTITION_VERT_B:
6015 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
6016#endif // CONFIG_EXT_PARTITION_TYPES
6017 default: assert(0); return 0;
6018 }
6019}
6020
Urvang Joshi52648442016-10-13 17:27:51 -07006021static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006022#if CONFIG_EXT_INTER
6023 int mi_row_ori, int mi_col_ori,
6024#endif // CONFIG_EXT_INTER
6025 int mi_row_pred, int mi_col_pred,
6026 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
6027 // Used in supertx
6028 // (mi_row_ori, mi_col_ori): location for mv
6029 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07006030 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006031 MACROBLOCK *const x = &td->mb;
6032 MACROBLOCKD *const xd = &x->e_mbd;
6033 MODE_INFO *mi_8x8 = xd->mi[0];
6034 MODE_INFO *mi = mi_8x8;
6035 MB_MODE_INFO *mbmi = &mi->mbmi;
6036 int ref;
6037 const int is_compound = has_second_ref(mbmi);
6038
6039 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
6040
6041 for (ref = 0; ref < 1 + is_compound; ++ref) {
6042 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006043 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
6044 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006045 }
6046
6047 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07006048 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006050 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006051#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006052 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006053 else
Yaowu Xuf883b422016-08-30 14:01:10 -07006054 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006055#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006056 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006058 mi_row_pred, mi_col_pred,
6059 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060}
6061
Urvang Joshi52648442016-10-13 17:27:51 -07006062static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006063 const TileInfo *const tile, int block,
6064 int mi_row_ori, int mi_col_ori, int mi_row_pred,
6065 int mi_col_pred, int mi_row_top, int mi_col_top,
6066 uint8_t *dst_buf[3], int dst_stride[3],
6067 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006068 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006069 // Used in supertx
6070 // (mi_row_ori, mi_col_ori): location for mv
6071 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
6072 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
6073 // block: sub location of sub8x8 blocks
6074 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
6075 // bextend: 1: region to predict is an extension of ori; 0: not
6076
6077 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07006078 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006079 MACROBLOCKD *const xd = &x->e_mbd;
6080 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
6081 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
Jingning Han1856e432016-12-21 14:58:39 -08006082 const int mi_width_top = mi_size_wide[bsize_top];
6083 const int mi_height_top = mi_size_high[bsize_top];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006084
6085 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
6086 mi_row_pred >= mi_row_top + mi_height_top ||
6087 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
6088 mi_col_pred >= cm->mi_cols)
6089 return;
6090
6091 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
6092 mi_col_ori, bsize_pred);
6093 xd->plane[0].dst.stride = dst_stride[0];
6094 xd->plane[1].dst.stride = dst_stride[1];
6095 xd->plane[2].dst.stride = dst_stride[2];
6096 xd->plane[0].dst.buf = dst_buf[0] +
6097 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
6098 (c >> xd->plane[0].subsampling_x);
6099 xd->plane[1].dst.buf = dst_buf[1] +
6100 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
6101 (c >> xd->plane[1].subsampling_x);
6102 xd->plane[2].dst.buf = dst_buf[2] +
6103 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
6104 (c >> xd->plane[2].subsampling_x);
6105
6106 predict_superblock(cpi, td,
6107#if CONFIG_EXT_INTER
6108 mi_row_ori, mi_col_ori,
6109#endif // CONFIG_EXT_INTER
6110 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
6111
Jingning Hanfc0476d2016-12-21 14:43:16 -08006112 if (!dry_run && !bextend)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07006113 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006114}
6115
Urvang Joshi52648442016-10-13 17:27:51 -07006116static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6118 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006119 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006120 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
6121 // dir: 0-lower, 1-upper, 2-left, 3-right
6122 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
6123 MACROBLOCKD *xd = &td->mb.e_mbd;
Jingning Han1856e432016-12-21 14:58:39 -08006124 const int mi_width = mi_size_wide[bsize];
6125 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006126 int xss = xd->plane[1].subsampling_x;
6127 int yss = xd->plane[1].subsampling_y;
Jingning Hanfeb517c2016-12-21 16:02:07 -08006128#if CONFIG_CB4X4
6129 const int unify_bsize = 1;
6130#else
6131 const int unify_bsize = 0;
6132#endif
6133 int b_sub8x8 = (bsize < BLOCK_8X8) && !unify_bsize ? 1 : 0;
Jingning Han24f24a52016-12-27 10:13:28 -08006134 int wide_unit, high_unit;
6135 int i, j;
6136 int ext_offset = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006137
6138 BLOCK_SIZE extend_bsize;
Jingning Han24f24a52016-12-27 10:13:28 -08006139 int mi_row_pred, mi_col_pred;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006140
6141 if (dir == 0 || dir == 1) { // lower and upper
Jingning Han1856e432016-12-21 14:58:39 -08006142 extend_bsize =
6143 (mi_width == mi_size_wide[BLOCK_8X8] || bsize < BLOCK_8X8 || xss < yss)
6144 ? BLOCK_8X8
6145 : BLOCK_16X8;
Jingning Han24f24a52016-12-27 10:13:28 -08006146
6147#if CONFIG_CB4X4
6148 if (bsize < BLOCK_8X8) {
6149 extend_bsize = BLOCK_4X4;
6150 ext_offset = mi_size_wide[BLOCK_8X8];
6151 }
6152#endif
6153 wide_unit = mi_size_wide[extend_bsize];
6154 high_unit = mi_size_high[extend_bsize];
6155
6156 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -(mi_height + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157 mi_col_pred = mi_col;
6158
Jingning Han24f24a52016-12-27 10:13:28 -08006159 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6160 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6161 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6162 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006163 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6164 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165 } else if (dir == 2 || dir == 3) { // left and right
Jingning Han1856e432016-12-21 14:58:39 -08006166 extend_bsize =
6167 (mi_height == mi_size_high[BLOCK_8X8] || bsize < BLOCK_8X8 || yss < xss)
6168 ? BLOCK_8X8
6169 : BLOCK_8X16;
Jingning Han24f24a52016-12-27 10:13:28 -08006170#if CONFIG_CB4X4
6171 if (bsize < BLOCK_8X8) {
6172 extend_bsize = BLOCK_4X4;
6173 ext_offset = mi_size_wide[BLOCK_8X8];
6174 }
6175#endif
6176 wide_unit = mi_size_wide[extend_bsize];
6177 high_unit = mi_size_high[extend_bsize];
6178
Yaowu Xuc27fc142016-08-22 16:08:15 -07006179 mi_row_pred = mi_row;
Jingning Han24f24a52016-12-27 10:13:28 -08006180 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -(mi_width + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006181
Jingning Han24f24a52016-12-27 10:13:28 -08006182 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6183 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6184 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6185 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006186 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6187 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006188 } else {
6189 extend_bsize = BLOCK_8X8;
Jingning Han24f24a52016-12-27 10:13:28 -08006190#if CONFIG_CB4X4
6191 if (bsize < BLOCK_8X8) {
6192 extend_bsize = BLOCK_4X4;
6193 ext_offset = mi_size_wide[BLOCK_8X8];
6194 }
6195#endif
6196 wide_unit = mi_size_wide[extend_bsize];
6197 high_unit = mi_size_high[extend_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198
Jingning Han24f24a52016-12-27 10:13:28 -08006199 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height
6200 : -(mi_height + ext_offset));
6201 mi_col_pred =
6202 mi_col + ((dir == 6 || dir == 7) ? mi_width : -(mi_width + ext_offset));
6203
6204 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6205 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6206 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6207 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
6208 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6209 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006210 }
6211}
6212
Urvang Joshi52648442016-10-13 17:27:51 -07006213static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006214 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6215 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006216 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006217 uint8_t *dst_buf[3], int dst_stride[3]) {
6218 assert(block >= 0 && block < 4);
6219 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006220 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006221 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006222 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006223 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006224 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006225 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006226 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006228 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006229 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006230 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006231 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006232 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006233 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006234 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006235}
6236
6237// This function generates prediction for multiple blocks, between which
6238// discontinuity around boundary is reduced by smoothing masks. The basic
6239// smoothing mask is a soft step function along horz/vert direction. In more
6240// complicated case when a block is split into 4 subblocks, the basic mask is
6241// first applied to neighboring subblocks (2 pairs) in horizontal direction and
6242// then applied to the 2 masked prediction mentioned above in vertical direction
6243// If the block is split into more than one level, at every stage, masked
6244// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07006245static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006246 const TileInfo *const tile, int mi_row,
6247 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006248 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006249 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
6250 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006251 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006252 MACROBLOCK *const x = &td->mb;
6253 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse55c6bde2017-01-12 15:55:31 -08006254 const int hbs = mi_size_wide[bsize] / 2;
Jingning Hanfeb517c2016-12-21 16:02:07 -08006255 const int is_partition_root = bsize >= BLOCK_8X8;
6256 const int ctx = is_partition_root
Alex Converse55c6bde2017-01-12 15:55:31 -08006257 ? partition_plane_context(xd, mi_row, mi_col,
6258#if CONFIG_UNPOISON_PARTITION_CTX
6259 mi_row + hbs < cm->mi_rows,
6260 mi_col + hbs < cm->mi_cols,
6261#endif
6262 bsize)
6263 : -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264 const PARTITION_TYPE partition = pc_tree->partitioning;
6265 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
6266#if CONFIG_EXT_PARTITION_TYPES
6267 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
6268#endif
6269
6270 int i;
6271 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
6272 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6273 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6274 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6275 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6276 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6277 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
Jingning Hanfeb517c2016-12-21 16:02:07 -08006278#if CONFIG_CB4X4
6279 const int unify_bsize = 1;
6280#else
6281 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006282 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08006283#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006284
6285 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
6286
Yaowu Xuf883b422016-08-30 14:01:10 -07006287#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006288 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6289 int len = sizeof(uint16_t);
6290 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6291 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
6292 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
6293 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6294 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
6295 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
6296 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
6297 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
6298 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
6299 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006300#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006301 dst_buf1[0] = tmp_buf1;
6302 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
6303 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
6304 dst_buf2[0] = tmp_buf2;
6305 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
6306 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
6307 dst_buf3[0] = tmp_buf3;
6308 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
6309 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006310#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006311 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006312#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313
Alex Converse55c6bde2017-01-12 15:55:31 -08006314 if (!dry_run && ctx >= 0 && bsize < top_bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -07006315 // Explicitly cast away const.
6316 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6317 frame_counts->partition[ctx][partition]++;
6318 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006319
6320 for (i = 0; i < MAX_MB_PLANE; i++) {
6321 xd->plane[i].dst.buf = dst_buf[i];
6322 xd->plane[i].dst.stride = dst_stride[i];
6323 }
6324
6325 switch (partition) {
6326 case PARTITION_NONE:
6327 assert(bsize < top_bsize);
6328 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6329 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006330 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006331 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006332 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006333 break;
6334 case PARTITION_HORZ:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006335 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006336 // Fisrt half
6337 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6338 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006339 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006340 if (bsize < top_bsize)
6341 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006342 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006343
6344 // Second half
6345 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6346 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006347 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006348 if (bsize < top_bsize)
6349 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006350 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006351
6352 // Smooth
6353 xd->plane[0].dst.buf = dst_buf[0];
6354 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006355 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006356 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6357 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6358 0);
6359 } else {
6360 // First half
6361 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6362 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006363 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364 if (bsize < top_bsize)
6365 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006366 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006367 else
6368 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006369 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006370
6371 if (mi_row + hbs < cm->mi_rows) {
6372 // Second half
6373 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6374 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006375 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006376 if (bsize < top_bsize)
6377 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006378 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379 dst_stride1);
6380 else
6381 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006382 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383 dst_stride1, 1);
6384
6385 // Smooth
6386 for (i = 0; i < MAX_MB_PLANE; i++) {
6387 xd->plane[i].dst.buf = dst_buf[i];
6388 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006389 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006390 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6391 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6392 PARTITION_HORZ, i);
6393 }
6394 }
6395 }
6396 break;
6397 case PARTITION_VERT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006398 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006399 // First half
6400 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6401 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006402 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006403 if (bsize < top_bsize)
6404 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006405 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006406
6407 // Second half
6408 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6409 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006410 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006411 if (bsize < top_bsize)
6412 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006413 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006414
6415 // Smooth
6416 xd->plane[0].dst.buf = dst_buf[0];
6417 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006418 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006419 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6420 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6421 0);
6422 } else {
6423 // bsize: not important, not useful
6424 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6425 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006426 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006427 if (bsize < top_bsize)
6428 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006429 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006430 else
6431 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006432 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006433
6434 if (mi_col + hbs < cm->mi_cols) {
6435 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6436 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006437 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006438 if (bsize < top_bsize)
6439 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006440 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6441 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006442 else
6443 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006444 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6445 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006446
6447 for (i = 0; i < MAX_MB_PLANE; i++) {
6448 xd->plane[i].dst.buf = dst_buf[i];
6449 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006450 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006451 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6452 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6453 PARTITION_VERT, i);
6454 }
6455 }
6456 }
6457 break;
6458 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006459 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006460 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6461 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006462 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006463 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6464 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006465 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006466 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6467 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006468 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006469 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6470 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006471 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006472
6473 if (bsize < top_bsize) {
6474 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006475 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006476 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006477 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006478 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006479 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006480 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006481 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006482 }
6483 } else {
6484 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006485 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6486 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006487 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6488 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006489 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6490 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006491 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6492 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006493 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6494 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006495 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6496 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006497 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006498 top_bsize, dst_buf3, dst_stride3,
6499 pc_tree->split[3]);
6500 }
6501 for (i = 0; i < MAX_MB_PLANE; i++) {
Jingning Han9e0976a2016-12-27 17:52:42 -08006502#if !CONFIG_CB4X4
Jingning Han24f24a52016-12-27 10:13:28 -08006503 if (bsize == BLOCK_8X8 && i != 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006504 continue; // Skip <4x4 chroma smoothing
Jingning Han9e0976a2016-12-27 17:52:42 -08006505#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006506 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006507 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006508 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6509 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6510 PARTITION_VERT, i);
6511 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006512 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006513 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6514 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6515 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006516 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006517 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6518 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6519 PARTITION_HORZ, i);
6520 }
6521 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Jingning Han24f24a52016-12-27 10:13:28 -08006522 if (bsize == BLOCK_8X8 && i != 0)
6523 continue; // Skip <4x4 chroma smoothing
6524
Yaowu Xuf883b422016-08-30 14:01:10 -07006525 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006526 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6527 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6528 PARTITION_HORZ, i);
6529 }
6530 }
6531 break;
6532#if CONFIG_EXT_PARTITION_TYPES
6533 case PARTITION_HORZ_A:
6534 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6535 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006536 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006537 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006538 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006539
6540 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6541 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006542 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006543 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006544 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545
6546 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6547 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006548 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006549 if (bsize < top_bsize)
6550 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006551 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006552 else
6553 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006554 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006555
6556 for (i = 0; i < MAX_MB_PLANE; i++) {
6557 xd->plane[i].dst.buf = dst_buf[i];
6558 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006559 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006560 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6561 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6562 i);
6563 }
6564 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006565 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006566 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6567 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6568 i);
6569 }
6570
6571 break;
6572 case PARTITION_VERT_A:
6573
6574 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6575 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006576 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006577 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006578 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006579
6580 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6581 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006582 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006583 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006584 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006585
6586 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6587 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006588 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006589 if (bsize < top_bsize)
6590 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006591 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006592 else
6593 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006594 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006595
6596 for (i = 0; i < MAX_MB_PLANE; i++) {
6597 xd->plane[i].dst.buf = dst_buf[i];
6598 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006599 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006600 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6601 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6602 i);
6603 }
6604 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006605 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006606 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6607 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6608 i);
6609 }
6610 break;
6611 case PARTITION_HORZ_B:
6612
6613 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6614 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006615 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006616 if (bsize < top_bsize)
6617 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006618 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006619 else
6620 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006621 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006622
6623 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6624 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006625 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006626 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006627 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006628
6629 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6630 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006631 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006632 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006633 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006634 dst_stride2);
6635
6636 for (i = 0; i < MAX_MB_PLANE; i++) {
6637 xd->plane[i].dst.buf = dst_buf1[i];
6638 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006639 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006640 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6641 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6642 PARTITION_VERT, i);
6643 }
6644 for (i = 0; i < MAX_MB_PLANE; i++) {
6645 xd->plane[i].dst.buf = dst_buf[i];
6646 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006647 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006648 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6649 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6650 i);
6651 }
6652 break;
6653 case PARTITION_VERT_B:
6654
6655 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6656 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006657 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006658 if (bsize < top_bsize)
6659 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006660 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006661 else
6662 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006663 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006664
6665 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6666 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006667 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006668 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006669 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006670
6671 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6672 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006673 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006674 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006675 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006676 dst_stride2);
6677
6678 for (i = 0; i < MAX_MB_PLANE; i++) {
6679 xd->plane[i].dst.buf = dst_buf1[i];
6680 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006681 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006682 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6683 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6684 PARTITION_HORZ, i);
6685 }
6686 for (i = 0; i < MAX_MB_PLANE; i++) {
6687 xd->plane[i].dst.buf = dst_buf[i];
6688 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006689 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006690 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6691 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6692 i);
6693 }
6694 break;
6695#endif // CONFIG_EXT_PARTITION_TYPES
6696 default: assert(0);
6697 }
6698
6699#if CONFIG_EXT_PARTITION_TYPES
6700 if (bsize < top_bsize)
6701 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6702#else
6703 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6704 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6705#endif // CONFIG_EXT_PARTITION_TYPES
6706}
6707
Urvang Joshi52648442016-10-13 17:27:51 -07006708static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006709 const TileInfo *const tile, int mi_row, int mi_col,
6710 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6711 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006712 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006713 MACROBLOCK *const x = &td->mb;
6714 MACROBLOCKD *const xd = &x->e_mbd;
6715 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6716 base_rate = *tmp_rate;
6717 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6718 uint8_t *dst_buf[3];
6719 int dst_stride[3];
6720 TX_SIZE tx_size;
6721 MB_MODE_INFO *mbmi;
6722 TX_TYPE tx_type, best_tx_nostx;
6723#if CONFIG_EXT_TX
Yaowu Xu7640f5f2017-02-27 09:45:34 -08006724 int ext_tx_set;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006725#endif // CONFIG_EXT_TX
6726 int tmp_rate_tx = 0, skip_tx = 0;
6727 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6728
6729 set_skip_context(xd, mi_row, mi_col);
6730 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006731 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006732 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006733 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6734 dst_buf[plane] = xd->plane[plane].dst.buf;
6735 dst_stride[plane] = xd->plane[plane].dst.stride;
6736 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006737 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006738 bsize, dst_buf, dst_stride, pc_tree);
6739
6740 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6741 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6742
6743 mbmi = &xd->mi[0]->mbmi;
6744 best_tx_nostx = mbmi->tx_type;
6745
6746 *best_tx = DCT_DCT;
6747
6748 // chroma
6749 skippable_uv = 1;
6750 rate_uv = 0;
6751 dist_uv = 0;
6752 sse_uv = 0;
6753 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6754#if CONFIG_VAR_TX
6755 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6756 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6757 const struct macroblockd_plane *const pd = &xd->plane[plane];
6758 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006759 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006760 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006761
6762 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006763 tx_size =
6764 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006765 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006766 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6767
Yaowu Xuf883b422016-08-30 14:01:10 -07006768 av1_subtract_plane(x, bsize, plane);
6769 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006770 get_plane_block_size(bsize, pd), coeff_ctx,
6771 &this_rd_stats);
6772
6773 this_rate = this_rd_stats.rate;
6774 this_dist = this_rd_stats.dist;
6775 pnsse = this_rd_stats.sse;
6776 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006777#else
6778 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006779 tx_size =
6780 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006781 av1_subtract_plane(x, bsize, plane);
6782 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6783 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006784#endif // CONFIG_VAR_TX
6785
6786 rate_uv += this_rate;
6787 dist_uv += this_dist;
6788 sse_uv += pnsse;
6789 skippable_uv &= pnskip;
6790 }
6791
6792 // luma
6793 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006794 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006795#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08006796 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006797#endif // CONFIG_EXT_TX
6798 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6799#if CONFIG_VAR_TX
6800 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6801 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6802 const struct macroblockd_plane *const pd = &xd->plane[0];
6803 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006804 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006805#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006806
Yaowu Xuc27fc142016-08-22 16:08:15 -07006807#if CONFIG_EXT_TX
6808 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6809#else
6810 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6811#endif // CONFIG_EXT_TX
6812 mbmi->tx_type = tx_type;
6813
6814#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006815 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006816
Yaowu Xuf883b422016-08-30 14:01:10 -07006817 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006818 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006819 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6820 &this_rd_stats);
6821
6822 this_rate = this_rd_stats.rate;
6823 this_dist = this_rd_stats.dist;
6824 pnsse = this_rd_stats.sse;
6825 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006826#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006827 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6828 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006829#endif // CONFIG_VAR_TX
6830
6831#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08006832 if (get_ext_tx_types(tx_size, bsize, 1, cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07006833 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6834 if (ext_tx_set > 0)
6835 this_rate +=
6836 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6837 }
6838#else
6839 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6840 this_rate != INT_MAX) {
6841 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6842 }
6843#endif // CONFIG_EXT_TX
6844 *tmp_rate = rate_uv + this_rate;
6845 *tmp_dist = dist_uv + this_dist;
6846 sse = sse_uv + pnsse;
6847 skippable = skippable_uv && pnskip;
6848 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006849 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006850 x->skip = 1;
6851 } else {
6852 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6853 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006854 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006855 x->skip = 0;
6856 } else {
6857 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006858 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006859 x->skip = 1;
6860 }
6861 }
6862 *tmp_rate += base_rate;
6863 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6864 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6865 *best_tx = tx_type;
6866 bestrd_tx = rd_tx;
6867 tmp_rate_tx = *tmp_rate;
6868 tmp_dist_tx = *tmp_dist;
6869 skip_tx = x->skip;
6870 }
6871 }
6872 *tmp_rate = tmp_rate_tx;
6873 *tmp_dist = tmp_dist_tx;
6874 x->skip = skip_tx;
6875#if CONFIG_VAR_TX
6876 for (plane = 0; plane < 1; ++plane)
6877 memset(x->blk_skip[plane], x->skip,
6878 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6879#endif // CONFIG_VAR_TX
6880 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6881}
6882#endif // CONFIG_SUPERTX