blob: 01fe0b70f477aa350873235f30dd94376f5e7cfd [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)));
296 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
297 cm->mi_cols);
298
299 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700300 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700301
302 // R/D setup.
303 x->rddiv = cpi->rd.RDDIV;
304 x->rdmult = cpi->rd.RDMULT;
305
Yaowu Xuf883b422016-08-30 14:01:10 -0700306 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700307 xd->tile = *tile;
308}
309
Urvang Joshi52648442016-10-13 17:27:51 -0700310static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700311 MACROBLOCK *const x, int mi_row, int mi_col,
312 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700313 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700314 MACROBLOCKD *const xd = &x->e_mbd;
315 MB_MODE_INFO *mbmi;
316 const struct segmentation *const seg = &cm->seg;
317
318 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
319
320 mbmi = &xd->mi[0]->mbmi;
321
322 // Setup segment ID.
323 if (seg->enabled) {
324 if (!cpi->vaq_refresh) {
325 const uint8_t *const map =
326 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
327 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
328 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700329 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700330 } else {
331 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700332 }
333
334#if CONFIG_SUPERTX
335 mbmi->segment_id_supertx = MAX_SEGMENTS;
336#endif // CONFIG_SUPERTX
337}
338
339#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700340static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700341 const TileInfo *const tile, int mi_row,
342 int mi_col, BLOCK_SIZE bsize) {
343 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700344 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700345 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800346 const int mi_width = mi_size_wide[bsize];
347 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700348
349 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
350
351 // Set up distance of MB to edge of frame in 1/8th pel units.
352 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
353 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
354 cm->mi_cols);
355}
356
Urvang Joshi52648442016-10-13 17:27:51 -0700357static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700358 const TileInfo *const tile, int mi_row_pred,
359 int mi_col_pred, int mi_row_ori, int mi_col_ori,
360 BLOCK_SIZE bsize_pred) {
361 // Used in supertx
362 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
363 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
364 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700365 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800367 const int mi_width = mi_size_wide[bsize_pred];
368 const int mi_height = mi_size_high[bsize_pred];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700369
370 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
371
372 // Set up limit values for MV components.
373 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700374 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
375 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
376 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
377 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700378
Jingning Hanfeb517c2016-12-21 16:02:07 -0800379// Set up distance of MB to edge of frame in 1/8th pel units.
380#if !CONFIG_CB4X4
Jingning Han5b7706a2016-12-21 09:55:10 -0800381 assert(!(mi_col_pred & (mi_width - mi_size_wide[BLOCK_8X8])) &&
382 !(mi_row_pred & (mi_height - mi_size_high[BLOCK_8X8])));
Jingning Hanfeb517c2016-12-21 16:02:07 -0800383#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700384 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
385 cm->mi_rows, cm->mi_cols);
386 xd->up_available = (mi_row_ori > tile->mi_row_start);
387 xd->left_available = (mi_col_ori > tile->mi_col_start);
388
389 // R/D setup.
390 x->rddiv = cpi->rd.RDDIV;
391 x->rdmult = cpi->rd.RDMULT;
392}
393
Yaowu Xuf883b422016-08-30 14:01:10 -0700394static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700395 MACROBLOCK *const x, const int mi_row,
396 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700397 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700398 const struct segmentation *seg = &cm->seg;
Jingning Han5b7706a2016-12-21 09:55:10 -0800399 const int miw = AOMMIN(mi_size_wide[bsize], cm->mi_cols - mi_col);
400 const int mih = AOMMIN(mi_size_high[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700401 const int mi_offset = mi_row * cm->mi_stride + mi_col;
402 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
403 int r, c;
404 int seg_id_supertx = MAX_SEGMENTS;
405
406 if (!seg->enabled) {
407 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 } else {
409 // Find the minimum segment_id
410 for (r = 0; r < mih; r++)
411 for (c = 0; c < miw; c++)
412 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700413 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
415
416 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700417 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700418 }
419
420 // Assign the the segment_id back to segment_id_supertx
421 for (r = 0; r < mih; r++)
422 for (c = 0; c < miw; c++)
423 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
424}
425#endif // CONFIG_SUPERTX
426
Yaowu Xuf883b422016-08-30 14:01:10 -0700427static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700428 MACROBLOCKD *const xd, int mi_row, int mi_col,
429 BLOCK_SIZE bsize) {
430 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
431 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
432 xd->mi[0]->mbmi.sb_type = bsize;
433 }
434}
435
Yaowu Xuf883b422016-08-30 14:01:10 -0700436static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
438 int mi_col, const int64_t *const threshold,
439 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700440 AV1_COMMON *const cm = &cpi->common;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800441 const int hbw = mi_size_wide[vt->bsize] / 2;
442 const int hbh = mi_size_high[vt->bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700443 const int has_cols = mi_col + hbw < cm->mi_cols;
444 const int has_rows = mi_row + hbh < cm->mi_rows;
445
446 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
447
448 assert(vt->bsize >= BLOCK_8X8);
449
450 assert(hbh == hbw);
451
452 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
453 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
454 return;
455 }
456
457 if (vt->force_split || (!has_cols && !has_rows)) goto split;
458
459 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
460 // variance is below threshold, otherwise split will be selected.
461 // No check for vert/horiz split as too few samples for variance.
462 if (vt->bsize == bsize_min[0]) {
463 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
464 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
465 return;
466 } else {
467 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
468 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
469 if (vt->bsize > BLOCK_8X8) {
470 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
471 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
472 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
473 }
474 return;
475 }
476 } else if (vt->bsize > bsize_min[0]) {
477 // For key frame: take split for bsize above 32X32 or very high variance.
478 if (cm->frame_type == KEY_FRAME &&
479 (vt->bsize > BLOCK_32X32 ||
480 vt->variances.none.variance > (threshold[0] << 4))) {
481 goto split;
482 }
483 // If variance is low, take the bsize (no split).
484 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
485 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
486 return;
487 }
488
489 // Check vertical split.
490 if (has_rows) {
491 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
492 if (vt->variances.vert[0].variance < threshold[0] &&
493 vt->variances.vert[1].variance < threshold[0] &&
494 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
495 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
496 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
497 return;
498 }
499 }
500 // Check horizontal split.
501 if (has_cols) {
502 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
503 if (vt->variances.horz[0].variance < threshold[0] &&
504 vt->variances.horz[1].variance < threshold[0] &&
505 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
506 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
507 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
508 return;
509 }
510 }
511 }
512
513split : {
514 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
515 bsize_min + 1);
516 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
517 threshold + 1, bsize_min + 1);
518 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
519 threshold + 1, bsize_min + 1);
520 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
521 threshold + 1, bsize_min + 1);
522 return;
523}
524}
525
526// Set the variance split thresholds for following the block sizes:
527// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
528// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
529// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700530static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
531 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700532 const int is_key_frame = (cm->frame_type == KEY_FRAME);
533 const int threshold_multiplier = is_key_frame ? 20 : 1;
534 const int64_t threshold_base =
535 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
536 if (is_key_frame) {
537 thresholds[1] = threshold_base;
538 thresholds[2] = threshold_base >> 2;
539 thresholds[3] = threshold_base >> 2;
540 thresholds[4] = threshold_base << 2;
541 } else {
542 thresholds[2] = threshold_base;
543 if (cm->width <= 352 && cm->height <= 288) {
544 thresholds[1] = threshold_base >> 2;
545 thresholds[3] = threshold_base << 3;
546 } else {
547 thresholds[1] = threshold_base;
548 thresholds[2] = (5 * threshold_base) >> 2;
549 if (cm->width >= 1920 && cm->height >= 1080)
550 thresholds[2] = (7 * threshold_base) >> 2;
551 thresholds[3] = threshold_base << cpi->oxcf.speed;
552 }
553 }
554 thresholds[0] = INT64_MIN;
555}
556
Yaowu Xuf883b422016-08-30 14:01:10 -0700557void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
558 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559 SPEED_FEATURES *const sf = &cpi->sf;
560 const int is_key_frame = (cm->frame_type == KEY_FRAME);
561 if (sf->partition_search_type != VAR_BASED_PARTITION &&
562 sf->partition_search_type != REFERENCE_PARTITION) {
563 return;
564 } else {
565 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
566 // The thresholds below are not changed locally.
567 if (is_key_frame) {
568 cpi->vbp_threshold_sad = 0;
569 cpi->vbp_bsize_min = BLOCK_8X8;
570 } else {
571 if (cm->width <= 352 && cm->height <= 288)
572 cpi->vbp_threshold_sad = 100;
573 else
574 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
575 ? (cpi->y_dequant[q][1] << 1)
576 : 1000;
577 cpi->vbp_bsize_min = BLOCK_16X16;
578 }
579 cpi->vbp_threshold_minmax = 15 + (q >> 3);
580 }
581}
582
583// Compute the minmax over the 8x8 subblocks.
584static int compute_minmax_8x8(const uint8_t *src, int src_stride,
585 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700586#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587 int highbd,
588#endif
589 int pixels_wide, int pixels_high) {
590 int k;
591 int minmax_max = 0;
592 int minmax_min = 255;
593 // Loop over the 4 8x8 subblocks.
594 for (k = 0; k < 4; k++) {
595 const int x8_idx = ((k & 1) << 3);
596 const int y8_idx = ((k >> 1) << 3);
597 int min = 0;
598 int max = 0;
599 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
600 const int src_offset = y8_idx * src_stride + x8_idx;
601 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700602#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700604 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700605 ref_stride, &min, &max);
606 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700607 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608 ref_stride, &min, &max);
609 }
610#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700611 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612 &min, &max);
613#endif
614 if ((max - min) > minmax_max) minmax_max = (max - min);
615 if ((max - min) < minmax_min) minmax_min = (max - min);
616 }
617 }
618 return (minmax_max - minmax_min);
619}
620
Yaowu Xuf883b422016-08-30 14:01:10 -0700621#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700622static INLINE int avg_4x4(const uint8_t *const src, const int stride,
623 const int highbd) {
624 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700625 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700627 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628 }
629}
630#else
631static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700632 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633}
634#endif
635
Yaowu Xuf883b422016-08-30 14:01:10 -0700636#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700637static INLINE int avg_8x8(const uint8_t *const src, const int stride,
638 const int highbd) {
639 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700640 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700642 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643 }
644}
645#else
646static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700647 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648}
649#endif
650
651static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700652#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653 const int highbd,
654#endif
655 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
656 const int width, const int height,
657 const uint8_t *const src, const int src_stride,
658 const uint8_t *const ref, const int ref_stride) {
659 assert(bsize >= leaf_size);
660
661 vt->bsize = bsize;
662
663 vt->force_split = 0;
664
665 vt->src = src;
666 vt->src_stride = src_stride;
667 vt->ref = ref;
668 vt->ref_stride = ref_stride;
669
670 vt->width = width;
671 vt->height = height;
672
Yaowu Xuf883b422016-08-30 14:01:10 -0700673#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700675#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676
677 if (bsize > leaf_size) {
678 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800679 const int px = block_size_wide[subsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700680
681 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700682#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700684#endif // CONFIG_AOM_HIGHBITDEPTH
685 subsize, leaf_size, AOMMIN(px, width),
686 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700690#endif // CONFIG_AOM_HIGHBITDEPTH
691 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692 src + px, src_stride, ref + px, ref_stride);
693 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700694#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700696#endif // CONFIG_AOM_HIGHBITDEPTH
697 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700698 src + px * src_stride, src_stride, ref + px * ref_stride,
699 ref_stride);
700 init_variance_tree(vt->split[3],
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
Yaowu Xuc27fc142016-08-22 16:08:15 -0700704 subsize, leaf_size, width - px, height - px,
705 src + px * src_stride + px, src_stride,
706 ref + px * ref_stride + px, ref_stride);
707 }
708}
709
710// Fill the variance tree based on averaging pixel values (sub-sampling), at
711// the leaf node size.
712static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
713 if (vt->bsize > leaf_size) {
714 fill_variance_tree(vt->split[0], leaf_size);
715 fill_variance_tree(vt->split[1], leaf_size);
716 fill_variance_tree(vt->split[2], leaf_size);
717 fill_variance_tree(vt->split[3], leaf_size);
718 fill_variance_node(vt);
719 } else if (vt->width <= 0 || vt->height <= 0) {
720 fill_variance(0, 0, 0, &vt->variances.none);
721 } else {
722 unsigned int sse = 0;
723 int sum = 0;
724 int src_avg;
725 int ref_avg;
726 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
727 if (leaf_size == BLOCK_4X4) {
728 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
729 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
730 } else {
731 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
732 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
733 }
734 sum = src_avg - ref_avg;
735 sse = sum * sum;
736 fill_variance(sse, sum, 0, &vt->variances.none);
737 }
738}
739
740static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
741 if (vt->bsize >= BLOCK_8X8) {
742 if (vt->bsize == BLOCK_16X16) {
743 if (vt->variances.none.variance <= threshold)
744 return;
745 else
746 vt->force_split = 0;
747 }
748
749 refine_variance_tree(vt->split[0], threshold);
750 refine_variance_tree(vt->split[1], threshold);
751 refine_variance_tree(vt->split[2], threshold);
752 refine_variance_tree(vt->split[3], threshold);
753
754 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
755 } else if (vt->width <= 0 || vt->height <= 0) {
756 fill_variance(0, 0, 0, &vt->variances.none);
757 } else {
758 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
759 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
760 const int sum = src_avg - ref_avg;
761 const unsigned int sse = sum * sum;
762 assert(vt->bsize == BLOCK_4X4);
763 fill_variance(sse, sum, 0, &vt->variances.none);
764 }
765}
766
767static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
768 if (vt->bsize == BLOCK_32X32) {
769 vt->force_split = vt->variances.none.variance > threshold;
770 } else {
771 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
772 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
773 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
774 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
775 }
776 return vt->force_split;
777}
778
Yaowu Xuf883b422016-08-30 14:01:10 -0700779static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700780 const int segment_id, const int64_t *const thresholds) {
781 if (vt->bsize == BLOCK_16X16) {
782 vt->force_split = vt->variances.none.variance > thresholds[0];
783 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
784 !cyclic_refresh_segment_id_boosted(segment_id)) {
785 // We have some nominal amount of 16x16 variance (based on average),
786 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
787 // force split to 8x8 block for this 16x16 block.
788 int minmax =
789 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700790#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791 vt->highbd,
792#endif
793 vt->width, vt->height);
794 vt->force_split = minmax > cpi->vbp_threshold_minmax;
795 }
796 } else {
797 vt->force_split |=
798 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
799 vt->force_split |=
800 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
801 vt->force_split |=
802 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
803 vt->force_split |=
804 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
805
806 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
807 vt->force_split = vt->variances.none.variance > thresholds[0];
808 }
809 }
810
811 return vt->force_split;
812}
813
814// This function chooses partitioning based on the variance between source and
815// reconstructed last (or golden), where variance is computed for down-sampled
816// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700817static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700818 const TileInfo *const tile, MACROBLOCK *const x,
819 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700820 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700821 MACROBLOCKD *const xd = &x->e_mbd;
822 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700823#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700825#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700826 const uint8_t *src;
827 const uint8_t *ref;
828 int src_stride;
829 int ref_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800830 int pixels_wide = MI_SIZE * mi_size_wide[cm->sb_size];
831 int pixels_high = MI_SIZE * mi_size_high[cm->sb_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700832 int64_t thresholds[5] = {
833 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
834 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
835 };
836 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
837 cpi->vbp_bsize_min, BLOCK_8X8 };
838 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
839 const int64_t *const thre = thresholds + start_level;
840 const BLOCK_SIZE *const bmin = bsize_min + start_level;
841
842 const int is_key_frame = (cm->frame_type == KEY_FRAME);
843 const int low_res = (cm->width <= 352 && cm->height <= 288);
844
845 int segment_id = CR_SEGMENT_ID_BASE;
846
847 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
848 const uint8_t *const map =
849 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
850 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
851
852 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700853 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854 set_vbp_thresholds(cpi, thresholds, q);
855 }
856 }
857
858 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
859
860 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
861 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
862
863 src = x->plane[0].src.buf;
864 src_stride = x->plane[0].src.stride;
865
866 if (!is_key_frame) {
867 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
869 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
870 unsigned int y_sad, y_sad_g;
871
872 const int hbs = cm->mib_size / 2;
873 const int split_vert = mi_col + hbs >= cm->mi_cols;
874 const int split_horz = mi_row + hbs >= cm->mi_rows;
875 BLOCK_SIZE bsize;
876
877 if (split_vert && split_horz)
878 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
879 else if (split_vert)
880 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
881 else if (split_horz)
882 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
883 else
884 bsize = cm->sb_size;
885
886 assert(yv12 != NULL);
887
888 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700889 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
890 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700891 y_sad_g = cpi->fn_ptr[bsize].sdf(
892 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
893 xd->plane[0].pre[0].stride);
894 } else {
895 y_sad_g = UINT_MAX;
896 }
897
Yaowu Xuf883b422016-08-30 14:01:10 -0700898 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
899 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 mbmi->ref_frame[0] = LAST_FRAME;
901 mbmi->ref_frame[1] = NONE;
902 mbmi->sb_type = cm->sb_size;
903 mbmi->mv[0].as_int = 0;
904#if CONFIG_DUAL_FILTER
905 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
906#else
907 mbmi->interp_filter = BILINEAR;
908#endif
909
Yaowu Xuf883b422016-08-30 14:01:10 -0700910 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911
912 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700913 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
914 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 mbmi->ref_frame[0] = GOLDEN_FRAME;
916 mbmi->mv[0].as_int = 0;
917 y_sad = y_sad_g;
918 } else {
919 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
920 }
921
David Barkerac37fa32016-12-02 12:30:21 +0000922 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700923
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924 ref = xd->plane[0].dst.buf;
925 ref_stride = xd->plane[0].dst.stride;
926
927 // If the y_sad is very small, take the largest partition and exit.
928 // Don't check on boosted segment for now, as largest is suppressed there.
929 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
930 if (!split_vert && !split_horz) {
931 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
932 return;
933 }
934 }
935 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700936 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700938#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
940 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700941 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
942 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700944 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 }
946 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700947#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 }
949
950 init_variance_tree(
951 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700952#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700954#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
956 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
957
958 // Fill in the entire tree of variances and compute splits.
959 if (is_key_frame) {
960 fill_variance_tree(vt, BLOCK_4X4);
961 check_split_key_frame(vt, thre[1]);
962 } else {
963 fill_variance_tree(vt, BLOCK_8X8);
964 check_split(cpi, vt, segment_id, thre);
965 if (low_res) {
966 refine_variance_tree(vt, thre[1] << 1);
967 }
968 }
969
970 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
971 mi_row + cm->mib_size > cm->mi_rows;
972
973 // Now go through the entire structure, splitting every block size until
974 // we get to one that's got a variance lower than our threshold.
975 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
976}
977
978#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700979static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 MB_MODE_INFO *mbmi) {
981 int dir;
982 for (dir = 0; dir < 2; ++dir) {
983 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
984 (mbmi->ref_frame[1] == NONE ||
985 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
986 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
987 ? EIGHTTAP_REGULAR
988 : cm->interp_filter;
989 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
990 }
991}
992
993static void update_filter_type_count(FRAME_COUNTS *counts,
994 const MACROBLOCKD *xd,
995 const MB_MODE_INFO *mbmi) {
996 int dir;
997 for (dir = 0; dir < 2; ++dir) {
998 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
999 (mbmi->ref_frame[1] > INTRA_FRAME &&
1000 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001001 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001002 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1003 }
1004 }
1005}
1006#endif
1007#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001008static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001009 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001010 if (mode == ZEROMV) {
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001011 const int num_4x4s = bsize >= BLOCK_8X8
1012 ? num_4x4_blocks_wide_lookup[bsize] *
1013 num_4x4_blocks_high_lookup[bsize]
1014 : 1;
1015 ++cpi->global_motion_used[mbmi->ref_frame[0]][0];
1016 cpi->global_motion_used[mbmi->ref_frame[0]][1] += num_4x4s;
1017 if (has_second_ref(mbmi)) {
1018 ++cpi->global_motion_used[mbmi->ref_frame[1]][0];
1019 cpi->global_motion_used[mbmi->ref_frame[1]][1] += num_4x4s;
1020 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001021 }
1022}
1023#endif // CONFIG_GLOBAL_MOTION
1024
Urvang Joshi52648442016-10-13 17:27:51 -07001025static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1026 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1027 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001028 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001029 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001030 RD_COUNTS *const rdc = &td->rd_counts;
1031 MACROBLOCK *const x = &td->mb;
1032 MACROBLOCKD *const xd = &x->e_mbd;
1033 struct macroblock_plane *const p = x->plane;
1034 struct macroblockd_plane *const pd = xd->plane;
1035 MODE_INFO *mi = &ctx->mic;
1036 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1037 MODE_INFO *mi_addr = xd->mi[0];
1038 const struct segmentation *const seg = &cm->seg;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001039 const int bw = mi_size_wide[mi->mbmi.sb_type];
1040 const int bh = mi_size_high[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001041 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1042 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1044 int w, h;
1045
1046 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001047 const int mi_width = mi_size_wide[bsize];
1048 const int mi_height = mi_size_high[bsize];
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001049 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001050
1051#if CONFIG_REF_MV
1052 int8_t rf_type;
1053#endif
1054
1055#if !CONFIG_SUPERTX
1056 assert(mi->mbmi.sb_type == bsize);
1057#endif
1058
1059 *mi_addr = *mi;
1060 *x->mbmi_ext = ctx->mbmi_ext;
1061
1062#if CONFIG_DUAL_FILTER
1063 reset_intmv_filter_type(cm, xd, mbmi);
1064#endif
1065
1066#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001067 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001068 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1069 (mbmi->sb_type >= BLOCK_8X8 || unify_bsize) && mbmi->mode == NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001070 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1071 int_mv this_mv =
1072 (i == 0)
1073 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1074 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001075 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1076 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001077 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1078 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001079 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001080 }
1081 }
1082#endif
1083
1084 // If segmentation in use
1085 if (seg->enabled) {
1086 // For in frame complexity AQ copy the segment id from the segment map.
1087 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1088 const uint8_t *const map =
1089 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1090 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1091 }
1092 // Else for cyclic refresh mode update the segment map, set the segment id
1093 // and then update the quantizer.
1094 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001095 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1096 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001097 }
1098 }
1099
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001100 for (i = 0; i < MAX_MB_PLANE; ++i) {
1101 p[i].coeff = ctx->coeff[i];
1102 p[i].qcoeff = ctx->qcoeff[i];
1103 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001104#if CONFIG_PVQ
1105 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1106#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001107 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108 }
Urvang Joshib100db72016-10-12 16:28:56 -07001109#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001110 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001111#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001112
1113 // Restore the coding context of the MB to that that was in place
1114 // when the mode was picked for it
1115 for (y = 0; y < mi_height; y++)
1116 for (x_idx = 0; x_idx < mi_width; x_idx++)
1117 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1118 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1119 xd->mi[x_idx + y * mis] = mi_addr;
1120 }
1121
Arild Fuldseth07441162016-08-15 15:07:52 +02001122#if CONFIG_DELTA_Q
1123 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001124 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001125#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001126 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001127 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001128#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001129
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001130 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1132 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1133 }
1134
1135 x->skip = ctx->skip;
1136
1137#if CONFIG_VAR_TX
1138 for (i = 0; i < 1; ++i)
1139 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1140 sizeof(uint8_t) * ctx->num_4x4_blk);
1141#endif
1142
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001143 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001144
1145#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001146 {
1147 unsigned int *const mode_chosen_counts =
1148 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1149 if (frame_is_intra_only(cm)) {
1150 static const int kf_mode_index[] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -07001151 THR_DC /*DC_PRED*/,
1152 THR_V_PRED /*V_PRED*/,
1153 THR_H_PRED /*H_PRED*/,
1154 THR_D45_PRED /*D45_PRED*/,
1155 THR_D135_PRED /*D135_PRED*/,
1156 THR_D117_PRED /*D117_PRED*/,
1157 THR_D153_PRED /*D153_PRED*/,
1158 THR_D207_PRED /*D207_PRED*/,
1159 THR_D63_PRED /*D63_PRED*/,
1160#if CONFIG_ALT_INTRA
1161 THR_SMOOTH, /*SMOOTH_PRED*/
1162#endif // CONFIG_ALT_INTRA
1163 THR_TM /*TM_PRED*/,
Urvang Joshi52648442016-10-13 17:27:51 -07001164 };
1165 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1166 } else {
1167 // Note how often each mode chosen as best
1168 ++mode_chosen_counts[ctx->best_mode_index];
1169 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001170 }
1171#endif
1172 if (!frame_is_intra_only(cm)) {
1173 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001174 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001175#if CONFIG_GLOBAL_MOTION
1176 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001177 // TODO(sarahparker): global motion stats need to be handled per-tile
1178 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001179 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001180 } else {
1181 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1182 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1183 int idx, idy;
1184 for (idy = 0; idy < 2; idy += num_4x4_h) {
1185 for (idx = 0; idx < 2; idx += num_4x4_w) {
1186 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001187 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
James Zernaf322e12016-10-22 12:43:15 -07001188 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001189 }
1190 }
1191 }
1192#endif // CONFIG_GLOBAL_MOTION
1193 if (cm->interp_filter == SWITCHABLE
1194#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001195 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001196#endif
Yue Chen69f18e12016-09-08 14:48:15 -07001197#if CONFIG_WARPED_MOTION
1198 && mbmi->motion_mode != WARPED_CAUSAL
1199#endif // CONFIG_WARPED_MOTION
1200 ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001201#if CONFIG_DUAL_FILTER
1202 update_filter_type_count(td->counts, xd, mbmi);
1203#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001204 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1205 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001206#endif
1207 }
1208 }
1209
1210 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1211 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1212 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1213 }
1214
1215 for (h = 0; h < y_mis; ++h) {
1216 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1217 for (w = 0; w < x_mis; ++w) {
1218 MV_REF *const mv = frame_mv + w;
1219 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1220 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1221 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1222 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1223 }
1224 }
1225}
1226
1227#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001228static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001230 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231 int y, x_idx;
1232#if CONFIG_VAR_TX || CONFIG_REF_MV
1233 int i;
1234#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001235 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001236 RD_COUNTS *const rdc = &td->rd_counts;
1237 MACROBLOCK *const x = &td->mb;
1238 MACROBLOCKD *const xd = &x->e_mbd;
1239 MODE_INFO *mi = &ctx->mic;
1240 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1241 MODE_INFO *mi_addr = xd->mi[0];
1242 const struct segmentation *const seg = &cm->seg;
1243 const int mis = cm->mi_stride;
Jingning Han5b7706a2016-12-21 09:55:10 -08001244 const int mi_width = mi_size_wide[bsize];
1245 const int mi_height = mi_size_high[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001246 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1247 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1249 int w, h;
1250
1251#if CONFIG_REF_MV
1252 int8_t rf_type;
1253#endif
1254
1255 *mi_addr = *mi;
1256 *x->mbmi_ext = ctx->mbmi_ext;
1257 assert(is_inter_block(mbmi));
1258 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1259
1260#if CONFIG_DUAL_FILTER
1261 reset_intmv_filter_type(cm, xd, mbmi);
1262#endif
1263
1264#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001265 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Han38b1bc42016-12-22 15:51:04 -08001266 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1267#if !CONFIG_CB4X4
1268 mbmi->sb_type >= BLOCK_8X8 &&
1269#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001270 mbmi->mode == NEWMV) {
1271 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1272 int_mv this_mv =
1273 (i == 0)
1274 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1275 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001276 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1277 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001278 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1279 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1280 mbmi->pred_mv[i] = this_mv;
1281 }
1282 }
1283#endif
1284
1285 // If segmentation in use
1286 if (seg->enabled) {
1287 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001288 const int energy =
1289 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1290 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001291 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1292 // For cyclic refresh mode, now update the segment map
1293 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001294 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1295 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001296 } else {
1297 // Otherwise just set the segment id based on the current segment map
1298 const uint8_t *const map =
1299 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1300 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1301 }
1302 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1303 }
1304
1305 // Restore the coding context of the MB to that that was in place
1306 // when the mode was picked for it
1307 for (y = 0; y < mi_height; y++)
1308 for (x_idx = 0; x_idx < mi_width; x_idx++)
1309 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1310 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1311 xd->mi[x_idx + y * mis] = mi_addr;
1312 }
1313
Jingning Han38b1bc42016-12-22 15:51:04 -08001314#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001315 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1316 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1317 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1318 }
Jingning Han38b1bc42016-12-22 15:51:04 -08001319#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320
1321 x->skip = ctx->skip;
1322
1323#if CONFIG_VAR_TX
1324 for (i = 0; i < 1; ++i)
1325 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1326 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001327
1328 if (!is_inter_block(mbmi) || mbmi->skip)
1329 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001330#endif // CONFIG_VAR_TX
1331
1332#if CONFIG_VAR_TX
1333 {
1334 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001335 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1336 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001338 mbmi->inter_tx_size[0][0] = mtx;
1339 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1340 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1341 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001342 }
1343#endif // CONFIG_VAR_TX
1344 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001345 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001346
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001347 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348
1349 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001350 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001351
David Barker03bd2102016-11-17 14:55:04 +00001352#if CONFIG_GLOBAL_MOTION
1353 if (is_inter_block(mbmi)) {
1354 if (bsize >= BLOCK_8X8) {
1355 // TODO(sarahparker): global motion stats need to be handled per-tile
1356 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001357 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
David Barker03bd2102016-11-17 14:55:04 +00001358 } else {
1359 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1360 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1361 int idx, idy;
1362 for (idy = 0; idy < 2; idy += num_4x4_h) {
1363 for (idx = 0; idx < 2; idx += num_4x4_w) {
1364 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001365 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
David Barker03bd2102016-11-17 14:55:04 +00001366 (AV1_COMP *)cpi);
1367 }
1368 }
1369 }
1370 }
1371#endif // CONFIG_GLOBAL_MOTION
1372
Yaowu Xuc27fc142016-08-22 16:08:15 -07001373 if (cm->interp_filter == SWITCHABLE
1374#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001375 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001376#endif
1377 ) {
1378#if CONFIG_DUAL_FILTER
1379 update_filter_type_count(td->counts, xd, mbmi);
1380#else
James Zern9ca190c2016-10-22 12:42:43 -07001381 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1382 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383#endif
1384 }
1385
1386 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1387 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1388 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1389 }
1390
1391 for (h = 0; h < y_mis; ++h) {
1392 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1393 for (w = 0; w < x_mis; ++w) {
1394 MV_REF *const mv = frame_mv + w;
1395 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1396 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1397 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1398 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1399 }
1400 }
1401}
1402
Urvang Joshi52648442016-10-13 17:27:51 -07001403static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001404 const TileInfo *const tile, int mi_row,
1405 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001406 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001407 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001408 MACROBLOCK *const x = &td->mb;
1409 MACROBLOCKD *const xd = &x->e_mbd;
1410 struct macroblock_plane *const p = x->plane;
1411 struct macroblockd_plane *const pd = xd->plane;
Jingning Han5b7706a2016-12-21 09:55:10 -08001412 int hbs = mi_size_wide[bsize] / 2;
Jingning Hanfeb517c2016-12-21 16:02:07 -08001413#if CONFIG_CB4X4
1414 const int unify_bsize = 1;
1415#else
1416 const int unify_bsize = 0;
1417#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001418 PARTITION_TYPE partition = pc_tree->partitioning;
1419 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1420 int i;
1421#if CONFIG_EXT_PARTITION_TYPES
1422 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1423#endif
1424 PICK_MODE_CONTEXT *pmc = NULL;
1425
1426 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1427
1428 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001429 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001430
1431 switch (partition) {
1432 case PARTITION_NONE:
1433 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1434 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001435 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436 break;
1437 case PARTITION_VERT:
1438 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1439 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001440 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001441 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001442 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1443 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001444 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001445 }
1446 pmc = &pc_tree->vertical_supertx;
1447 break;
1448 case PARTITION_HORZ:
1449 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1450 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001451 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001452 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001453 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1454 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001455 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456 }
1457 pmc = &pc_tree->horizontal_supertx;
1458 break;
1459 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001460 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1462 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001463 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464 } else {
1465 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001466 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1467 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001468 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1469 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001470 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001471 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1472 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001473 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1475 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001476 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001477 }
1478 pmc = &pc_tree->split_supertx;
1479 break;
1480#if CONFIG_EXT_PARTITION_TYPES
1481 case PARTITION_HORZ_A:
1482 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1483 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001484 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001485 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1486 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001487 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001488 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1489 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001490 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001491 pmc = &pc_tree->horizontala_supertx;
1492 break;
1493 case PARTITION_HORZ_B:
1494 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1495 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001496 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001497 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1498 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001499 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001500 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1501 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001502 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001503 pmc = &pc_tree->horizontalb_supertx;
1504 break;
1505 case PARTITION_VERT_A:
1506 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1507 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001508 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001509 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1510 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001511 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001512 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1513 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001514 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515 pmc = &pc_tree->verticala_supertx;
1516 break;
1517 case PARTITION_VERT_B:
1518 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1519 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001520 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1522 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001523 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001524 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1525 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001526 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001527 pmc = &pc_tree->verticalb_supertx;
1528 break;
1529#endif // CONFIG_EXT_PARTITION_TYPES
1530 default: assert(0);
1531 }
1532
1533 for (i = 0; i < MAX_MB_PLANE; ++i) {
1534 if (pmc != NULL) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001535 p[i].coeff = pmc->coeff[i];
1536 p[i].qcoeff = pmc->qcoeff[i];
1537 pd[i].dqcoeff = pmc->dqcoeff[i];
1538 p[i].eobs = pmc->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001539 } else {
1540 // These should never be used
1541 p[i].coeff = NULL;
1542 p[i].qcoeff = NULL;
1543 pd[i].dqcoeff = NULL;
1544 p[i].eobs = NULL;
1545 }
1546 }
1547}
1548
1549static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1550 int best_tx, TX_SIZE supertx_size) {
1551 MACROBLOCK *const x = &td->mb;
1552#if CONFIG_VAR_TX
1553 int i;
1554
1555 for (i = 0; i < 1; ++i)
1556 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1557 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001558 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001559#endif // CONFIG_VAR_TX
1560 ctx->mic.mbmi.tx_size = supertx_size;
1561 ctx->skip = x->skip;
1562 ctx->mic.mbmi.tx_type = best_tx;
1563}
1564
Urvang Joshi52648442016-10-13 17:27:51 -07001565static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1566 int mi_row, int mi_col, BLOCK_SIZE bsize,
1567 int best_tx, TX_SIZE supertx_size,
1568 PC_TREE *pc_tree) {
1569 const AV1_COMMON *const cm = &cpi->common;
Jingning Han5b7706a2016-12-21 09:55:10 -08001570 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001571 PARTITION_TYPE partition = pc_tree->partitioning;
1572 BLOCK_SIZE subsize = get_subsize(bsize, partition);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001573#if CONFIG_CB4X4
1574 const int unify_bsize = 1;
1575#else
1576 const int unify_bsize = 0;
1577#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001578#if CONFIG_EXT_PARTITION_TYPES
1579 int i;
1580#endif
1581
1582 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1583
1584 switch (partition) {
1585 case PARTITION_NONE:
1586 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1587 break;
1588 case PARTITION_VERT:
1589 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001590 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001591 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1592 break;
1593 case PARTITION_HORZ:
1594 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001595 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001596 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1597 supertx_size);
1598 break;
1599 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001600 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001601 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1602 } else {
1603 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1604 supertx_size, pc_tree->split[0]);
1605 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1606 supertx_size, pc_tree->split[1]);
1607 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1608 supertx_size, pc_tree->split[2]);
1609 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1610 best_tx, supertx_size, pc_tree->split[3]);
1611 }
1612 break;
1613#if CONFIG_EXT_PARTITION_TYPES
1614 case PARTITION_HORZ_A:
1615 for (i = 0; i < 3; i++)
1616 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1617 supertx_size);
1618 break;
1619 case PARTITION_HORZ_B:
1620 for (i = 0; i < 3; i++)
1621 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1622 supertx_size);
1623 break;
1624 case PARTITION_VERT_A:
1625 for (i = 0; i < 3; i++)
1626 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1627 break;
1628 case PARTITION_VERT_B:
1629 for (i = 0; i < 3; i++)
1630 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1631 break;
1632#endif // CONFIG_EXT_PARTITION_TYPES
1633 default: assert(0);
1634 }
1635}
1636#endif // CONFIG_SUPERTX
1637
Yaowu Xuf883b422016-08-30 14:01:10 -07001638void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1639 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001640 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1641 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1642 src->uv_crop_width };
1643 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1644 src->uv_crop_height };
1645 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1646 int i;
1647
1648 // Set current frame pointer.
1649 x->e_mbd.cur_buf = src;
1650
1651 for (i = 0; i < MAX_MB_PLANE; i++)
1652 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1653 strides[i], mi_row, mi_col, NULL,
1654 x->e_mbd.plane[i].subsampling_x,
1655 x->e_mbd.plane[i].subsampling_y);
1656}
1657
Urvang Joshi52648442016-10-13 17:27:51 -07001658static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001659 int8_t segment_id) {
1660 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001661 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001662 av1_init_plane_quantizers(cpi, x, segment_id);
1663 aom_clear_system_state();
1664 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1665 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001666}
1667
Urvang Joshi52648442016-10-13 17:27:51 -07001668static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001669 MACROBLOCK *const x, int mi_row, int mi_col,
1670 RD_COST *rd_cost,
1671#if CONFIG_SUPERTX
1672 int *totalrate_nocoef,
1673#endif
1674#if CONFIG_EXT_PARTITION_TYPES
1675 PARTITION_TYPE partition,
1676#endif
1677 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1678 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001679 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001680 TileInfo *const tile_info = &tile_data->tile_info;
1681 MACROBLOCKD *const xd = &x->e_mbd;
1682 MB_MODE_INFO *mbmi;
1683 struct macroblock_plane *const p = x->plane;
1684 struct macroblockd_plane *const pd = xd->plane;
1685 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1686 int i, orig_rdmult;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001687 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001688
Yaowu Xuf883b422016-08-30 14:01:10 -07001689 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001690
1691 // Use the lower precision, but faster, 32x32 fdct for mode selection.
1692 x->use_lp32x32fdct = 1;
1693
Yushin Cho77bba8d2016-11-04 16:36:56 -07001694#if CONFIG_PVQ
1695 x->pvq_speed = 1;
1696 x->pvq_coded = 0;
1697#endif
1698
Yaowu Xuc27fc142016-08-22 16:08:15 -07001699 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1700 mbmi = &xd->mi[0]->mbmi;
1701 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001702#if CONFIG_RD_DEBUG
1703 mbmi->mi_row = mi_row;
1704 mbmi->mi_col = mi_col;
1705#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001706#if CONFIG_SUPERTX
1707 // We set tx_size here as skip blocks would otherwise not set it.
1708 // tx_size needs to be set at this point as supertx_enable in
1709 // write_modes_sb is computed based on this, and if the garbage in memory
1710 // just happens to be the supertx_size, then the packer will code this
1711 // block as a supertx block, even if rdopt did not pick it as such.
1712 mbmi->tx_size = max_txsize_lookup[bsize];
1713#endif
1714#if CONFIG_EXT_PARTITION_TYPES
1715 mbmi->partition = partition;
1716#endif
1717
1718 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001719 p[i].coeff = ctx->coeff[i];
1720 p[i].qcoeff = ctx->qcoeff[i];
1721 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001722#if CONFIG_PVQ
1723 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1724#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001725 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001726 }
1727
Urvang Joshib100db72016-10-12 16:28:56 -07001728#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001729 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001730#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001731
Yaowu Xuc27fc142016-08-22 16:08:15 -07001732 ctx->skippable = 0;
1733 ctx->pred_pixel_ready = 0;
1734
1735 // Set to zero to make sure we do not use the previous encoded frame stats
1736 mbmi->skip = 0;
1737
Yaowu Xuf883b422016-08-30 14:01:10 -07001738#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001739 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001740 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001741 cpi, &x->plane[0].src, bsize, xd->bd);
1742 } else {
1743 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001744 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001745 }
1746#else
1747 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001748 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1749#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001750
1751 // Save rdmult before it might be changed, so it can be restored later.
1752 orig_rdmult = x->rdmult;
1753
1754 if (aq_mode == VARIANCE_AQ) {
1755 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001756 const int energy =
1757 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1758 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001759 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001760 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001761 }
1762 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1763 } else if (aq_mode == COMPLEXITY_AQ) {
1764 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1765 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1766 // If segment is boosted, use rdmult for that segment.
1767 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001768 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001769 }
1770
1771 // Find best coding mode & reconstruct the MB so it is available
1772 // as a predictor for MBs that follow in the SB
1773 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001774 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775#if CONFIG_SUPERTX
1776 *totalrate_nocoef = 0;
1777#endif // CONFIG_SUPERTX
1778 } else {
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001779 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001781 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1782 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001783#if CONFIG_SUPERTX
1784 *totalrate_nocoef = rd_cost->rate;
1785#endif // CONFIG_SUPERTX
1786 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001787 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001788#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001789 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001790#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001791 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792#if CONFIG_SUPERTX
1793 assert(*totalrate_nocoef >= 0);
1794#endif // CONFIG_SUPERTX
1795 }
1796 } else {
1797 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1798 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1799 rd_cost->rate = INT_MAX;
1800 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001801 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1802 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001803#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001804 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001805#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001806 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001807#if CONFIG_SUPERTX
1808 assert(*totalrate_nocoef >= 0);
1809#endif // CONFIG_SUPERTX
1810 }
1811 }
1812 }
1813
1814 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1815 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1816 (bsize >= BLOCK_16X16) &&
1817 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1818 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001819 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001820 }
1821
1822 x->rdmult = orig_rdmult;
1823
1824 // TODO(jingning) The rate-distortion optimization flow needs to be
1825 // refactored to provide proper exit/return handle.
1826 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1827
1828 ctx->rate = rd_cost->rate;
1829 ctx->dist = rd_cost->dist;
1830}
1831
1832#if CONFIG_REF_MV
1833static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1834#if CONFIG_EXT_INTER
1835 int is_compound,
1836#endif // CONFIG_EXT_INTER
1837 int16_t mode_context) {
1838 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1839#if CONFIG_EXT_INTER
1840 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1841 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1842#else
1843 if (mode == NEWMV) {
1844#endif // CONFIG_EXT_INTER
1845 ++counts->newmv_mode[mode_ctx][0];
1846 return;
1847 } else {
1848 ++counts->newmv_mode[mode_ctx][1];
1849
1850 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1851 return;
1852 }
1853
1854 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1855 if (mode == ZEROMV) {
1856 ++counts->zeromv_mode[mode_ctx][0];
1857 return;
1858 } else {
1859 ++counts->zeromv_mode[mode_ctx][1];
1860 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1861
1862 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1863 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1864 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1865
1866 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1867 }
1868 }
1869}
1870#endif
1871
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001872static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1873 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07001874#if CONFIG_SUPERTX
1875 ,
1876 int supertx_enabled
1877#endif
1878 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01001879#if CONFIG_DELTA_Q
1880 MACROBLOCK *x = &td->mb;
1881 MACROBLOCKD *const xd = &x->e_mbd;
1882#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 const MACROBLOCK *x = &td->mb;
1884 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01001885#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001886 const MODE_INFO *const mi = xd->mi[0];
1887 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1888 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1889 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001890 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891
Thomas Daviesf6936102016-09-05 16:51:31 +01001892#if CONFIG_DELTA_Q
1893 // delta quant applies to both intra and inter
1894 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
1895
1896 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
1897 super_block_upper_left) {
1898 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1899 const int absdq = abs(dq);
1900 int i;
1901 for (i = 0; i < absdq; ++i) {
1902 td->counts->delta_q[i][1]++;
1903 }
1904 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1905 xd->prev_qindex = mbmi->current_q_index;
1906 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001907#else
1908 (void)mi_row;
1909 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01001910#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001911 if (!frame_is_intra_only(cm)) {
1912 FRAME_COUNTS *const counts = td->counts;
1913 const int inter_block = is_inter_block(mbmi);
1914 const int seg_ref_active =
1915 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1916 if (!seg_ref_active) {
1917#if CONFIG_SUPERTX
1918 if (!supertx_enabled)
1919#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001920 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921 // If the segment reference feature is enabled we have only a single
1922 // reference frame allowed for the segment so exclude it from
1923 // the reference frame counts used to work out probabilities.
1924 if (inter_block) {
1925 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1926#if CONFIG_EXT_REFS
1927 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1928#endif // CONFIG_EXT_REFS
1929
1930 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07001931 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1932 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001933
1934 if (has_second_ref(mbmi)) {
1935#if CONFIG_EXT_REFS
1936 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1937
Yaowu Xuf883b422016-08-30 14:01:10 -07001938 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001939 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07001940 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1941 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001942 } else {
clang-format67948d32016-09-07 22:40:40 -07001943 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1944 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001945 }
1946
clang-format67948d32016-09-07 22:40:40 -07001947 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1948 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949#else
clang-format67948d32016-09-07 22:40:40 -07001950 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1951 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001952#endif // CONFIG_EXT_REFS
1953 } else {
1954#if CONFIG_EXT_REFS
1955 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
1956
Yaowu Xuf883b422016-08-30 14:01:10 -07001957 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001958 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07001959 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1960 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001961 } else {
1962 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001963 counts->single_ref[av1_get_pred_context_single_ref_p3(xd)][2]
1964 [bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001965 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001966 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1967 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001968 } else {
clang-format67948d32016-09-07 22:40:40 -07001969 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1970 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 }
1972 }
1973#else
clang-format67948d32016-09-07 22:40:40 -07001974 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1975 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07001977 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1978 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001979 }
1980#endif // CONFIG_EXT_REFS
1981 }
1982
1983#if CONFIG_EXT_INTER
1984 if (cm->reference_mode != COMPOUND_REFERENCE &&
1985#if CONFIG_SUPERTX
1986 !supertx_enabled &&
1987#endif
1988 is_interintra_allowed(mbmi)) {
1989 const int bsize_group = size_group_lookup[bsize];
1990 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1991 counts->interintra[bsize_group][1]++;
1992 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1993 if (is_interintra_wedge_used(bsize))
1994 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1995 } else {
1996 counts->interintra[bsize_group][0]++;
1997 }
1998 }
1999#endif // CONFIG_EXT_INTER
2000
Yue Chencb60b182016-10-13 15:18:22 -07002001#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002#if CONFIG_SUPERTX
2003 if (!supertx_enabled)
2004#endif // CONFIG_SUPERTX
2005#if CONFIG_EXT_INTER
2006 if (mbmi->ref_frame[1] != INTRA_FRAME)
2007#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07002008#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
2009 {
2010 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -07002011 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
Yue Chen69f18e12016-09-08 14:48:15 -07002012 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
2013 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
2014 }
2015#else
2016 if (motion_mode_allowed(mbmi) > SIMPLE_TRANSLATION)
2017 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
2018#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07002019#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002020
2021#if CONFIG_EXT_INTER
2022 if (cm->reference_mode != SINGLE_REFERENCE &&
Sarah Parker6fdc8532016-11-16 17:47:13 -08002023 is_inter_compound_mode(mbmi->mode)
Yue Chencb60b182016-10-13 15:18:22 -07002024#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002025 && mbmi->motion_mode == SIMPLE_TRANSLATION
Yue Chencb60b182016-10-13 15:18:22 -07002026#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002027 ) {
2028 counts->compound_interinter[bsize]
2029 [mbmi->interinter_compound_data.type]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002030 }
2031#endif // CONFIG_EXT_INTER
2032 }
2033 }
2034
2035 if (inter_block &&
2036 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08002037 int16_t mode_ctx;
2038#if !CONFIG_REF_MV
2039 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
2040#endif
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002041 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002042 const PREDICTION_MODE mode = mbmi->mode;
2043#if CONFIG_REF_MV
2044#if CONFIG_EXT_INTER
2045 if (has_second_ref(mbmi)) {
2046 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
2047 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2048 } else {
2049#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002050 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2051 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052 update_inter_mode_stats(counts, mode,
2053#if CONFIG_EXT_INTER
2054 has_second_ref(mbmi),
2055#endif // CONFIG_EXT_INTER
2056 mode_ctx);
2057
2058 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002059 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002060 int idx;
2061
2062 for (idx = 0; idx < 2; ++idx) {
2063 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2064 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002065 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002066 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
2067
2068 if (mbmi->ref_mv_idx == idx) break;
2069 }
2070 }
2071 }
2072
2073 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002074 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002075 int idx;
2076
2077 for (idx = 1; idx < 3; ++idx) {
2078 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2079 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002080 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002081 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2082
2083 if (mbmi->ref_mv_idx == idx - 1) break;
2084 }
2085 }
2086 }
2087#if CONFIG_EXT_INTER
2088 }
2089#endif // CONFIG_EXT_INTER
2090#else
2091#if CONFIG_EXT_INTER
2092 if (is_inter_compound_mode(mode))
2093 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2094 else
2095#endif // CONFIG_EXT_INTER
2096 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2097#endif
2098 } else {
2099 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2100 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2101 int idx, idy;
2102 for (idy = 0; idy < 2; idy += num_4x4_h) {
2103 for (idx = 0; idx < 2; idx += num_4x4_w) {
2104 const int j = idy * 2 + idx;
2105 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2106#if CONFIG_REF_MV
2107#if CONFIG_EXT_INTER
2108 if (has_second_ref(mbmi)) {
2109 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002110 ++counts->inter_compound_mode[mode_ctx]
2111 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002112 } else {
2113#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002114 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2115 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002116 update_inter_mode_stats(counts, b_mode,
2117#if CONFIG_EXT_INTER
2118 has_second_ref(mbmi),
2119#endif // CONFIG_EXT_INTER
2120 mode_ctx);
2121#if CONFIG_EXT_INTER
2122 }
2123#endif // CONFIG_EXT_INTER
2124#else
2125#if CONFIG_EXT_INTER
2126 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002127 ++counts->inter_compound_mode[mode_ctx]
2128 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002129 else
2130#endif // CONFIG_EXT_INTER
2131 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2132#endif
2133 }
2134 }
2135 }
2136 }
2137 }
2138}
2139
2140typedef struct {
2141 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2142 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2143 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2144 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2145#if CONFIG_VAR_TX
2146 TXFM_CONTEXT *p_ta;
2147 TXFM_CONTEXT *p_tl;
2148 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2149 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2150#endif
2151} RD_SEARCH_MACROBLOCK_CONTEXT;
2152
2153static void restore_context(MACROBLOCK *x,
2154 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002155 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002156#if CONFIG_PVQ
2157 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002158#endif
2159 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002160 MACROBLOCKD *xd = &x->e_mbd;
2161 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002162 const int num_4x4_blocks_wide =
2163 block_size_wide[bsize] >> tx_size_wide_log2[0];
2164 const int num_4x4_blocks_high =
2165 block_size_high[bsize] >> tx_size_high_log2[0];
2166 int mi_width = mi_size_wide[bsize];
2167 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002168 for (p = 0; p < MAX_MB_PLANE; p++) {
2169 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2170 ctx->a + num_4x4_blocks_wide * p,
2171 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2172 xd->plane[p].subsampling_x);
2173 memcpy(xd->left_context[p] +
2174 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2175 ctx->l + num_4x4_blocks_high * p,
2176 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2177 xd->plane[p].subsampling_y);
2178 }
2179 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2180 sizeof(*xd->above_seg_context) * mi_width);
2181 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2182 sizeof(xd->left_seg_context[0]) * mi_height);
2183#if CONFIG_VAR_TX
2184 xd->above_txfm_context = ctx->p_ta;
2185 xd->left_txfm_context = ctx->p_tl;
2186 memcpy(xd->above_txfm_context, ctx->ta,
2187 sizeof(*xd->above_txfm_context) * mi_width);
2188 memcpy(xd->left_txfm_context, ctx->tl,
2189 sizeof(*xd->left_txfm_context) * mi_height);
2190#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002191#if CONFIG_PVQ
2192 od_encode_rollback(&x->daala_enc, rdo_buf);
2193#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002194}
2195
2196static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002197 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002198#if CONFIG_PVQ
2199 od_rollback_buffer *rdo_buf,
2200#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002201 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002202 const MACROBLOCKD *xd = &x->e_mbd;
2203 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002204 const int num_4x4_blocks_wide =
2205 block_size_wide[bsize] >> tx_size_wide_log2[0];
2206 const int num_4x4_blocks_high =
2207 block_size_high[bsize] >> tx_size_high_log2[0];
2208 int mi_width = mi_size_wide[bsize];
2209 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002210
2211 // buffer the above/left context information of the block in search.
2212 for (p = 0; p < MAX_MB_PLANE; ++p) {
2213 memcpy(ctx->a + num_4x4_blocks_wide * p,
2214 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2215 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2216 xd->plane[p].subsampling_x);
2217 memcpy(ctx->l + num_4x4_blocks_high * p,
2218 xd->left_context[p] +
2219 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2220 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2221 xd->plane[p].subsampling_y);
2222 }
2223 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2224 sizeof(*xd->above_seg_context) * mi_width);
2225 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2226 sizeof(xd->left_seg_context[0]) * mi_height);
2227#if CONFIG_VAR_TX
2228 memcpy(ctx->ta, xd->above_txfm_context,
2229 sizeof(*xd->above_txfm_context) * mi_width);
2230 memcpy(ctx->tl, xd->left_txfm_context,
2231 sizeof(*xd->left_txfm_context) * mi_height);
2232 ctx->p_ta = xd->above_txfm_context;
2233 ctx->p_tl = xd->left_txfm_context;
2234#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002235#if CONFIG_PVQ
2236 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2237#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238}
2239
Urvang Joshi52648442016-10-13 17:27:51 -07002240static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2241 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2242 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002243#if CONFIG_EXT_PARTITION_TYPES
2244 PARTITION_TYPE partition,
2245#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002246 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002247 MACROBLOCK *const x = &td->mb;
2248 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2249#if CONFIG_EXT_PARTITION_TYPES
2250 x->e_mbd.mi[0]->mbmi.partition = partition;
2251#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002252 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2253 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002254
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002255 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002257 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002258#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002259 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002260#endif
2261 }
2262}
2263
Urvang Joshi52648442016-10-13 17:27:51 -07002264static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2265 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2266 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2267 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002268 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002269 MACROBLOCK *const x = &td->mb;
2270 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002271 const int is_partition_root = bsize >= BLOCK_8X8;
2272 const int ctx = is_partition_root
2273 ? partition_plane_context(xd, mi_row, mi_col, bsize)
2274 : 0;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002275 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002276 const PARTITION_TYPE partition = pc_tree->partitioning;
2277 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2278#if CONFIG_EXT_PARTITION_TYPES
2279 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2280#endif
2281
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002282#if CONFIG_CB4X4
2283 const int unify_bsize = 1;
2284#else
2285 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002286 assert(bsize >= BLOCK_8X8);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002287#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288
2289 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2290
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002291 if (!dry_run && is_partition_root) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292
2293#if CONFIG_SUPERTX
2294 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2295 partition != PARTITION_NONE && !xd->lossless[0]) {
2296 int supertx_enabled;
2297 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2298 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2299 if (supertx_enabled) {
Jingning Han5b7706a2016-12-21 09:55:10 -08002300 const int mi_width = mi_size_wide[bsize];
2301 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002302 int x_idx, y_idx, i;
2303 uint8_t *dst_buf[3];
2304 int dst_stride[3];
2305 set_skip_context(xd, mi_row, mi_col);
2306 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002307 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2308 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002309
Yaowu Xuf883b422016-08-30 14:01:10 -07002310 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002311 for (i = 0; i < MAX_MB_PLANE; i++) {
2312 dst_buf[i] = xd->plane[i].dst.buf;
2313 dst_stride[i] = xd->plane[i].dst.stride;
2314 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002315 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2316 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002317
2318 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2319 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2320
2321 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002322 int this_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2324
Angie Chiangff6d8902016-10-21 11:02:09 -07002325 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002326 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2327 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002328 } else {
2329 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002330 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331 reset_skip_context(xd, bsize);
2332 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002333 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002334 for (y_idx = 0; y_idx < mi_height; y_idx++)
2335 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2336 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2337 x_idx &&
2338 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2339 y_idx) {
2340 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2341 xd->mi[0]->mbmi.skip;
2342 }
2343 }
2344 td->counts->supertx[partition_supertx_context_lookup[partition]]
2345 [supertx_size][1]++;
2346 td->counts->supertx_size[supertx_size]++;
2347#if CONFIG_EXT_TX
2348 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2349 !xd->mi[0]->mbmi.skip) {
2350 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2351 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002352 ++td->counts->inter_ext_tx[eset][supertx_size]
2353 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002354 }
2355 }
2356#else
2357 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2358 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2359 }
2360#endif // CONFIG_EXT_TX
2361 }
2362#if CONFIG_EXT_PARTITION_TYPES
2363 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2364 partition);
2365#else
2366 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2367 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2368#endif
2369#if CONFIG_VAR_TX
Yaowu Xu52a17632016-11-17 15:48:21 -08002370 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2371 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002372#endif // CONFIG_VAR_TX
2373 return;
2374 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002375 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002376 td->counts->supertx[partition_supertx_context_lookup[partition]]
2377 [supertx_size][0]++;
2378 }
2379 }
2380 }
2381#endif // CONFIG_SUPERTX
2382
2383 switch (partition) {
2384 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002385 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002386#if CONFIG_EXT_PARTITION_TYPES
2387 partition,
2388#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002389 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002390 break;
2391 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002392 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002393#if CONFIG_EXT_PARTITION_TYPES
2394 partition,
2395#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002396 &pc_tree->vertical[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002397 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002398 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002399#if CONFIG_EXT_PARTITION_TYPES
2400 partition,
2401#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002402 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002403 }
2404 break;
2405 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002406 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002407#if CONFIG_EXT_PARTITION_TYPES
2408 partition,
2409#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002410 &pc_tree->horizontal[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002411 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002412 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413#if CONFIG_EXT_PARTITION_TYPES
2414 partition,
2415#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002416 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417 }
2418 break;
2419 case PARTITION_SPLIT:
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002420 if (bsize == BLOCK_8X8 && !unify_bsize) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002421 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002422#if CONFIG_EXT_PARTITION_TYPES
2423 partition,
2424#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002425 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002426 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002427 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2428 pc_tree->split[0], rate);
2429 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2430 pc_tree->split[1], rate);
2431 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2432 pc_tree->split[2], rate);
2433 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2434 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435 }
2436 break;
2437#if CONFIG_EXT_PARTITION_TYPES
2438 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002439 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2440 &pc_tree->horizontala[0], rate);
2441 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2442 partition, &pc_tree->horizontala[1], rate);
2443 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2444 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002445 break;
2446 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002447 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2448 &pc_tree->horizontalb[0], rate);
2449 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2450 partition, &pc_tree->horizontalb[1], rate);
2451 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2452 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002453 break;
2454 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002455 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2456 &pc_tree->verticala[0], rate);
2457 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2458 partition, &pc_tree->verticala[1], rate);
2459 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2460 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002461
2462 break;
2463 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002464 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2465 &pc_tree->verticalb[0], rate);
2466 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2467 partition, &pc_tree->verticalb[1], rate);
2468 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2469 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002470 break;
2471#endif // CONFIG_EXT_PARTITION_TYPES
2472 default: assert(0 && "Invalid partition type."); break;
2473 }
2474
2475#if CONFIG_EXT_PARTITION_TYPES
2476 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2477#else
2478 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2479 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2480#endif // CONFIG_EXT_PARTITION_TYPES
2481}
2482
2483// Check to see if the given partition size is allowed for a specified number
2484// of mi block rows and columns remaining in the image.
2485// If not then return the largest allowed partition size
2486static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2487 int cols_left, int *bh, int *bw) {
2488 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002489 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002490 } else {
2491 for (; bsize > 0; bsize -= 3) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08002492 *bh = mi_size_high[bsize];
2493 *bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2495 break;
2496 }
2497 }
2498 }
2499 return bsize;
2500}
2501
Yaowu Xuf883b422016-08-30 14:01:10 -07002502static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002503 int bh_in, int bw_in,
2504 int mi_rows_remaining,
2505 int mi_cols_remaining, BLOCK_SIZE bsize,
2506 MODE_INFO **mib) {
2507 int bh = bh_in;
2508 int r, c;
2509 for (r = 0; r < cm->mib_size; r += bh) {
2510 int bw = bw_in;
2511 for (c = 0; c < cm->mib_size; c += bw) {
2512 const int index = r * cm->mi_stride + c;
2513 mib[index] = mi + index;
2514 mib[index]->mbmi.sb_type = find_partition_size(
2515 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2516 }
2517 }
2518}
2519
2520// This function attempts to set all mode info entries in a given superblock
2521// to the same block partition size.
2522// However, at the bottom and right borders of the image the requested size
2523// may not be allowed in which case this code attempts to choose the largest
2524// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002525static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002526 MODE_INFO **mib, int mi_row, int mi_col,
2527 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002528 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2530 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2531 int block_row, block_col;
2532 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002533 int bh = mi_size_high[bsize];
2534 int bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002535
2536 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2537
2538 // Apply the requested partition size to the SB if it is all "in image"
2539 if ((mi_cols_remaining >= cm->mib_size) &&
2540 (mi_rows_remaining >= cm->mib_size)) {
2541 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2542 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2543 int index = block_row * cm->mi_stride + block_col;
2544 mib[index] = mi_upper_left + index;
2545 mib[index]->mbmi.sb_type = bsize;
2546 }
2547 }
2548 } else {
2549 // Else this is a partial SB.
2550 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2551 mi_cols_remaining, bsize, mib);
2552 }
2553}
2554
Yaowu Xuf883b422016-08-30 14:01:10 -07002555static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556 TileDataEnc *tile_data, MODE_INFO **mib,
2557 TOKENEXTRA **tp, int mi_row, int mi_col,
2558 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2559#if CONFIG_SUPERTX
2560 int *rate_nocoef,
2561#endif
2562 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002563 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002564 TileInfo *const tile_info = &tile_data->tile_info;
2565 MACROBLOCK *const x = &td->mb;
2566 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002567 const int bs = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002568 const int hbs = bs / 2;
2569 int i;
2570 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2571 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2572 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2573 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2574 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2575 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2576 int splits_below = 0;
2577 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2578 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002579 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580#if CONFIG_SUPERTX
2581 int last_part_rate_nocoef = INT_MAX;
2582 int none_rate_nocoef = INT_MAX;
2583 int chosen_rate_nocoef = INT_MAX;
2584#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002585#if CONFIG_PVQ
2586 od_rollback_buffer pre_rdo_buf;
2587#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2589
2590 assert(num_4x4_blocks_wide_lookup[bsize] ==
2591 num_4x4_blocks_high_lookup[bsize]);
2592
Yaowu Xuf883b422016-08-30 14:01:10 -07002593 av1_rd_cost_reset(&last_part_rdc);
2594 av1_rd_cost_reset(&none_rdc);
2595 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002596
2597 pc_tree->partitioning = partition;
2598
2599#if CONFIG_VAR_TX
2600 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2601 xd->left_txfm_context =
2602 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2603#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002604#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002605 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002606#else
2607 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2608#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002609
2610 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2611 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002612 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002613 }
2614
2615 if (do_partition_search &&
2616 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2617 cpi->sf.adjust_partitioning_from_last_frame) {
2618 // Check if any of the sub blocks are further split.
2619 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2620 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2621 splits_below = 1;
2622 for (i = 0; i < 4; i++) {
2623 int jj = i >> 1, ii = i & 0x01;
2624 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2625 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2626 splits_below = 0;
2627 }
2628 }
2629 }
2630
2631 // If partition is not none try none unless each of the 4 splits are split
2632 // even further..
2633 if (partition != PARTITION_NONE && !splits_below &&
2634 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2635 pc_tree->partitioning = PARTITION_NONE;
2636 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2637#if CONFIG_SUPERTX
2638 &none_rate_nocoef,
2639#endif
2640#if CONFIG_EXT_PARTITION_TYPES
2641 PARTITION_NONE,
2642#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002643 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002644
2645 if (none_rdc.rate < INT_MAX) {
2646 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2647 none_rdc.rdcost =
2648 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2649#if CONFIG_SUPERTX
2650 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2651#endif
2652 }
2653
Yushin Cho77bba8d2016-11-04 16:36:56 -07002654#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002655 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002656#else
2657 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2658#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002659 mib[0]->mbmi.sb_type = bs_type;
2660 pc_tree->partitioning = partition;
2661 }
2662 }
2663
2664 switch (partition) {
2665 case PARTITION_NONE:
2666 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2667#if CONFIG_SUPERTX
2668 &last_part_rate_nocoef,
2669#endif
2670#if CONFIG_EXT_PARTITION_TYPES
2671 PARTITION_NONE,
2672#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002673 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002674 break;
2675 case PARTITION_HORZ:
2676 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2677#if CONFIG_SUPERTX
2678 &last_part_rate_nocoef,
2679#endif
2680#if CONFIG_EXT_PARTITION_TYPES
2681 PARTITION_HORZ,
2682#endif
2683 subsize, &pc_tree->horizontal[0], INT64_MAX);
2684 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2685 mi_row + hbs < cm->mi_rows) {
2686 RD_COST tmp_rdc;
2687#if CONFIG_SUPERTX
2688 int rt_nocoef = 0;
2689#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002690 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002691 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002692 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002693 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002694 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002695 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2696#if CONFIG_SUPERTX
2697 &rt_nocoef,
2698#endif
2699#if CONFIG_EXT_PARTITION_TYPES
2700 PARTITION_HORZ,
2701#endif
2702 subsize, &pc_tree->horizontal[1], INT64_MAX);
2703 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002704 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002705#if CONFIG_SUPERTX
2706 last_part_rate_nocoef = INT_MAX;
2707#endif
2708 break;
2709 }
2710 last_part_rdc.rate += tmp_rdc.rate;
2711 last_part_rdc.dist += tmp_rdc.dist;
2712 last_part_rdc.rdcost += tmp_rdc.rdcost;
2713#if CONFIG_SUPERTX
2714 last_part_rate_nocoef += rt_nocoef;
2715#endif
2716 }
2717 break;
2718 case PARTITION_VERT:
2719 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2720#if CONFIG_SUPERTX
2721 &last_part_rate_nocoef,
2722#endif
2723#if CONFIG_EXT_PARTITION_TYPES
2724 PARTITION_VERT,
2725#endif
2726 subsize, &pc_tree->vertical[0], INT64_MAX);
2727 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2728 mi_col + hbs < cm->mi_cols) {
2729 RD_COST tmp_rdc;
2730#if CONFIG_SUPERTX
2731 int rt_nocoef = 0;
2732#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002733 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002734 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002735 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002736 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002737 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002738 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2739#if CONFIG_SUPERTX
2740 &rt_nocoef,
2741#endif
2742#if CONFIG_EXT_PARTITION_TYPES
2743 PARTITION_VERT,
2744#endif
2745 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2746 INT64_MAX);
2747 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002748 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002749#if CONFIG_SUPERTX
2750 last_part_rate_nocoef = INT_MAX;
2751#endif
2752 break;
2753 }
2754 last_part_rdc.rate += tmp_rdc.rate;
2755 last_part_rdc.dist += tmp_rdc.dist;
2756 last_part_rdc.rdcost += tmp_rdc.rdcost;
2757#if CONFIG_SUPERTX
2758 last_part_rate_nocoef += rt_nocoef;
2759#endif
2760 }
2761 break;
2762 case PARTITION_SPLIT:
2763 if (bsize == BLOCK_8X8) {
2764 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2765#if CONFIG_SUPERTX
2766 &last_part_rate_nocoef,
2767#endif
2768#if CONFIG_EXT_PARTITION_TYPES
2769 PARTITION_SPLIT,
2770#endif
2771 subsize, pc_tree->leaf_split[0], INT64_MAX);
2772 break;
2773 }
2774 last_part_rdc.rate = 0;
2775 last_part_rdc.dist = 0;
2776 last_part_rdc.rdcost = 0;
2777#if CONFIG_SUPERTX
2778 last_part_rate_nocoef = 0;
2779#endif
2780 for (i = 0; i < 4; i++) {
2781 int x_idx = (i & 1) * hbs;
2782 int y_idx = (i >> 1) * hbs;
2783 int jj = i >> 1, ii = i & 0x01;
2784 RD_COST tmp_rdc;
2785#if CONFIG_SUPERTX
2786 int rt_nocoef;
2787#endif
2788 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2789 continue;
2790
Yaowu Xuf883b422016-08-30 14:01:10 -07002791 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002792 rd_use_partition(cpi, td, tile_data,
2793 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2794 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2795 &tmp_rdc.dist,
2796#if CONFIG_SUPERTX
2797 &rt_nocoef,
2798#endif
2799 i != 3, pc_tree->split[i]);
2800 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002801 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002802#if CONFIG_SUPERTX
2803 last_part_rate_nocoef = INT_MAX;
2804#endif
2805 break;
2806 }
2807 last_part_rdc.rate += tmp_rdc.rate;
2808 last_part_rdc.dist += tmp_rdc.dist;
2809#if CONFIG_SUPERTX
2810 last_part_rate_nocoef += rt_nocoef;
2811#endif
2812 }
2813 break;
2814#if CONFIG_EXT_PARTITION_TYPES
2815 case PARTITION_VERT_A:
2816 case PARTITION_VERT_B:
2817 case PARTITION_HORZ_A:
2818 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2819#endif // CONFIG_EXT_PARTITION_TYPES
2820 default: assert(0); break;
2821 }
2822
2823 if (last_part_rdc.rate < INT_MAX) {
2824 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2825 last_part_rdc.rdcost =
2826 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2827#if CONFIG_SUPERTX
2828 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2829#endif
2830 }
2831
2832 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2833 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2834 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2835 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2836 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2837 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2838 chosen_rdc.rate = 0;
2839 chosen_rdc.dist = 0;
2840#if CONFIG_SUPERTX
2841 chosen_rate_nocoef = 0;
2842#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002843#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002845#else
2846 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2847#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002848 pc_tree->partitioning = PARTITION_SPLIT;
2849
2850 // Split partition.
2851 for (i = 0; i < 4; i++) {
2852 int x_idx = (i & 1) * hbs;
2853 int y_idx = (i >> 1) * hbs;
2854 RD_COST tmp_rdc;
2855#if CONFIG_SUPERTX
2856 int rt_nocoef = 0;
2857#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002858#if CONFIG_PVQ
2859 od_rollback_buffer buf;
2860#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2862 continue;
2863
Yushin Cho77bba8d2016-11-04 16:36:56 -07002864#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002865 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002866#else
2867 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2868#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002869 pc_tree->split[i]->partitioning = PARTITION_NONE;
2870 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2871 &tmp_rdc,
2872#if CONFIG_SUPERTX
2873 &rt_nocoef,
2874#endif
2875#if CONFIG_EXT_PARTITION_TYPES
2876 PARTITION_SPLIT,
2877#endif
2878 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2879
Yushin Cho77bba8d2016-11-04 16:36:56 -07002880#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002881 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002882#else
2883 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2884#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002885 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002886 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002887#if CONFIG_SUPERTX
2888 chosen_rate_nocoef = INT_MAX;
2889#endif
2890 break;
2891 }
2892
2893 chosen_rdc.rate += tmp_rdc.rate;
2894 chosen_rdc.dist += tmp_rdc.dist;
2895#if CONFIG_SUPERTX
2896 chosen_rate_nocoef += rt_nocoef;
2897#endif
2898
2899 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002900 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2901 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002902
2903 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2904#if CONFIG_SUPERTX
2905 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2906#endif
2907 }
2908 if (chosen_rdc.rate < INT_MAX) {
2909 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2910 chosen_rdc.rdcost =
2911 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2912#if CONFIG_SUPERTX
2913 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2914#endif
2915 }
2916 }
2917
2918 // If last_part is better set the partitioning to that.
2919 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2920 mib[0]->mbmi.sb_type = bsize;
2921 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2922 chosen_rdc = last_part_rdc;
2923#if CONFIG_SUPERTX
2924 chosen_rate_nocoef = last_part_rate_nocoef;
2925#endif
2926 }
2927 // If none was better set the partitioning to that.
2928 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2929 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2930 chosen_rdc = none_rdc;
2931#if CONFIG_SUPERTX
2932 chosen_rate_nocoef = none_rate_nocoef;
2933#endif
2934 }
2935
Yushin Cho77bba8d2016-11-04 16:36:56 -07002936#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002937 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002938#else
2939 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2940#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002941
2942 // We must have chosen a partitioning and encoding or we'll fail later on.
2943 // No other opportunities for success.
2944 if (bsize == cm->sb_size)
2945 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2946
2947 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002948 if (bsize == cm->sb_size) {
2949 // NOTE: To get estimate for rate due to the tokens, use:
2950 // int rate_coeffs = 0;
2951 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2952 // bsize, pc_tree, &rate_coeffs);
2953 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2954 pc_tree, NULL);
2955 } else {
2956 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2957 pc_tree, NULL);
2958 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002959 }
2960
2961 *rate = chosen_rdc.rate;
2962 *dist = chosen_rdc.dist;
2963#if CONFIG_SUPERTX
2964 *rate_nocoef = chosen_rate_nocoef;
2965#endif
2966}
2967
2968/* clang-format off */
2969static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002970#if CONFIG_CB4X4
2971 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
2972#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002973 BLOCK_4X4, // 4x4
2974 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2975 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2976 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2977 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2978#if CONFIG_EXT_PARTITION
2979 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2980#endif // CONFIG_EXT_PARTITION
2981};
2982
2983static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002984#if CONFIG_CB4X4
2985 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 2x2, 2x4, 4x2
2986#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987 BLOCK_8X8, // 4x4
2988 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2989 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2990 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2991 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2992#if CONFIG_EXT_PARTITION
2993 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2994#endif // CONFIG_EXT_PARTITION
2995};
2996
2997// Next square block size less or equal than current block size.
2998static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08002999#if CONFIG_CB4X4
3000 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3001#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003002 BLOCK_4X4, // 4x4
3003 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
3004 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
3005 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
3006 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
3007#if CONFIG_EXT_PARTITION
3008 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
3009#endif // CONFIG_EXT_PARTITION
3010};
3011/* clang-format on */
3012
3013// Look at all the mode_info entries for blocks that are part of this
3014// partition and find the min and max values for sb_type.
3015// At the moment this is designed to work on a superblock but could be
3016// adjusted to use a size parameter.
3017//
3018// The min and max are assumed to have been initialized prior to calling this
3019// function so repeat calls can accumulate a min and max of more than one
3020// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07003021static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 MACROBLOCKD *xd, MODE_INFO **mib,
3023 BLOCK_SIZE *min_block_size,
3024 BLOCK_SIZE *max_block_size) {
3025 int i, j;
3026 int index = 0;
3027
3028 // Check the sb_type for each block that belongs to this region.
3029 for (i = 0; i < cm->mib_size; ++i) {
3030 for (j = 0; j < cm->mib_size; ++j) {
3031 MODE_INFO *mi = mib[index + j];
3032 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07003033 *min_block_size = AOMMIN(*min_block_size, sb_type);
3034 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003035 }
3036 index += xd->mi_stride;
3037 }
3038}
3039
3040// Look at neighboring blocks and set a min and max partition size based on
3041// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07003042static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003043 MACROBLOCKD *const xd, int mi_row,
3044 int mi_col, BLOCK_SIZE *min_block_size,
3045 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003046 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003047 MODE_INFO **mi = xd->mi;
3048 const int left_in_image = xd->left_available && mi[-1];
3049 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3050 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3051 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3052 int bh, bw;
3053 BLOCK_SIZE min_size = BLOCK_4X4;
3054 BLOCK_SIZE max_size = BLOCK_LARGEST;
3055
3056 // Trap case where we do not have a prediction.
3057 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3058 // Default "min to max" and "max to min"
3059 min_size = BLOCK_LARGEST;
3060 max_size = BLOCK_4X4;
3061
3062 // NOTE: each call to get_sb_partition_size_range() uses the previous
3063 // passed in values for min and max as a starting point.
3064 // Find the min and max partition used in previous frame at this location
3065 if (cm->frame_type != KEY_FRAME) {
3066 MODE_INFO **prev_mi =
3067 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3068 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3069 }
3070 // Find the min and max partition sizes used in the left superblock
3071 if (left_in_image) {
3072 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3073 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3074 }
3075 // Find the min and max partition sizes used in the above suprblock.
3076 if (above_in_image) {
3077 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3078 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3079 }
3080
3081 // Adjust observed min and max for "relaxed" auto partition case.
3082 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3083 min_size = min_partition_size[min_size];
3084 max_size = max_partition_size[max_size];
3085 }
3086 }
3087
3088 // Check border cases where max and min from neighbors may not be legal.
3089 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3090 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07003091 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092
3093 // Test for blocks at the edge of the active image.
3094 // This may be the actual edge of the image or where there are formatting
3095 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003096 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003097 min_size = BLOCK_4X4;
3098 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003099 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003100 }
3101
3102 // When use_square_partition_only is true, make sure at least one square
3103 // partition is allowed by selecting the next smaller square size as
3104 // *min_block_size.
3105 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003106 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003107 }
3108
Yaowu Xuf883b422016-08-30 14:01:10 -07003109 *min_block_size = AOMMIN(min_size, cm->sb_size);
3110 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003111}
3112
3113// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003114static void set_partition_range(const AV1_COMMON *const cm,
3115 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003116 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003117 BLOCK_SIZE *const min_bs,
3118 BLOCK_SIZE *const max_bs) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08003119 const int mi_width = mi_size_wide[bsize];
3120 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003121 int idx, idy;
3122
Yaowu Xuc27fc142016-08-22 16:08:15 -07003123 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003124 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3125 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3126 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003127
3128 if (prev_mi) {
3129 for (idy = 0; idy < mi_height; ++idy) {
3130 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003131 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3132 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003133 min_size = AOMMIN(min_size, bs);
3134 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003135 }
3136 }
3137 }
3138
3139 if (xd->left_available) {
3140 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003141 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3142 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003143 min_size = AOMMIN(min_size, bs);
3144 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003145 }
3146 }
3147
3148 if (xd->up_available) {
3149 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003150 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3151 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003152 min_size = AOMMIN(min_size, bs);
3153 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003154 }
3155 }
3156
3157 if (min_size == max_size) {
3158 min_size = min_partition_size[min_size];
3159 max_size = max_partition_size[max_size];
3160 }
3161
Yaowu Xuf883b422016-08-30 14:01:10 -07003162 *min_bs = AOMMIN(min_size, cm->sb_size);
3163 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003164}
3165
3166static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3167 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3168}
3169
3170static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3171 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3172}
3173
3174#if CONFIG_FP_MB_STATS
3175const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3176 0,
3177 10,
3178 10,
3179 30,
3180 40,
3181 40,
3182 60,
3183 80,
3184 80,
3185 90,
3186 100,
3187 100,
3188 120,
3189#if CONFIG_EXT_PARTITION
3190 // TODO(debargha): What are the correct numbers here?
3191 130,
3192 130,
3193 150
3194#endif // CONFIG_EXT_PARTITION
3195};
3196const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3197 0,
3198 3,
3199 3,
3200 7,
3201 15,
3202 15,
3203 30,
3204 40,
3205 40,
3206 60,
3207 80,
3208 80,
3209 120,
3210#if CONFIG_EXT_PARTITION
3211 // TODO(debargha): What are the correct numbers here?
3212 160,
3213 160,
3214 240
3215#endif // CONFIG_EXT_PARTITION
3216};
3217const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3218 1,
3219 1,
3220 1,
3221 1,
3222 1,
3223 1,
3224 1,
3225 1,
3226 1,
3227 1,
3228 4,
3229 4,
Yaowu Xu17fd2f22016-11-17 18:23:28 -08003230 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003231#if CONFIG_EXT_PARTITION
3232 // TODO(debargha): What are the correct numbers here?
3233 8,
3234 8,
3235 10
3236#endif // CONFIG_EXT_PARTITION
3237};
3238
3239typedef enum {
3240 MV_ZERO = 0,
3241 MV_LEFT = 1,
3242 MV_UP = 2,
3243 MV_RIGHT = 3,
3244 MV_DOWN = 4,
3245 MV_INVALID
3246} MOTION_DIRECTION;
3247
3248static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3249 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3250 return MV_ZERO;
3251 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3252 return MV_LEFT;
3253 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3254 return MV_RIGHT;
3255 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3256 return MV_UP;
3257 } else {
3258 return MV_DOWN;
3259 }
3260}
3261
3262static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3263 MOTION_DIRECTION that_mv) {
3264 if (this_mv == that_mv) {
3265 return 0;
3266 } else {
3267 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3268 }
3269}
3270#endif
3271
3272#if CONFIG_EXT_PARTITION_TYPES
3273static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003274 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3275 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3276 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3277 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003278#if CONFIG_SUPERTX
3279 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3280#endif
3281 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3282 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3283 MACROBLOCK *const x = &td->mb;
3284 MACROBLOCKD *const xd = &x->e_mbd;
3285 RD_COST this_rdc, sum_rdc;
3286#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003287 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003288 TileInfo *const tile_info = &tile_data->tile_info;
3289 int this_rate_nocoef, sum_rate_nocoef;
3290 int abort_flag;
3291 const int supertx_allowed = !frame_is_intra_only(cm) &&
3292 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3293 !xd->lossless[0];
3294#endif
3295 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3296
3297 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3298#if CONFIG_SUPERTX
3299 &sum_rate_nocoef,
3300#endif
3301#if CONFIG_EXT_PARTITION_TYPES
3302 partition,
3303#endif
3304 subsize0, &ctxs[0], best_rdc->rdcost);
3305#if CONFIG_SUPERTX
3306 abort_flag = sum_rdc.rdcost >= best_rd;
3307#endif
3308
3309#if CONFIG_SUPERTX
3310 if (sum_rdc.rdcost < INT64_MAX) {
3311#else
3312 if (sum_rdc.rdcost < best_rdc->rdcost) {
3313#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003314 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3315 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003316 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003317 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318
Urvang Joshi368fbc92016-10-17 16:31:34 -07003319 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003320
3321#if CONFIG_SUPERTX
3322 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3323 &this_rate_nocoef,
3324#if CONFIG_EXT_PARTITION_TYPES
3325 partition,
3326#endif
3327 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3328#else
3329 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3330#if CONFIG_EXT_PARTITION_TYPES
3331 partition,
3332#endif
3333 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3334#endif // CONFIG_SUPERTX
3335
3336 if (this_rdc.rate == INT_MAX) {
3337 sum_rdc.rdcost = INT64_MAX;
3338#if CONFIG_SUPERTX
3339 sum_rate_nocoef = INT_MAX;
3340#endif
3341 } else {
3342 sum_rdc.rate += this_rdc.rate;
3343 sum_rdc.dist += this_rdc.dist;
3344 sum_rdc.rdcost += this_rdc.rdcost;
3345#if CONFIG_SUPERTX
3346 sum_rate_nocoef += this_rate_nocoef;
3347#endif
3348 }
3349
3350#if CONFIG_SUPERTX
3351 if (sum_rdc.rdcost < INT64_MAX) {
3352#else
3353 if (sum_rdc.rdcost < best_rdc->rdcost) {
3354#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003355 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3356 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003357 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003358 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003359
Urvang Joshi368fbc92016-10-17 16:31:34 -07003360 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003361
3362#if CONFIG_SUPERTX
3363 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3364 &this_rate_nocoef,
3365#if CONFIG_EXT_PARTITION_TYPES
3366 partition,
3367#endif
3368 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3369#else
3370 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3371#if CONFIG_EXT_PARTITION_TYPES
3372 partition,
3373#endif
3374 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3375#endif // CONFIG_SUPERTX
3376
3377 if (this_rdc.rate == INT_MAX) {
3378 sum_rdc.rdcost = INT64_MAX;
3379#if CONFIG_SUPERTX
3380 sum_rate_nocoef = INT_MAX;
3381#endif
3382 } else {
3383 sum_rdc.rate += this_rdc.rate;
3384 sum_rdc.dist += this_rdc.dist;
3385 sum_rdc.rdcost += this_rdc.rdcost;
3386#if CONFIG_SUPERTX
3387 sum_rate_nocoef += this_rate_nocoef;
3388#endif
3389 }
3390
3391#if CONFIG_SUPERTX
3392 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3393 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3394 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3395 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003396 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003397 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3398 [supertx_size],
3399 0);
3400 sum_rdc.rdcost =
3401 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3402
3403 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3404 TX_TYPE best_tx = DCT_DCT;
3405 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3406
3407 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3408
3409 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3410 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3411
Yaowu Xuf883b422016-08-30 14:01:10 -07003412 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003413 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3414 [supertx_size],
3415 1);
3416 tmp_rdc.rdcost =
3417 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3418 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3419 sum_rdc = tmp_rdc;
3420 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3421 supertx_size, pc_tree);
3422 }
3423 }
3424
3425 pc_tree->partitioning = best_partition;
3426 }
3427#endif // CONFIG_SUPERTX
3428
3429 if (sum_rdc.rdcost < best_rdc->rdcost) {
3430 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3431 sum_rdc.rate += cpi->partition_cost[pl][partition];
3432 sum_rdc.rdcost =
3433 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3434#if CONFIG_SUPERTX
3435 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3436#endif
3437 if (sum_rdc.rdcost < best_rdc->rdcost) {
3438#if CONFIG_SUPERTX
3439 *best_rate_nocoef = sum_rate_nocoef;
3440 assert(*best_rate_nocoef >= 0);
3441#endif
3442 *best_rdc = sum_rdc;
3443 pc_tree->partitioning = partition;
3444 }
3445 }
3446 }
3447 }
3448}
3449#endif // CONFIG_EXT_PARTITION_TYPES
3450
3451// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3452// unlikely to be selected depending on previous rate-distortion optimization
3453// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003454static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003455 TileDataEnc *tile_data, TOKENEXTRA **tp,
3456 int mi_row, int mi_col, BLOCK_SIZE bsize,
3457 RD_COST *rd_cost,
3458#if CONFIG_SUPERTX
3459 int *rate_nocoef,
3460#endif
3461 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003462 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003463 TileInfo *const tile_info = &tile_data->tile_info;
3464 MACROBLOCK *const x = &td->mb;
3465 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08003466 const int mi_step = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003467 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003468 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003469 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003470
Yaowu Xuc27fc142016-08-22 16:08:15 -07003471 int tmp_partition_cost[PARTITION_TYPES];
3472 BLOCK_SIZE subsize;
3473 RD_COST this_rdc, sum_rdc, best_rdc;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003474 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3475 int do_square_split = bsize_at_least_8x8;
3476
3477#if CONFIG_CB4X4
3478 const int unify_bsize = 1;
3479 const int pl = bsize_at_least_8x8
3480 ? partition_plane_context(xd, mi_row, mi_col, bsize)
3481 : 0;
3482#else
3483 const int unify_bsize = 0;
3484 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3485#endif // CONFIG_CB4X4
3486 const int *partition_cost = cpi->partition_cost[pl];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003487#if CONFIG_SUPERTX
3488 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3489 int abort_flag;
3490 const int supertx_allowed = !frame_is_intra_only(cm) &&
3491 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3492 !xd->lossless[0];
3493#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003494
Urvang Joshi52648442016-10-13 17:27:51 -07003495 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496#if CONFIG_EXT_PARTITION_TYPES
3497 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3498#endif
3499
3500 // Override skipping rectangular partition operations for edge blocks
3501 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3502 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3503 const int xss = x->e_mbd.plane[1].subsampling_x;
3504 const int yss = x->e_mbd.plane[1].subsampling_y;
3505
3506 BLOCK_SIZE min_size = x->min_partition_size;
3507 BLOCK_SIZE max_size = x->max_partition_size;
3508
3509#if CONFIG_FP_MB_STATS
3510 unsigned int src_diff_var = UINT_MAX;
3511 int none_complexity = 0;
3512#endif
3513
3514 int partition_none_allowed = !force_horz_split && !force_vert_split;
3515 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003516 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003517 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003518 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003519
3520#if CONFIG_PVQ
3521 od_rollback_buffer pre_rdo_buf;
3522#endif
3523
Yaowu Xuc27fc142016-08-22 16:08:15 -07003524 (void)*tp_orig;
3525
3526 if (force_horz_split || force_vert_split) {
3527 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3528
3529 if (!force_vert_split) { // force_horz_split only
3530 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3531 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003532 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003533 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003534 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003535 } else if (!force_horz_split) { // force_vert_split only
3536 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3537 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003538 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003539 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003540 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003541 } else { // force_ horz_split && force_vert_split horz_split
3542 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3543 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3544 tmp_partition_cost[PARTITION_SPLIT] = 0;
3545 }
3546
3547 partition_cost = tmp_partition_cost;
3548 }
3549
3550#if CONFIG_VAR_TX
3551#ifndef NDEBUG
3552 // Nothing should rely on the default value of this array (which is just
3553 // leftover from encoding the previous block. Setting it to magic number
3554 // when debugging.
3555 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3556#endif // NDEBUG
3557#endif // CONFIG_VAR_TX
3558
Jingning Hanc709e1f2016-12-06 14:48:09 -08003559 assert(mi_size_wide[bsize] == mi_size_high[bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003560
Yaowu Xuf883b422016-08-30 14:01:10 -07003561 av1_rd_cost_init(&this_rdc);
3562 av1_rd_cost_init(&sum_rdc);
3563 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003564 best_rdc.rdcost = best_rd;
3565
3566 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3567
3568 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003569 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570
3571 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003572 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003573 ((pc_tree->index == 0 || pc_tree->index == 3) +
3574 get_chessboard_index(cm->current_video_frame)) &
3575 0x1;
3576
3577 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3578 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3579 }
3580
3581 // Determine partition types in search according to the speed features.
3582 // The threshold set here has to be of square block size.
3583 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003584 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3585 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3586 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3587 partition_none_allowed &= no_partition_allowed;
3588 partition_horz_allowed &= partition_allowed || force_horz_split;
3589 partition_vert_allowed &= partition_allowed || force_vert_split;
3590 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003591 }
3592 if (cpi->sf.use_square_partition_only) {
3593 partition_horz_allowed &= force_horz_split;
3594 partition_vert_allowed &= force_vert_split;
3595 }
3596
3597#if CONFIG_VAR_TX
3598 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3599 xd->left_txfm_context =
3600 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3601#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003602#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003603 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003604#else
3605 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3606#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003607
3608#if CONFIG_FP_MB_STATS
3609 if (cpi->use_fp_mb_stats) {
3610 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3611 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3612 mi_col, bsize);
3613 }
3614#endif
3615
3616#if CONFIG_FP_MB_STATS
3617 // Decide whether we shall split directly and skip searching NONE by using
3618 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003619 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 partition_none_allowed && src_diff_var > 4 &&
3621 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3622 int mb_row = mi_row >> 1;
3623 int mb_col = mi_col >> 1;
3624 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003625 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003626 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003627 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003628 int r, c;
3629
3630 // compute a complexity measure, basically measure inconsistency of motion
3631 // vectors obtained from the first pass in the current block
3632 for (r = mb_row; r < mb_row_end; r++) {
3633 for (c = mb_col; c < mb_col_end; c++) {
3634 const int mb_index = r * cm->mb_cols + c;
3635
3636 MOTION_DIRECTION this_mv;
3637 MOTION_DIRECTION right_mv;
3638 MOTION_DIRECTION bottom_mv;
3639
3640 this_mv =
3641 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3642
3643 // to its right
3644 if (c != mb_col_end - 1) {
3645 right_mv = get_motion_direction_fp(
3646 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3647 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3648 }
3649
3650 // to its bottom
3651 if (r != mb_row_end - 1) {
3652 bottom_mv = get_motion_direction_fp(
3653 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3654 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3655 }
3656
3657 // do not count its left and top neighbors to avoid double counting
3658 }
3659 }
3660
3661 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3662 partition_none_allowed = 0;
3663 }
3664 }
3665#endif
3666
3667 // PARTITION_NONE
3668 if (partition_none_allowed) {
3669 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3670#if CONFIG_SUPERTX
3671 &this_rate_nocoef,
3672#endif
3673#if CONFIG_EXT_PARTITION_TYPES
3674 PARTITION_NONE,
3675#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003676 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003677 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003678 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003679 this_rdc.rate += partition_cost[PARTITION_NONE];
3680 this_rdc.rdcost =
3681 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3682#if CONFIG_SUPERTX
3683 this_rate_nocoef += partition_cost[PARTITION_NONE];
3684#endif
3685 }
3686
3687 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003688 // Adjust dist breakout threshold according to the partition size.
3689 const int64_t dist_breakout_thr =
3690 cpi->sf.partition_search_breakout_dist_thr >>
3691 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3692 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3693 const int rate_breakout_thr =
3694 cpi->sf.partition_search_breakout_rate_thr *
3695 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003696
3697 best_rdc = this_rdc;
3698#if CONFIG_SUPERTX
3699 best_rate_nocoef = this_rate_nocoef;
3700 assert(best_rate_nocoef >= 0);
3701#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003702 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003703
3704 // If all y, u, v transform blocks in this partition are skippable, and
3705 // the dist & rate are within the thresholds, the partition search is
3706 // terminated for current branch of the partition search tree.
3707 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3708 // early termination at that speed.
3709 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003710 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003711 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003712 do_square_split = 0;
3713 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714 }
3715
3716#if CONFIG_FP_MB_STATS
3717 // Check if every 16x16 first pass block statistics has zero
3718 // motion and the corresponding first pass residue is small enough.
3719 // If that is the case, check the difference variance between the
3720 // current frame and the last frame. If the variance is small enough,
3721 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003722 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003723 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3724 int mb_row = mi_row >> 1;
3725 int mb_col = mi_col >> 1;
3726 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003727 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003728 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003729 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003730 int r, c;
3731
3732 int skip = 1;
3733 for (r = mb_row; r < mb_row_end; r++) {
3734 for (c = mb_col; c < mb_col_end; c++) {
3735 const int mb_index = r * cm->mb_cols + c;
3736 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3737 FPMB_MOTION_ZERO_MASK) ||
3738 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3739 FPMB_ERROR_SMALL_MASK)) {
3740 skip = 0;
3741 break;
3742 }
3743 }
3744 if (skip == 0) {
3745 break;
3746 }
3747 }
3748 if (skip) {
3749 if (src_diff_var == UINT_MAX) {
3750 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3751 src_diff_var = get_sby_perpixel_diff_variance(
3752 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3753 }
3754 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003755 do_square_split = 0;
3756 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003757 }
3758 }
3759 }
3760#endif
3761 }
3762 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003763#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003764 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003765#else
3766 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3767#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003768 }
3769
3770 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003771 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003772
3773 // PARTITION_SPLIT
3774 // TODO(jingning): use the motion vectors given by the above search as
3775 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003776 if (do_square_split) {
3777 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003778 subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003779 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003780#if CONFIG_DUAL_FILTER
3781 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3782 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003783 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003784#else
3785 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3786 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003787 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788#endif
3789#if CONFIG_SUPERTX
3790 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3791 &sum_rate_nocoef,
3792#if CONFIG_EXT_PARTITION_TYPES
3793 PARTITION_SPLIT,
3794#endif
3795 subsize, pc_tree->leaf_split[0], INT64_MAX);
3796#else
3797 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3798#if CONFIG_EXT_PARTITION_TYPES
3799 PARTITION_SPLIT,
3800#endif
3801 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3802#endif // CONFIG_SUPERTX
3803 if (sum_rdc.rate == INT_MAX) {
3804 sum_rdc.rdcost = INT64_MAX;
3805#if CONFIG_SUPERTX
3806 sum_rate_nocoef = INT_MAX;
3807#endif
3808 }
3809#if CONFIG_SUPERTX
3810 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3811 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3812 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3813
3814 pc_tree->partitioning = PARTITION_SPLIT;
3815
clang-format67948d32016-09-07 22:40:40 -07003816 sum_rdc.rate +=
3817 av1_cost_bit(cm->fc->supertx_prob
3818 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3819 [supertx_size],
3820 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003821 sum_rdc.rdcost =
3822 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3823
3824 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3825 TX_TYPE best_tx = DCT_DCT;
3826 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3827
3828 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3829
3830 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3831 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3832
Yaowu Xuf883b422016-08-30 14:01:10 -07003833 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003834 cm->fc->supertx_prob
3835 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3836 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003837 1);
3838 tmp_rdc.rdcost =
3839 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3840 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3841 sum_rdc = tmp_rdc;
3842 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3843 supertx_size, pc_tree);
3844 }
3845 }
3846
3847 pc_tree->partitioning = best_partition;
3848 }
3849#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003850 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003851 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07003852 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003853#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003854 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003855#else
Urvang Joshi52648442016-10-13 17:27:51 -07003856 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003858 const int x_idx = (idx & 1) * mi_step;
3859 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003860
3861 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3862 continue;
3863
Urvang Joshi454280d2016-10-14 16:51:44 -07003864 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865
Urvang Joshi52648442016-10-13 17:27:51 -07003866 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003867#if CONFIG_SUPERTX
3868 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3869 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07003870 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003871#else
Urvang Joshi52648442016-10-13 17:27:51 -07003872 rd_pick_partition(
3873 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
3874 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003875#endif // CONFIG_SUPERTX
3876
3877 if (this_rdc.rate == INT_MAX) {
3878 sum_rdc.rdcost = INT64_MAX;
3879#if CONFIG_SUPERTX
3880 sum_rate_nocoef = INT_MAX;
3881#endif // CONFIG_SUPERTX
3882 break;
3883 } else {
3884 sum_rdc.rate += this_rdc.rate;
3885 sum_rdc.dist += this_rdc.dist;
3886 sum_rdc.rdcost += this_rdc.rdcost;
3887#if CONFIG_SUPERTX
3888 sum_rate_nocoef += this_rate_nocoef;
3889#endif // CONFIG_SUPERTX
3890 }
3891 }
Urvang Joshi52648442016-10-13 17:27:51 -07003892 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003893#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003894 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3896 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3897
3898 pc_tree->partitioning = PARTITION_SPLIT;
3899
clang-format67948d32016-09-07 22:40:40 -07003900 sum_rdc.rate +=
3901 av1_cost_bit(cm->fc->supertx_prob
3902 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3903 [supertx_size],
3904 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905 sum_rdc.rdcost =
3906 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3907
3908 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3909 TX_TYPE best_tx = DCT_DCT;
3910 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3911
3912 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3913
3914 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3915 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3916
Yaowu Xuf883b422016-08-30 14:01:10 -07003917 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003918 cm->fc->supertx_prob
3919 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3920 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003921 1);
3922 tmp_rdc.rdcost =
3923 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3924 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3925 sum_rdc = tmp_rdc;
3926 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3927 supertx_size, pc_tree);
3928 }
3929 }
3930
3931 pc_tree->partitioning = best_partition;
3932 }
3933#endif // CONFIG_SUPERTX
3934 }
3935
Urvang Joshi52648442016-10-13 17:27:51 -07003936 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3938 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3939#if CONFIG_SUPERTX
3940 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3941#endif // CONFIG_SUPERTX
3942
3943 if (sum_rdc.rdcost < best_rdc.rdcost) {
3944 best_rdc = sum_rdc;
3945#if CONFIG_SUPERTX
3946 best_rate_nocoef = sum_rate_nocoef;
3947 assert(best_rate_nocoef >= 0);
3948#endif // CONFIG_SUPERTX
3949 pc_tree->partitioning = PARTITION_SPLIT;
3950 }
Urvang Joshi52648442016-10-13 17:27:51 -07003951 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003952 // skip rectangular partition test when larger block size
3953 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07003954 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003955 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003956#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003957 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003958#else
3959 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3960#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003961 } // if (do_split)
3962
3963 // PARTITION_HORZ
3964 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003965 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07003967 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003968#if CONFIG_DUAL_FILTER
3969 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3970 partition_none_allowed)
3971 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003972 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003973#else
3974 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3975 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003976 pc_tree->horizontal[0].pred_interp_filter =
3977 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978#endif
3979 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3980#if CONFIG_SUPERTX
3981 &sum_rate_nocoef,
3982#endif // CONFIG_SUPERTX
3983#if CONFIG_EXT_PARTITION_TYPES
3984 PARTITION_HORZ,
3985#endif
3986 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3987
3988#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08003989 abort_flag =
3990 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
3991 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003992 if (sum_rdc.rdcost < INT64_MAX &&
3993#else
3994 if (sum_rdc.rdcost < best_rdc.rdcost &&
3995#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003996 !force_horz_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07003997 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
3998 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003999 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07004000 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004001
Urvang Joshi454280d2016-10-14 16:51:44 -07004002 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004003
4004#if CONFIG_DUAL_FILTER
4005 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4006 partition_none_allowed)
4007 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004008 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004009#else
4010 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4011 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004012 pc_tree->horizontal[1].pred_interp_filter =
4013 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004014#endif
4015#if CONFIG_SUPERTX
4016 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4017 &this_rate_nocoef,
4018#if CONFIG_EXT_PARTITION_TYPES
4019 PARTITION_HORZ,
4020#endif
4021 subsize, &pc_tree->horizontal[1], INT64_MAX);
4022#else
4023 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4024#if CONFIG_EXT_PARTITION_TYPES
4025 PARTITION_HORZ,
4026#endif
4027 subsize, &pc_tree->horizontal[1],
4028 best_rdc.rdcost - sum_rdc.rdcost);
4029#endif // CONFIG_SUPERTX
4030 if (this_rdc.rate == INT_MAX) {
4031 sum_rdc.rdcost = INT64_MAX;
4032#if CONFIG_SUPERTX
4033 sum_rate_nocoef = INT_MAX;
4034#endif // CONFIG_SUPERTX
4035 } else {
4036 sum_rdc.rate += this_rdc.rate;
4037 sum_rdc.dist += this_rdc.dist;
4038 sum_rdc.rdcost += this_rdc.rdcost;
4039#if CONFIG_SUPERTX
4040 sum_rate_nocoef += this_rate_nocoef;
4041#endif // CONFIG_SUPERTX
4042 }
4043 }
4044
4045#if CONFIG_SUPERTX
4046 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4047 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4048 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4049
4050 pc_tree->partitioning = PARTITION_HORZ;
4051
Yaowu Xuf883b422016-08-30 14:01:10 -07004052 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004053 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4054 [supertx_size],
4055 0);
4056 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4057
4058 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4059 TX_TYPE best_tx = DCT_DCT;
4060 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4061
4062 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4063
4064 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4065 &tmp_rdc.dist, &best_tx, pc_tree);
4066
Yaowu Xuf883b422016-08-30 14:01:10 -07004067 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004068 cm->fc
4069 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4070 [supertx_size],
4071 1);
4072 tmp_rdc.rdcost =
4073 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4074 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4075 sum_rdc = tmp_rdc;
4076 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4077 supertx_size, pc_tree);
4078 }
4079 }
4080
4081 pc_tree->partitioning = best_partition;
4082 }
4083#endif // CONFIG_SUPERTX
4084
4085 if (sum_rdc.rdcost < best_rdc.rdcost) {
4086 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4087 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4088#if CONFIG_SUPERTX
4089 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4090#endif // CONFIG_SUPERTX
4091 if (sum_rdc.rdcost < best_rdc.rdcost) {
4092 best_rdc = sum_rdc;
4093#if CONFIG_SUPERTX
4094 best_rate_nocoef = sum_rate_nocoef;
4095 assert(best_rate_nocoef >= 0);
4096#endif // CONFIG_SUPERTX
4097 pc_tree->partitioning = PARTITION_HORZ;
4098 }
4099 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004100#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004101 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004102#else
4103 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4104#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 }
4106
4107 // PARTITION_VERT
4108 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004109 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004110 subsize = get_subsize(bsize, PARTITION_VERT);
4111
Urvang Joshi454280d2016-10-14 16:51:44 -07004112 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004113
4114#if CONFIG_DUAL_FILTER
4115 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4116 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004117 pc_tree->vertical[0].pred_interp_filter =
4118 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004119#else
4120 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4121 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004122 pc_tree->vertical[0].pred_interp_filter =
4123 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004124#endif
4125 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4126#if CONFIG_SUPERTX
4127 &sum_rate_nocoef,
4128#endif // CONFIG_SUPERTX
4129#if CONFIG_EXT_PARTITION_TYPES
4130 PARTITION_VERT,
4131#endif
4132 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4133#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08004134 abort_flag =
4135 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4136 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004137 if (sum_rdc.rdcost < INT64_MAX &&
4138#else
4139 if (sum_rdc.rdcost < best_rdc.rdcost &&
4140#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004141 !force_vert_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004142 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4143 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4144 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004145
Urvang Joshi454280d2016-10-14 16:51:44 -07004146 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147
4148#if CONFIG_DUAL_FILTER
4149 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4150 partition_none_allowed)
4151 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004152 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004153#else
4154 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4155 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004156 pc_tree->vertical[1].pred_interp_filter =
4157 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004158#endif
4159#if CONFIG_SUPERTX
4160 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4161 &this_rate_nocoef,
4162#if CONFIG_EXT_PARTITION_TYPES
4163 PARTITION_VERT,
4164#endif
4165 subsize, &pc_tree->vertical[1],
4166 INT64_MAX - sum_rdc.rdcost);
4167#else
4168 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4169#if CONFIG_EXT_PARTITION_TYPES
4170 PARTITION_VERT,
4171#endif
4172 subsize, &pc_tree->vertical[1],
4173 best_rdc.rdcost - sum_rdc.rdcost);
4174#endif // CONFIG_SUPERTX
4175 if (this_rdc.rate == INT_MAX) {
4176 sum_rdc.rdcost = INT64_MAX;
4177#if CONFIG_SUPERTX
4178 sum_rate_nocoef = INT_MAX;
4179#endif // CONFIG_SUPERTX
4180 } else {
4181 sum_rdc.rate += this_rdc.rate;
4182 sum_rdc.dist += this_rdc.dist;
4183 sum_rdc.rdcost += this_rdc.rdcost;
4184#if CONFIG_SUPERTX
4185 sum_rate_nocoef += this_rate_nocoef;
4186#endif // CONFIG_SUPERTX
4187 }
4188 }
4189#if CONFIG_SUPERTX
4190 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4191 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4192 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4193
4194 pc_tree->partitioning = PARTITION_VERT;
4195
Yaowu Xuf883b422016-08-30 14:01:10 -07004196 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004197 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4198 [supertx_size],
4199 0);
4200 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4201
4202 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4203 TX_TYPE best_tx = DCT_DCT;
4204 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4205
4206 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4207
4208 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4209 &tmp_rdc.dist, &best_tx, pc_tree);
4210
Yaowu Xuf883b422016-08-30 14:01:10 -07004211 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004212 cm->fc
4213 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4214 [supertx_size],
4215 1);
4216 tmp_rdc.rdcost =
4217 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4218 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4219 sum_rdc = tmp_rdc;
4220 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4221 supertx_size, pc_tree);
4222 }
4223 }
4224
4225 pc_tree->partitioning = best_partition;
4226 }
4227#endif // CONFIG_SUPERTX
4228
4229 if (sum_rdc.rdcost < best_rdc.rdcost) {
4230 sum_rdc.rate += partition_cost[PARTITION_VERT];
4231 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4232#if CONFIG_SUPERTX
4233 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4234#endif // CONFIG_SUPERTX
4235 if (sum_rdc.rdcost < best_rdc.rdcost) {
4236 best_rdc = sum_rdc;
4237#if CONFIG_SUPERTX
4238 best_rate_nocoef = sum_rate_nocoef;
4239 assert(best_rate_nocoef >= 0);
4240#endif // CONFIG_SUPERTX
4241 pc_tree->partitioning = PARTITION_VERT;
4242 }
4243 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004244#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004245 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004246#else
4247 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4248#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004249 }
4250
4251#if CONFIG_EXT_PARTITION_TYPES
4252 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004253 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004254 partition_none_allowed) {
4255 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4256 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004257 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004258 PARTITION_HORZ_A,
4259#if CONFIG_SUPERTX
4260 best_rd, &best_rate_nocoef, &x_ctx,
4261#endif
4262 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4263 mi_row + mi_step, mi_col, subsize);
4264 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4265 }
4266 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004267 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004268 partition_none_allowed) {
4269 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4270 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004271 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004272 PARTITION_HORZ_B,
4273#if CONFIG_SUPERTX
4274 best_rd, &best_rate_nocoef, &x_ctx,
4275#endif
4276 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4277 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4278 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4279 }
4280 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004281 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004282 partition_none_allowed) {
4283 subsize = get_subsize(bsize, PARTITION_VERT_A);
4284 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004285 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286 PARTITION_VERT_A,
4287#if CONFIG_SUPERTX
4288 best_rd, &best_rate_nocoef, &x_ctx,
4289#endif
4290 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4291 mi_row, mi_col + mi_step, subsize);
4292 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4293 }
4294 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004295 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004296 partition_none_allowed) {
4297 subsize = get_subsize(bsize, PARTITION_VERT_B);
4298 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004299 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004300 PARTITION_VERT_B,
4301#if CONFIG_SUPERTX
4302 best_rd, &best_rate_nocoef, &x_ctx,
4303#endif
4304 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4305 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4306 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4307 }
4308#endif // CONFIG_EXT_PARTITION_TYPES
4309
4310 // TODO(jbb): This code added so that we avoid static analysis
4311 // warning related to the fact that best_rd isn't used after this
4312 // point. This code should be refactored so that the duplicate
4313 // checks occur in some sub function and thus are used...
4314 (void)best_rd;
4315 *rd_cost = best_rdc;
4316#if CONFIG_SUPERTX
4317 *rate_nocoef = best_rate_nocoef;
4318#endif // CONFIG_SUPERTX
4319
4320 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4321 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004322 if (bsize == cm->sb_size) {
4323 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4324 pc_tree, NULL);
4325 } else {
4326 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4327 pc_tree, NULL);
4328 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004329 }
4330
4331 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004332#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004333 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004334#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004335 assert(best_rdc.rate < INT_MAX);
4336 assert(best_rdc.dist < INT64_MAX);
4337 } else {
4338 assert(tp_orig == *tp);
4339 }
4340}
4341
Yaowu Xuf883b422016-08-30 14:01:10 -07004342static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004343 TileDataEnc *tile_data, int mi_row,
4344 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004345 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004346 const TileInfo *const tile_info = &tile_data->tile_info;
4347 MACROBLOCK *const x = &td->mb;
4348 MACROBLOCKD *const xd = &x->e_mbd;
4349 SPEED_FEATURES *const sf = &cpi->sf;
4350 int mi_col;
4351#if CONFIG_EXT_PARTITION
4352 const int leaf_nodes = 256;
4353#else
4354 const int leaf_nodes = 64;
4355#endif // CONFIG_EXT_PARTITION
4356
4357 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004358 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004359
Thomas Daviesf6936102016-09-05 16:51:31 +01004360#if CONFIG_DELTA_Q
4361 // Reset delta for every tile
4362 if (cm->delta_q_present_flag)
4363 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4364#endif
4365
Yaowu Xuc27fc142016-08-22 16:08:15 -07004366 // Code each SB in the row
4367 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4368 mi_col += cm->mib_size) {
4369 const struct segmentation *const seg = &cm->seg;
4370 int dummy_rate;
4371 int64_t dummy_dist;
4372 RD_COST dummy_rdc;
4373#if CONFIG_SUPERTX
4374 int dummy_rate_nocoef;
4375#endif // CONFIG_SUPERTX
4376 int i;
4377 int seg_skip = 0;
4378
4379 const int idx_str = cm->mi_stride * mi_row + mi_col;
4380 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4381 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4382
4383 if (sf->adaptive_pred_interp_filter) {
4384 for (i = 0; i < leaf_nodes; ++i)
4385 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4386
4387 for (i = 0; i < leaf_nodes; ++i) {
4388 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4389 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4390 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4391 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4392 }
4393 }
4394
Yaowu Xuf883b422016-08-30 14:01:10 -07004395 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004396 pc_root->index = 0;
4397
4398 if (seg->enabled) {
4399 const uint8_t *const map =
4400 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4401 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4402 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4403 }
4404
Arild Fuldseth07441162016-08-15 15:07:52 +02004405#if CONFIG_DELTA_Q
4406 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004407 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004408 int sb_row = mi_row >> 3;
4409 int sb_col = mi_col >> 3;
4410 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4411 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004412
4413 // Ensure divisibility of delta_qindex by delta_q_res
4414 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4415 int qmask = ~(cm->delta_q_res - 1);
4416 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4417 cm->delta_q_res, 256 - cm->delta_q_res);
4418 current_qindex =
4419 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4420 cm->base_qindex;
4421
Arild Fuldseth07441162016-08-15 15:07:52 +02004422 xd->delta_qindex = current_qindex - cm->base_qindex;
4423 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4424 xd->mi[0]->mbmi.current_q_index = current_qindex;
4425 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004426 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004427 }
4428#endif
4429
Yaowu Xuc27fc142016-08-22 16:08:15 -07004430 x->source_variance = UINT_MAX;
4431 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4432 BLOCK_SIZE bsize;
4433 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4434 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4435 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4436 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4437 &dummy_rate, &dummy_dist,
4438#if CONFIG_SUPERTX
4439 &dummy_rate_nocoef,
4440#endif // CONFIG_SUPERTX
4441 1, pc_root);
4442 } else if (cpi->partition_search_skippable_frame) {
4443 BLOCK_SIZE bsize;
4444 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4445 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4446 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4447 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4448 &dummy_rate, &dummy_dist,
4449#if CONFIG_SUPERTX
4450 &dummy_rate_nocoef,
4451#endif // CONFIG_SUPERTX
4452 1, pc_root);
4453 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4454 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4455 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4456 &dummy_rate, &dummy_dist,
4457#if CONFIG_SUPERTX
4458 &dummy_rate_nocoef,
4459#endif // CONFIG_SUPERTX
4460 1, pc_root);
4461 } else {
4462 // If required set upper and lower partition size limits
4463 if (sf->auto_min_max_partition_size) {
4464 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4465 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4466 &x->min_partition_size, &x->max_partition_size);
4467 }
4468 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4469 &dummy_rdc,
4470#if CONFIG_SUPERTX
4471 &dummy_rate_nocoef,
4472#endif // CONFIG_SUPERTX
4473 INT64_MAX, pc_root);
4474 }
4475 }
4476#if CONFIG_ENTROPY
4477 if (cm->do_subframe_update &&
4478 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4479 if ((mi_row + MI_SIZE) %
4480 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004481 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004482 0 &&
4483 mi_row + MI_SIZE < cm->mi_rows &&
4484 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4485 TX_SIZE t;
4486 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4487
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08004488 for (t = TX_4X4; t < TX_SIZES; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004489 av1_full_to_model_counts(cpi->td.counts->coef[t],
4490 cpi->td.rd_counts.coef_counts[t]);
4491 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004492 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004493 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4494 cm->fc->coef_probs);
4495 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4496 cpi->td.rd_counts.coef_counts);
4497 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4498 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004499 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004500 }
4501 }
4502#endif // CONFIG_ENTROPY
4503}
4504
Yaowu Xuf883b422016-08-30 14:01:10 -07004505static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004506 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004507 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 MACROBLOCKD *const xd = &x->e_mbd;
4509
4510 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004511 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004512
Yaowu Xuf883b422016-08-30 14:01:10 -07004513 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004514}
4515
Yaowu Xuf883b422016-08-30 14:01:10 -07004516static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004517 const int ref_flags = cpi->ref_frame_flags;
4518
4519 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4520 return 0;
4521 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004522 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004523#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004524 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4525 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004526#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004527 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004528 }
4529}
4530
4531#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004532static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533 int mi_row, mi_col;
4534 const int mis = cm->mi_stride;
4535 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4536
4537 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4538 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4539 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4540 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4541 }
4542 }
4543}
4544#endif
4545
Yaowu Xuf883b422016-08-30 14:01:10 -07004546static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004547 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4548#if CONFIG_EXT_REFS
4549 // We will not update the golden frame with an internal overlay frame
4550 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4551 cpi->rc.is_src_frame_ext_arf)
4552#else
4553 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4554#endif
4555 return ALTREF_FRAME;
4556 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4557 return GOLDEN_FRAME;
4558 else
4559 // TODO(zoeliu): To investigate whether a frame_type other than
4560 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4561 return LAST_FRAME;
4562}
4563
Yaowu Xuf883b422016-08-30 14:01:10 -07004564static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004565 if (xd->lossless[0]) return ONLY_4X4;
4566 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004567 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004568 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4569 cpi->sf.tx_size_search_method == USE_TX_8X8)
4570 return TX_MODE_SELECT;
4571 else
4572 return cpi->common.tx_mode;
4573}
4574
Yaowu Xuf883b422016-08-30 14:01:10 -07004575void av1_init_tile_data(AV1_COMP *cpi) {
4576 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577 const int tile_cols = cm->tile_cols;
4578 const int tile_rows = cm->tile_rows;
4579 int tile_col, tile_row;
4580 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4581 unsigned int tile_tok = 0;
4582
4583 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004584 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4585 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004586 sizeof(*cpi->tile_data)));
4587 cpi->allocated_tiles = tile_cols * tile_rows;
4588
4589 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4590 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4591 TileDataEnc *const tile_data =
4592 &cpi->tile_data[tile_row * tile_cols + tile_col];
4593 int i, j;
4594 for (i = 0; i < BLOCK_SIZES; ++i) {
4595 for (j = 0; j < MAX_MODES; ++j) {
4596 tile_data->thresh_freq_fact[i][j] = 32;
4597 tile_data->mode_map[i][j] = j;
4598 }
4599 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004600#if CONFIG_PVQ
4601 // This will be dynamically increased as more pvq block is encoded.
4602 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004603 CHECK_MEM_ERROR(
4604 cm, tile_data->pvq_q.buf,
4605 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004606 tile_data->pvq_q.curr_pos = 0;
4607#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004608 }
4609 }
4610
4611 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4612 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4613 TileInfo *const tile_info =
4614 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004615 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616
4617 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4618 pre_tok = cpi->tile_tok[tile_row][tile_col];
4619 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004620#if CONFIG_PVQ
4621 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4622#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004623 }
4624 }
4625}
4626
Yaowu Xuf883b422016-08-30 14:01:10 -07004627void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4628 int tile_col) {
4629 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004630 TileDataEnc *const this_tile =
4631 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4632 const TileInfo *const tile_info = &this_tile->tile_info;
4633 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4634 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004635#if CONFIG_PVQ
4636 od_adapt_ctx *adapt;
4637#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638
Yaowu Xuf883b422016-08-30 14:01:10 -07004639 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004640
4641 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004642 this_tile->m_search_count = 0; // Count of motion search hits.
4643 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4644 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4645 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004646
Yushin Cho77bba8d2016-11-04 16:36:56 -07004647#if CONFIG_PVQ
4648 td->mb.pvq_q = &this_tile->pvq_q;
4649
Yushin Cho70669122016-12-08 09:53:14 -10004650 // TODO(yushin) : activity masking info needs be signaled by a bitstream
4651 td->mb.daala_enc.use_activity_masking = AV1_PVQ_ENABLE_ACTIVITY_MASKING;
4652
4653 if (td->mb.daala_enc.use_activity_masking)
4654 td->mb.daala_enc.qm = OD_HVS_QM; // Hard coded. Enc/dec required to sync.
4655 else
4656 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4657
Yushin Cho77bba8d2016-11-04 16:36:56 -07004658 {
4659 // FIXME: Multiple segments support
4660 int segment_id = 0;
4661 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4662 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4663 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4664 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4665 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4666 td->mb.daala_enc.pvq_norm_lambda =
4667 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4668 td->mb.daala_enc.pvq_norm_lambda_dc =
4669 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4670 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4671 }
4672 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4673 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
Yushin Cho70669122016-12-08 09:53:14 -10004674
4675 if (td->mb.daala_enc.use_activity_masking) {
4676 int pli;
4677 int use_masking = td->mb.daala_enc.use_activity_masking;
4678 int segment_id = 0;
4679 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4680
4681 for (pli = 0; pli < MAX_MB_PLANE; pli++) {
4682 int i;
4683 int q;
4684
4685 q = qindex;
4686 if (q <= OD_DEFAULT_QMS[use_masking][0][pli].interp_q << OD_COEFF_SHIFT) {
4687 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4688 &OD_DEFAULT_QMS[use_masking][0][pli], NULL);
4689 } else {
4690 i = 0;
4691 while (OD_DEFAULT_QMS[use_masking][i + 1][pli].qm_q4 != NULL &&
4692 q > OD_DEFAULT_QMS[use_masking][i + 1][pli].interp_q
4693 << OD_COEFF_SHIFT) {
4694 i++;
4695 }
4696 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4697 &OD_DEFAULT_QMS[use_masking][i][pli],
4698 &OD_DEFAULT_QMS[use_masking][i + 1][pli]);
4699 }
4700 }
4701 }
4702
Yushin Cho77bba8d2016-11-04 16:36:56 -07004703 od_ec_enc_init(&td->mb.daala_enc.ec, 65025);
4704
4705 adapt = &td->mb.daala_enc.state.adapt;
4706 od_ec_enc_reset(&td->mb.daala_enc.ec);
4707 od_adapt_ctx_reset(adapt, 0);
Yushin Cho70669122016-12-08 09:53:14 -10004708#endif // #if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -07004709
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4711 mi_row += cm->mib_size) {
4712 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4713 }
4714
4715 cpi->tok_count[tile_row][tile_col] =
4716 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4717 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004718#if CONFIG_PVQ
4719 od_ec_enc_clear(&td->mb.daala_enc.ec);
4720
4721 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4722 // rewind current position so that bitstream can be written
4723 // from the 1st pvq block
4724 td->mb.pvq_q->curr_pos = 0;
4725
4726 td->mb.pvq_q = NULL;
4727#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728}
4729
Yaowu Xuf883b422016-08-30 14:01:10 -07004730static void encode_tiles(AV1_COMP *cpi) {
4731 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732 int tile_col, tile_row;
4733
Yaowu Xuf883b422016-08-30 14:01:10 -07004734 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735
4736 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4737 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004738 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004739}
4740
4741#if CONFIG_FP_MB_STATS
4742static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004743 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004744 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4745 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4746
4747 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4748
4749 *this_frame_mb_stats = mb_stats_in;
4750
4751 return 1;
4752}
4753#endif
4754
Yaowu Xuf883b422016-08-30 14:01:10 -07004755static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004756 ThreadData *const td = &cpi->td;
4757 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004758 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004759 MACROBLOCKD *const xd = &x->e_mbd;
4760 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4761 int i;
4762
Yaowu Xuf883b422016-08-30 14:01:10 -07004763 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4764 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Jingning Han24e0a182016-11-20 22:34:12 -08004765#if CONFIG_REF_MV
Dengca8d24d2016-10-17 14:06:35 +08004766 cm->setup_mi(cm);
4767#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768
4769 xd->mi = cm->mi_grid_visible;
4770 xd->mi[0] = cm->mi;
4771
Yaowu Xuf883b422016-08-30 14:01:10 -07004772 av1_zero(*td->counts);
4773 av1_zero(rdc->coef_counts);
4774 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004775
4776#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004777 av1_zero(cpi->global_motion_used);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004778 if (cpi->common.frame_type == INTER_FRAME && cpi->Source &&
4779 !cpi->global_motion_search_done) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004780 YV12_BUFFER_CONFIG *ref_buf;
4781 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004782 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004783 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004784 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4785 ref_buf = get_ref_frame_buffer(cpi, frame);
4786 if (ref_buf) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004787 TransformationType model;
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004788 aom_clear_system_state();
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004789 for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
4790 if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
David Barker557ce7b2016-11-16 10:22:24 +00004791#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004792 cpi->common.bit_depth,
David Barker557ce7b2016-11-16 10:22:24 +00004793#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004794 params)) {
4795 convert_model_to_params(params, &cm->global_motion[frame]);
4796 if (cm->global_motion[frame].wmtype != IDENTITY) {
4797 erroradvantage = refine_integerized_param(
4798 &cm->global_motion[frame], cm->global_motion[frame].wmtype,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004799#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004800 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004801#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004802 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4803 ref_buf->y_stride, cpi->Source->y_buffer,
4804 cpi->Source->y_width, cpi->Source->y_height,
4805 cpi->Source->y_stride, 3);
4806 if (erroradvantage >
4807 gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
4808 set_default_gmparams(&cm->global_motion[frame]);
4809 }
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08004810 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004811 }
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08004812 if (cm->global_motion[frame].wmtype != IDENTITY) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004813 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08004814 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004815 }
4816 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004817 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004818 }
4819#endif // CONFIG_GLOBAL_MOTION
4820
4821 for (i = 0; i < MAX_SEGMENTS; ++i) {
4822 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004823 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 : cm->base_qindex;
4825 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4826 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4827 }
4828
4829 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4830
4831 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004832 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004833
Yaowu Xuf883b422016-08-30 14:01:10 -07004834 av1_initialize_rd_consts(cpi);
4835 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004836 init_encode_frame_mb_context(cpi);
4837
4838 cm->use_prev_frame_mvs =
4839 !cm->error_resilient_mode && cm->width == cm->last_width &&
4840 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004841
4842#if CONFIG_DELTA_Q
4843 // Fix delta q resolution for the moment
4844 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4845#endif
4846
Yaowu Xuc27fc142016-08-22 16:08:15 -07004847#if CONFIG_EXT_REFS
4848 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4849 // show_exisiting_frame=1, nor can it take a frame not used as
4850 // a reference, it is probable that by the time it is being
4851 // referred to, the frame buffer it originally points to may
4852 // already get expired and have been reassigned to the current
4853 // newly coded frame. Hence, we need to check whether this is
4854 // the case, and if yes, we have 2 choices:
4855 // (1) Simply disable the use of previous frame mvs; or
4856 // (2) Have cm->prev_frame point to one reference frame buffer,
4857 // e.g. LAST_FRAME.
4858 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4859 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4860 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4861 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4862 }
4863#endif // CONFIG_EXT_REFS
4864
4865 // Special case: set prev_mi to NULL when the previous mode info
4866 // context cannot be used.
4867 cm->prev_mi =
4868 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4869
4870#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004871 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004872#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004873 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004874#endif
4875#endif
4876
4877 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4878 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004879 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004880
4881 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004882 struct aom_usec_timer emr_timer;
4883 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004884
4885#if CONFIG_FP_MB_STATS
4886 if (cpi->use_fp_mb_stats) {
4887 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4888 &cpi->twopass.this_frame_mb_stats);
4889 }
4890#endif
4891
4892 // If allowed, encoding tiles in parallel with one thread handling one tile.
4893 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4894 // 1 tile rows, as it uses the single above_context et al arrays from
4895 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004896 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4897 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004898 else
4899 encode_tiles(cpi);
4900
Yaowu Xuf883b422016-08-30 14:01:10 -07004901 aom_usec_timer_mark(&emr_timer);
4902 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004903 }
4904
4905#if 0
4906 // Keep record of the total distortion this time around for future use
4907 cpi->last_frame_distortion = cpi->frame_distortion;
4908#endif
4909}
4910
Yaowu Xuf883b422016-08-30 14:01:10 -07004911void av1_encode_frame(AV1_COMP *cpi) {
4912 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004913
4914 // In the longer term the encoder should be generalized to match the
4915 // decoder such that we allow compound where one of the 3 buffers has a
4916 // different sign bias and that buffer is then the fixed ref. However, this
4917 // requires further work in the rd loop. For now the only supported encoder
4918 // side behavior is where the ALT ref buffer has opposite sign bias to
4919 // the other two.
4920 if (!frame_is_intra_only(cm)) {
4921 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4922 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4923 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4924 cm->ref_frame_sign_bias[LAST_FRAME])) {
4925 cpi->allow_comp_inter_inter = 0;
4926 } else {
4927 cpi->allow_comp_inter_inter = 1;
4928
4929#if CONFIG_EXT_REFS
4930 cm->comp_fwd_ref[0] = LAST_FRAME;
4931 cm->comp_fwd_ref[1] = LAST2_FRAME;
4932 cm->comp_fwd_ref[2] = LAST3_FRAME;
4933 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4934 cm->comp_bwd_ref[0] = BWDREF_FRAME;
4935 cm->comp_bwd_ref[1] = ALTREF_FRAME;
4936#else
4937 cm->comp_fixed_ref = ALTREF_FRAME;
4938 cm->comp_var_ref[0] = LAST_FRAME;
4939 cm->comp_var_ref[1] = GOLDEN_FRAME;
4940#endif // CONFIG_EXT_REFS
4941 }
4942 } else {
4943 cpi->allow_comp_inter_inter = 0;
4944 }
4945
4946 if (cpi->sf.frame_parameter_update) {
4947 int i;
4948 RD_OPT *const rd_opt = &cpi->rd;
4949 FRAME_COUNTS *counts = cpi->td.counts;
4950 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4951
4952 // This code does a single RD pass over the whole frame assuming
4953 // either compound, single or hybrid prediction as per whatever has
4954 // worked best for that type of frame in the past.
4955 // It also predicts whether another coding mode would have worked
4956 // better than this coding mode. If that is the case, it remembers
4957 // that for subsequent frames.
4958 // It does the same analysis for transform size selection also.
4959 //
4960 // TODO(zoeliu): To investigate whether a frame_type other than
4961 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4962 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4963 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4964 const int is_alt_ref = frame_type == ALTREF_FRAME;
4965
4966 /* prediction (compound, single or hybrid) mode selection */
4967 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4968 cm->reference_mode = SINGLE_REFERENCE;
4969 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4970 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4971 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4972 cm->reference_mode = COMPOUND_REFERENCE;
4973 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4974 cm->reference_mode = SINGLE_REFERENCE;
4975 else
4976 cm->reference_mode = REFERENCE_MODE_SELECT;
4977
4978#if CONFIG_DUAL_FILTER
4979 cm->interp_filter = SWITCHABLE;
4980#endif
4981
4982 encode_frame_internal(cpi);
4983
4984 for (i = 0; i < REFERENCE_MODES; ++i)
4985 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4986
4987 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4988 int single_count_zero = 0;
4989 int comp_count_zero = 0;
4990
4991 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
4992 single_count_zero += counts->comp_inter[i][0];
4993 comp_count_zero += counts->comp_inter[i][1];
4994 }
4995
4996 if (comp_count_zero == 0) {
4997 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004998 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004999 } else if (single_count_zero == 0) {
5000 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005001 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005002 }
5003 }
5004
Jingning Han9777afc2016-10-20 15:17:43 -07005005#if CONFIG_VAR_TX
5006 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005007 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Jingning Han9777afc2016-10-20 15:17:43 -07005008#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005009 if (cm->tx_mode == TX_MODE_SELECT) {
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005010#if CONFIG_TX64X64
5011 int count4x4 = 0;
5012 int count8x8_8x8p = 0, count8x8_lp = 0;
5013 int count16x16_16x16p = 0, count16x16_lp = 0;
5014 int count32x32_32x32p = 0, count32x32_lp = 0;
5015 int count64x64_64x64p = 0;
5016 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5017 // counts->tx_size[max_depth][context_idx][this_depth_level]
5018 count4x4 += counts->tx_size[0][i][0];
5019 count4x4 += counts->tx_size[1][i][0];
5020 count4x4 += counts->tx_size[2][i][0];
5021 count4x4 += counts->tx_size[3][i][0];
5022
5023 count8x8_8x8p += counts->tx_size[0][i][1];
5024 count8x8_lp += counts->tx_size[1][i][1];
5025 count8x8_lp += counts->tx_size[2][i][1];
5026 count8x8_lp += counts->tx_size[3][i][1];
5027
5028 count16x16_16x16p += counts->tx_size[1][i][2];
5029 count16x16_lp += counts->tx_size[2][i][2];
5030 count16x16_lp += counts->tx_size[3][i][2];
5031
5032 count32x32_32x32p += counts->tx_size[2][i][3];
5033 count32x32_lp += counts->tx_size[3][i][3];
5034
5035 count64x64_64x64p += counts->tx_size[3][i][4];
5036 }
5037#if CONFIG_EXT_TX && CONFIG_RECT_TX
5038 count4x4 += counts->tx_size_implied[0][TX_4X4];
5039 count4x4 += counts->tx_size_implied[1][TX_4X4];
5040 count4x4 += counts->tx_size_implied[2][TX_4X4];
5041 count4x4 += counts->tx_size_implied[3][TX_4X4];
5042 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5043 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5044 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5045 count8x8_lp += counts->tx_size_implied[4][TX_8X8];
5046 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5047 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5048 count16x16_lp += counts->tx_size_implied[4][TX_16X16];
5049 count32x32_32x32p += counts->tx_size_implied[3][TX_32X32];
5050 count32x32_lp += counts->tx_size_implied[4][TX_32X32];
Debargha Mukherjee5a488a62016-11-22 22:24:10 -08005051 count64x64_64x64p += counts->tx_size_implied[4][TX_64X64];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005052#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5053 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5054 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5055#if CONFIG_SUPERTX
5056 cm->counts.supertx_size[TX_16X16] == 0 &&
5057 cm->counts.supertx_size[TX_32X32] == 0 &&
5058 cm->counts.supertx_size[TX_64X64] == 0 &&
5059#endif
5060 count64x64_64x64p == 0) {
5061 cm->tx_mode = ALLOW_8X8;
5062 reset_skip_tx_size(cm, TX_8X8);
5063 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5064 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5065 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5066#if CONFIG_SUPERTX
5067 cm->counts.supertx_size[TX_8X8] == 0 &&
5068 cm->counts.supertx_size[TX_16X16] == 0 &&
5069 cm->counts.supertx_size[TX_32X32] == 0 &&
5070 cm->counts.supertx_size[TX_64X64] == 0 &&
5071#endif
5072 count64x64_64x64p == 0) {
5073 cm->tx_mode = ONLY_4X4;
5074 reset_skip_tx_size(cm, TX_4X4);
5075 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5076 count32x32_lp == 0) {
5077 cm->tx_mode = ALLOW_64X64;
5078 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5079#if CONFIG_SUPERTX
5080 cm->counts.supertx_size[TX_64X64] == 0 &&
5081#endif
5082 count64x64_64x64p == 0) {
5083 cm->tx_mode = ALLOW_32X32;
5084 reset_skip_tx_size(cm, TX_32X32);
5085 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5086 count32x32_32x32p == 0 &&
5087#if CONFIG_SUPERTX
5088 cm->counts.supertx_size[TX_32X32] == 0 &&
5089 cm->counts.supertx_size[TX_64X64] == 0 &&
5090#endif
5091 count64x64_64x64p == 0) {
5092 cm->tx_mode = ALLOW_16X16;
5093 reset_skip_tx_size(cm, TX_16X16);
5094 }
5095
5096#else // CONFIG_TX64X64
5097
Yaowu Xuc27fc142016-08-22 16:08:15 -07005098 int count4x4 = 0;
5099 int count8x8_lp = 0, count8x8_8x8p = 0;
5100 int count16x16_16x16p = 0, count16x16_lp = 0;
5101 int count32x32 = 0;
5102 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005103 // counts->tx_size[max_depth][context_idx][this_depth_level]
5104 count4x4 += counts->tx_size[0][i][0];
5105 count4x4 += counts->tx_size[1][i][0];
5106 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005107
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005108 count8x8_8x8p += counts->tx_size[0][i][1];
Jingning Han2adcfb12016-10-27 11:19:53 -07005109 count8x8_lp += counts->tx_size[1][i][1];
5110 count8x8_lp += counts->tx_size[2][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005111
Jingning Han2adcfb12016-10-27 11:19:53 -07005112 count16x16_16x16p += counts->tx_size[1][i][2];
5113 count16x16_lp += counts->tx_size[2][i][2];
5114 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005115 }
5116#if CONFIG_EXT_TX && CONFIG_RECT_TX
5117 count4x4 += counts->tx_size_implied[0][TX_4X4];
5118 count4x4 += counts->tx_size_implied[1][TX_4X4];
5119 count4x4 += counts->tx_size_implied[2][TX_4X4];
5120 count4x4 += counts->tx_size_implied[3][TX_4X4];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005121 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005122 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5123 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5125 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5126 count32x32 += counts->tx_size_implied[3][TX_32X32];
5127#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5128 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5129#if CONFIG_SUPERTX
5130 cm->counts.supertx_size[TX_16X16] == 0 &&
5131 cm->counts.supertx_size[TX_32X32] == 0 &&
5132#endif // CONFIG_SUPERTX
5133 count32x32 == 0) {
5134 cm->tx_mode = ALLOW_8X8;
5135 reset_skip_tx_size(cm, TX_8X8);
5136 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5137 count8x8_lp == 0 && count16x16_lp == 0 &&
5138#if CONFIG_SUPERTX
5139 cm->counts.supertx_size[TX_8X8] == 0 &&
5140 cm->counts.supertx_size[TX_16X16] == 0 &&
5141 cm->counts.supertx_size[TX_32X32] == 0 &&
5142#endif // CONFIG_SUPERTX
5143 count32x32 == 0) {
5144 cm->tx_mode = ONLY_4X4;
5145 reset_skip_tx_size(cm, TX_4X4);
5146 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5147 cm->tx_mode = ALLOW_32X32;
5148 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5149#if CONFIG_SUPERTX
5150 cm->counts.supertx_size[TX_32X32] == 0 &&
5151#endif // CONFIG_SUPERTX
5152 count4x4 == 0) {
5153 cm->tx_mode = ALLOW_16X16;
5154 reset_skip_tx_size(cm, TX_16X16);
5155 }
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005156#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07005157 }
5158#endif
5159 } else {
5160 encode_frame_internal(cpi);
5161 }
5162}
5163
5164static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5165 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
5166 const int intraonly) {
5167 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5168 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5169 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005170 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005171
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005172 if (bsize < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005173 int idx, idy;
5174 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5175 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5176 for (idy = 0; idy < 2; idy += num_4x4_h)
5177 for (idx = 0; idx < 2; idx += num_4x4_w) {
5178 const int bidx = idy * 2 + idx;
5179 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5180 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005181 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5182 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005183 ++counts->kf_y_mode[a][l][bmode];
5184 } else {
5185 ++counts->y_mode[0][bmode];
5186 }
5187 }
5188 } else {
5189 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005190 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5191 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005192 ++counts->kf_y_mode[above][left][y_mode];
5193 } else {
5194 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5195 }
5196 }
5197
5198 ++counts->uv_mode[y_mode][uv_mode];
5199}
5200
5201#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005202static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005203 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005204 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5206 const int tx_row = blk_row >> 1;
5207 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005208 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5209 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005211 xd->left_txfm_context + tx_row,
5212 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005213 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5214
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5216
5217 if (tx_size == plane_tx_size) {
5218 ++counts->txfm_partition[ctx][0];
5219 mbmi->tx_size = tx_size;
5220 txfm_partition_update(xd->above_txfm_context + tx_col,
5221 xd->left_txfm_context + tx_row, tx_size);
5222 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005223 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5224 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005225 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005226
Yaowu Xuc27fc142016-08-22 16:08:15 -07005227 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005228 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005229
5230 if (tx_size == TX_8X8) {
5231 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5232 mbmi->tx_size = TX_4X4;
5233 txfm_partition_update(xd->above_txfm_context + tx_col,
5234 xd->left_txfm_context + tx_row, TX_4X4);
5235 return;
5236 }
5237
5238 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005239 int offsetr = (i >> 1) * bs;
5240 int offsetc = (i & 0x01) * bs;
5241 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5242 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005243 }
5244 }
5245}
5246
Jingning Han9777afc2016-10-20 15:17:43 -07005247static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5248 BLOCK_SIZE plane_bsize, int mi_row,
5249 int mi_col, FRAME_COUNTS *td_counts) {
5250 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005251 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5252 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005253 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005254 const int bh = tx_size_high_unit[max_tx_size];
5255 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005256 int idx, idy;
5257
5258 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5259 xd->left_txfm_context =
5260 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5261
5262 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005263 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005264 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5265 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005266}
5267
5268static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5269 int blk_col) {
5270 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5271 const int tx_row = blk_row >> 1;
5272 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005273 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5274 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005275 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5276
Yaowu Xuc27fc142016-08-22 16:08:15 -07005277 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5278
5279 if (tx_size == plane_tx_size) {
5280 mbmi->tx_size = tx_size;
5281 txfm_partition_update(xd->above_txfm_context + tx_col,
5282 xd->left_txfm_context + tx_row, tx_size);
5283
5284 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005285 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5286 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005287 int i;
5288
5289 if (tx_size == TX_8X8) {
5290 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5291 mbmi->tx_size = TX_4X4;
5292 txfm_partition_update(xd->above_txfm_context + tx_col,
5293 xd->left_txfm_context + tx_row, TX_4X4);
5294 return;
5295 }
5296
5297 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005298 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005299 int offsetr = (i >> 1) * bsl;
5300 int offsetc = (i & 0x01) * bsl;
5301 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005302 }
5303 }
5304}
5305
Urvang Joshi52648442016-10-13 17:27:51 -07005306static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5307 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5308 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005309 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5310 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005311 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005312 const int bh = tx_size_high_unit[max_tx_size];
5313 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005314 int idx, idy;
5315
5316 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5317 xd->left_txfm_context =
5318 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5319
5320 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005321 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005322 set_txfm_context(xd, max_tx_size, idy, idx);
5323}
5324#endif
5325
Urvang Joshi52648442016-10-13 17:27:51 -07005326static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5327 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5328 int mi_col, BLOCK_SIZE bsize,
5329 PICK_MODE_CONTEXT *ctx, int *rate) {
5330 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005331 MACROBLOCK *const x = &td->mb;
5332 MACROBLOCKD *const xd = &x->e_mbd;
5333 MODE_INFO **mi_8x8 = xd->mi;
5334 MODE_INFO *mi = mi_8x8[0];
5335 MB_MODE_INFO *mbmi = &mi->mbmi;
5336 const int seg_skip =
5337 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5338 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08005339 const int mi_width = mi_size_wide[bsize];
5340 const int mi_height = mi_size_high[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005341 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005342#if CONFIG_CB4X4
5343 const int unify_bsize = 1;
5344 const BLOCK_SIZE block_size = bsize;
5345#else
5346 const int unify_bsize = 0;
5347 const BLOCK_SIZE block_size = AOMMAX(bsize, BLOCK_8X8);
5348#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005349
Yaowu Xuc27fc142016-08-22 16:08:15 -07005350 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5351
Yushin Cho77bba8d2016-11-04 16:36:56 -07005352#if CONFIG_PVQ
5353 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005354 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005355#endif
5356
Jingning Han94ea1aa2016-11-08 12:10:46 -08005357 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005358 int plane;
5359 mbmi->skip = 1;
5360 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005361 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005362 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005363 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5364 frame_is_intra_only(cm));
5365
hui su5db97432016-10-14 16:10:14 -07005366 // TODO(huisu): move this into sum_intra_stats().
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005367 if (!dry_run && (bsize >= BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005369 (void)counts;
5370#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005371 if (mbmi->mode == DC_PRED
5372#if CONFIG_PALETTE
5373 && mbmi->palette_mode_info.palette_size[0] == 0
5374#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005375 ) {
5376 const int use_filter_intra_mode =
5377 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5378 ++counts->filter_intra[0][use_filter_intra_mode];
5379 }
Urvang Joshib100db72016-10-12 16:28:56 -07005380 if (mbmi->uv_mode == DC_PRED
5381#if CONFIG_PALETTE
5382 && mbmi->palette_mode_info.palette_size[1] == 0
5383#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005384 ) {
5385 const int use_filter_intra_mode =
5386 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5387 ++counts->filter_intra[1][use_filter_intra_mode];
5388 }
5389#endif // CONFIG_FILTER_INTRA
5390#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08005391#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08005392 if (av1_is_directional_mode(mbmi->mode, bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005393 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005394 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -08005395 p_angle = mode_to_angle_map[mbmi->mode] +
5396 mbmi->angle_delta[0] * av1_get_angle_step(mbmi->sb_type, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005397 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005398 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5399 }
hui sueda3d762016-12-06 16:58:23 -08005400#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07005401#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005402 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005403
Urvang Joshib100db72016-10-12 16:28:56 -07005404#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005405 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005406 for (plane = 0; plane <= 1; ++plane) {
5407 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5408 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5409 xd->plane[plane].color_index_map[0];
5410 // TODO(huisu): this increases the use of token buffer. Needs stretch
5411 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005412 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005413 }
5414 }
5415 }
Urvang Joshib100db72016-10-12 16:28:56 -07005416#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005417#if CONFIG_VAR_TX
5418 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5419#endif
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005420 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005421 } else {
5422 int ref;
5423 const int is_compound = has_second_ref(mbmi);
5424
5425 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5426 for (ref = 0; ref < 1 + is_compound; ++ref) {
5427 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5428 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005429 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5430 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005431 }
Yue Chen69f18e12016-09-08 14:48:15 -07005432#if CONFIG_WARPED_MOTION
5433 if (mbmi->motion_mode == WARPED_CAUSAL) {
5434 int i;
5435#if CONFIG_AOM_HIGHBITDEPTH
5436 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
5437#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005438
Yue Chen69f18e12016-09-08 14:48:15 -07005439 for (i = 0; i < 3; ++i) {
5440 const struct macroblockd_plane *pd = &xd->plane[i];
5441
5442 av1_warp_plane(&mbmi->wm_params[0],
5443#if CONFIG_AOM_HIGHBITDEPTH
5444 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5445#endif // CONFIG_AOM_HIGHBITDEPTH
5446 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
5447 pd->pre[0].stride, pd->dst.buf,
5448 ((mi_col * MI_SIZE) >> pd->subsampling_x),
5449 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -08005450 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
5451 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
5452 pd->dst.stride, pd->subsampling_x, pd->subsampling_y, 16,
5453 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07005454 }
5455 } else {
5456#endif // CONFIG_WARPED_MOTION
5457 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005458 av1_build_inter_predictors_sby(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005459
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005460 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005461#if CONFIG_WARPED_MOTION
5462 }
5463#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005464
Yue Chencb60b182016-10-13 15:18:22 -07005465#if CONFIG_MOTION_VAR
5466 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005467 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005468 }
Yue Chencb60b182016-10-13 15:18:22 -07005469#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005470
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005471 av1_encode_sb((AV1_COMMON *)cm, x, block_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005472#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005473 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Hanfe45b212016-11-22 10:30:23 -08005474 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5475 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005476#else
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005477 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005478#endif
5479 }
5480
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005481 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005482#if CONFIG_VAR_TX
5483 TX_SIZE tx_size =
5484 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5485#else
5486 TX_SIZE tx_size = mbmi->tx_size;
5487#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005488 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
Jingning Han94ea1aa2016-11-08 12:10:46 -08005489 !(is_inter && (mbmi->skip || seg_skip))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005490 const int tx_size_ctx = get_tx_size_context(xd);
5491 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5492 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005493 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005494 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005495#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005496 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005497#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5498#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -08005499 if (is_inter) {
5500 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5501 } else {
5502 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5503 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Yue Chena1e48dc2016-08-29 17:29:33 -07005504 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005505#else
Jingning Han4e1737a2016-10-25 16:05:02 -07005506 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005507#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005508 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005509 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005510 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005511 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005512 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005514 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005515 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005516 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517 }
5518#if CONFIG_EXT_TX && CONFIG_RECT_TX
5519 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
Jingning Hane67b38a2016-11-04 10:30:00 -07005520 [txsize_sqr_up_map[tx_size]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005521#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5522 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005523 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005524 }
5525
Urvang Joshi454280d2016-10-14 16:51:44 -07005526 for (j = 0; j < mi_height; j++)
5527 for (i = 0; i < mi_width; i++)
5528 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005529 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005530
5531#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005532 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5533 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005534#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005535 }
Jingning Han9777afc2016-10-20 15:17:43 -07005536
Jingning Hane67b38a2016-11-04 10:30:00 -07005537 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005538 ++td->counts
5539 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005540#if CONFIG_EXT_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005541 if (get_ext_tx_types(tx_size, bsize, is_inter) > 1 && cm->base_qindex > 0 &&
5542 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005544 int eset = get_ext_tx_set(tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005545 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005546 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005547 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
Yaowu Xuc27fc142016-08-22 16:08:15 -07005548 [mbmi->tx_type];
5549 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005550 ++td->counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005551 }
5552 }
5553 }
5554#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005555 if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005556 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005557 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005558 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005559 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005560 ++td->counts->intra_ext_tx[tx_size]
clang-format67948d32016-09-07 22:40:40 -07005561 [intra_mode_to_tx_type_context[mbmi->mode]]
5562 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005563 }
5564 }
5565#endif // CONFIG_EXT_TX
5566 }
5567
5568#if CONFIG_VAR_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005569 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 && is_inter &&
5570 !(mbmi->skip || seg_skip)) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005571 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005572 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005573 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005574 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005575 if (is_inter)
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005576 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577 else
Jingning Hane67b38a2016-11-04 10:30:00 -07005578 tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005579 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005580 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005582#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583}
5584
5585#if CONFIG_SUPERTX
5586static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5587 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5588#if CONFIG_EXT_INTER
5589 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5590#endif // CONFIG_EXT_INTER
5591 return 0;
5592}
5593
Urvang Joshi52648442016-10-13 17:27:51 -07005594static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5595 int mi_row, int mi_col, BLOCK_SIZE bsize,
5596 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005597 const AV1_COMMON *const cm = &cpi->common;
Jingning Han1856e432016-12-21 14:58:39 -08005598 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599 const PARTITION_TYPE partition = pc_tree->partitioning;
5600 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5601#if CONFIG_EXT_PARTITION_TYPES
5602 int i;
5603#endif
Jingning Hanfeb517c2016-12-21 16:02:07 -08005604#if CONFIG_CB4X4
5605 const int unify_bsize = 1;
5606#else
5607 const int unify_bsize = 0;
5608#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005609
Jingning Hanfeb517c2016-12-21 16:02:07 -08005610#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08005612#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613
5614 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5615
5616 switch (partition) {
5617 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5618 case PARTITION_VERT:
5619 if (check_intra_b(&pc_tree->vertical[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005620 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005621 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5622 }
5623 break;
5624 case PARTITION_HORZ:
5625 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005626 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005627 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5628 }
5629 break;
5630 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08005631 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005632 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5633 } else {
5634 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5635 pc_tree->split[0]))
5636 return 1;
5637 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5638 pc_tree->split[1]))
5639 return 1;
5640 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5641 pc_tree->split[2]))
5642 return 1;
5643 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5644 pc_tree->split[3]))
5645 return 1;
5646 }
5647 break;
5648#if CONFIG_EXT_PARTITION_TYPES
5649 case PARTITION_HORZ_A:
5650 for (i = 0; i < 3; i++) {
5651 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5652 }
5653 break;
5654 case PARTITION_HORZ_B:
5655 for (i = 0; i < 3; i++) {
5656 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5657 }
5658 break;
5659 case PARTITION_VERT_A:
5660 for (i = 0; i < 3; i++) {
5661 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5662 }
5663 break;
5664 case PARTITION_VERT_B:
5665 for (i = 0; i < 3; i++) {
5666 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5667 }
5668 break;
5669#endif // CONFIG_EXT_PARTITION_TYPES
5670 default: assert(0);
5671 }
5672 return 0;
5673}
5674
5675static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5676 return ctx->mic.mbmi.tx_size == supertx_size;
5677}
5678
5679static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5680 PC_TREE *pc_tree) {
5681 PARTITION_TYPE partition;
5682 BLOCK_SIZE subsize;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005683#if CONFIG_CB4X4
5684 const int unify_bsize = 1;
5685#else
5686 const int unify_bsize = 0;
5687#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005688
5689 partition = pc_tree->partitioning;
5690 subsize = get_subsize(bsize, partition);
5691 switch (partition) {
5692 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5693 case PARTITION_VERT:
5694 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5695 case PARTITION_HORZ:
5696 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5697 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08005698 if (bsize == BLOCK_8X8 && !unify_bsize)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005699 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5700 else
5701 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5702#if CONFIG_EXT_PARTITION_TYPES
5703 case PARTITION_HORZ_A:
5704 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5705 case PARTITION_HORZ_B:
5706 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5707 case PARTITION_VERT_A:
5708 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5709 case PARTITION_VERT_B:
5710 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5711#endif // CONFIG_EXT_PARTITION_TYPES
5712 default: assert(0); return 0;
5713 }
5714}
5715
Urvang Joshi52648442016-10-13 17:27:51 -07005716static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005717#if CONFIG_EXT_INTER
5718 int mi_row_ori, int mi_col_ori,
5719#endif // CONFIG_EXT_INTER
5720 int mi_row_pred, int mi_col_pred,
5721 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5722 // Used in supertx
5723 // (mi_row_ori, mi_col_ori): location for mv
5724 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005725 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726 MACROBLOCK *const x = &td->mb;
5727 MACROBLOCKD *const xd = &x->e_mbd;
5728 MODE_INFO *mi_8x8 = xd->mi[0];
5729 MODE_INFO *mi = mi_8x8;
5730 MB_MODE_INFO *mbmi = &mi->mbmi;
5731 int ref;
5732 const int is_compound = has_second_ref(mbmi);
5733
5734 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5735
5736 for (ref = 0; ref < 1 + is_compound; ++ref) {
5737 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005738 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5739 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005740 }
5741
5742 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005743 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005744#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005745 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005746#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005747 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005748 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005749 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005750#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005751 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005752#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005753 mi_row_pred, mi_col_pred,
5754 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005755}
5756
Urvang Joshi52648442016-10-13 17:27:51 -07005757static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005758 const TileInfo *const tile, int block,
5759 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5760 int mi_col_pred, int mi_row_top, int mi_col_top,
5761 uint8_t *dst_buf[3], int dst_stride[3],
5762 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005763 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764 // Used in supertx
5765 // (mi_row_ori, mi_col_ori): location for mv
5766 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5767 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5768 // block: sub location of sub8x8 blocks
5769 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5770 // bextend: 1: region to predict is an extension of ori; 0: not
5771
5772 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005773 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005774 MACROBLOCKD *const xd = &x->e_mbd;
5775 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5776 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
Jingning Han1856e432016-12-21 14:58:39 -08005777 const int mi_width_top = mi_size_wide[bsize_top];
5778 const int mi_height_top = mi_size_high[bsize_top];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005779
5780 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5781 mi_row_pred >= mi_row_top + mi_height_top ||
5782 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5783 mi_col_pred >= cm->mi_cols)
5784 return;
5785
5786 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5787 mi_col_ori, bsize_pred);
5788 xd->plane[0].dst.stride = dst_stride[0];
5789 xd->plane[1].dst.stride = dst_stride[1];
5790 xd->plane[2].dst.stride = dst_stride[2];
5791 xd->plane[0].dst.buf = dst_buf[0] +
5792 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5793 (c >> xd->plane[0].subsampling_x);
5794 xd->plane[1].dst.buf = dst_buf[1] +
5795 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5796 (c >> xd->plane[1].subsampling_x);
5797 xd->plane[2].dst.buf = dst_buf[2] +
5798 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5799 (c >> xd->plane[2].subsampling_x);
5800
5801 predict_superblock(cpi, td,
5802#if CONFIG_EXT_INTER
5803 mi_row_ori, mi_col_ori,
5804#endif // CONFIG_EXT_INTER
5805 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5806
Jingning Hanfc0476d2016-12-21 14:43:16 -08005807 if (!dry_run && !bextend)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005808 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809}
5810
Urvang Joshi52648442016-10-13 17:27:51 -07005811static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005812 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5813 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005814 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005815 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5816 // dir: 0-lower, 1-upper, 2-left, 3-right
5817 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5818 MACROBLOCKD *xd = &td->mb.e_mbd;
Jingning Han1856e432016-12-21 14:58:39 -08005819 const int mi_width = mi_size_wide[bsize];
5820 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821 int xss = xd->plane[1].subsampling_x;
5822 int yss = xd->plane[1].subsampling_y;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005823#if CONFIG_CB4X4
5824 const int unify_bsize = 1;
5825#else
5826 const int unify_bsize = 0;
5827#endif
5828 int b_sub8x8 = (bsize < BLOCK_8X8) && !unify_bsize ? 1 : 0;
Jingning Han24f24a52016-12-27 10:13:28 -08005829 int wide_unit, high_unit;
5830 int i, j;
5831 int ext_offset = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005832
5833 BLOCK_SIZE extend_bsize;
Jingning Han24f24a52016-12-27 10:13:28 -08005834 int mi_row_pred, mi_col_pred;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005835
5836 if (dir == 0 || dir == 1) { // lower and upper
Jingning Han1856e432016-12-21 14:58:39 -08005837 extend_bsize =
5838 (mi_width == mi_size_wide[BLOCK_8X8] || bsize < BLOCK_8X8 || xss < yss)
5839 ? BLOCK_8X8
5840 : BLOCK_16X8;
Jingning Han24f24a52016-12-27 10:13:28 -08005841
5842#if CONFIG_CB4X4
5843 if (bsize < BLOCK_8X8) {
5844 extend_bsize = BLOCK_4X4;
5845 ext_offset = mi_size_wide[BLOCK_8X8];
5846 }
5847#endif
5848 wide_unit = mi_size_wide[extend_bsize];
5849 high_unit = mi_size_high[extend_bsize];
5850
5851 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -(mi_height + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005852 mi_col_pred = mi_col;
5853
Jingning Han24f24a52016-12-27 10:13:28 -08005854 for (j = 0; j < mi_height + ext_offset; j += high_unit)
5855 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
5856 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
5857 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005858 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5859 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005860 } else if (dir == 2 || dir == 3) { // left and right
Jingning Han1856e432016-12-21 14:58:39 -08005861 extend_bsize =
5862 (mi_height == mi_size_high[BLOCK_8X8] || bsize < BLOCK_8X8 || yss < xss)
5863 ? BLOCK_8X8
5864 : BLOCK_8X16;
Jingning Han24f24a52016-12-27 10:13:28 -08005865#if CONFIG_CB4X4
5866 if (bsize < BLOCK_8X8) {
5867 extend_bsize = BLOCK_4X4;
5868 ext_offset = mi_size_wide[BLOCK_8X8];
5869 }
5870#endif
5871 wide_unit = mi_size_wide[extend_bsize];
5872 high_unit = mi_size_high[extend_bsize];
5873
Yaowu Xuc27fc142016-08-22 16:08:15 -07005874 mi_row_pred = mi_row;
Jingning Han24f24a52016-12-27 10:13:28 -08005875 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -(mi_width + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876
Jingning Han24f24a52016-12-27 10:13:28 -08005877 for (j = 0; j < mi_height + ext_offset; j += high_unit)
5878 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
5879 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
5880 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005881 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5882 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005883 } else {
5884 extend_bsize = BLOCK_8X8;
Jingning Han24f24a52016-12-27 10:13:28 -08005885#if CONFIG_CB4X4
5886 if (bsize < BLOCK_8X8) {
5887 extend_bsize = BLOCK_4X4;
5888 ext_offset = mi_size_wide[BLOCK_8X8];
5889 }
5890#endif
5891 wide_unit = mi_size_wide[extend_bsize];
5892 high_unit = mi_size_high[extend_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005893
Jingning Han24f24a52016-12-27 10:13:28 -08005894 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height
5895 : -(mi_height + ext_offset));
5896 mi_col_pred =
5897 mi_col + ((dir == 6 || dir == 7) ? mi_width : -(mi_width + ext_offset));
5898
5899 for (j = 0; j < mi_height + ext_offset; j += high_unit)
5900 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
5901 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
5902 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
5903 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5904 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005905 }
5906}
5907
Urvang Joshi52648442016-10-13 17:27:51 -07005908static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005909 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5910 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005911 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005912 uint8_t *dst_buf[3], int dst_stride[3]) {
5913 assert(block >= 0 && block < 4);
5914 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005915 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005916 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005917 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005919 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005920 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005921 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005922 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005923 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005925 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005927 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005928 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005929 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005930}
5931
5932// This function generates prediction for multiple blocks, between which
5933// discontinuity around boundary is reduced by smoothing masks. The basic
5934// smoothing mask is a soft step function along horz/vert direction. In more
5935// complicated case when a block is split into 4 subblocks, the basic mask is
5936// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5937// then applied to the 2 masked prediction mentioned above in vertical direction
5938// If the block is split into more than one level, at every stage, masked
5939// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005940static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005941 const TileInfo *const tile, int mi_row,
5942 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005943 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005944 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5945 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005946 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005947 MACROBLOCK *const x = &td->mb;
5948 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005949 const int is_partition_root = bsize >= BLOCK_8X8;
5950 const int ctx = is_partition_root
5951 ? partition_plane_context(xd, mi_row, mi_col, bsize)
5952 : 0;
Jingning Han1856e432016-12-21 14:58:39 -08005953 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954 const PARTITION_TYPE partition = pc_tree->partitioning;
5955 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5956#if CONFIG_EXT_PARTITION_TYPES
5957 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5958#endif
5959
5960 int i;
5961 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
5962 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5963 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5964 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5965 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5966 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5967 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
Jingning Hanfeb517c2016-12-21 16:02:07 -08005968#if CONFIG_CB4X4
5969 const int unify_bsize = 1;
5970#else
5971 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005972 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08005973#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005974
5975 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
5976
Yaowu Xuf883b422016-08-30 14:01:10 -07005977#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5979 int len = sizeof(uint16_t);
5980 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5981 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
5982 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
5983 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5984 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
5985 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
5986 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
5987 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
5988 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
5989 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005990#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005991 dst_buf1[0] = tmp_buf1;
5992 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
5993 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
5994 dst_buf2[0] = tmp_buf2;
5995 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
5996 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
5997 dst_buf3[0] = tmp_buf3;
5998 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
5999 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006000#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006001 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006002#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003
Jingning Hanfeb517c2016-12-21 16:02:07 -08006004 if (!dry_run && is_partition_root && bsize < top_bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -07006005 // Explicitly cast away const.
6006 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6007 frame_counts->partition[ctx][partition]++;
6008 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006009
6010 for (i = 0; i < MAX_MB_PLANE; i++) {
6011 xd->plane[i].dst.buf = dst_buf[i];
6012 xd->plane[i].dst.stride = dst_stride[i];
6013 }
6014
6015 switch (partition) {
6016 case PARTITION_NONE:
6017 assert(bsize < top_bsize);
6018 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6019 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006020 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006022 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006023 break;
6024 case PARTITION_HORZ:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006025 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006026 // Fisrt half
6027 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6028 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006029 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006030 if (bsize < top_bsize)
6031 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006032 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006033
6034 // Second half
6035 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6036 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006037 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006038 if (bsize < top_bsize)
6039 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006040 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006041
6042 // Smooth
6043 xd->plane[0].dst.buf = dst_buf[0];
6044 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006045 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006046 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6047 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6048 0);
6049 } else {
6050 // First half
6051 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6052 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006053 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006054 if (bsize < top_bsize)
6055 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006056 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057 else
6058 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006059 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060
6061 if (mi_row + hbs < cm->mi_rows) {
6062 // Second half
6063 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6064 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006065 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006066 if (bsize < top_bsize)
6067 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006068 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006069 dst_stride1);
6070 else
6071 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006072 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006073 dst_stride1, 1);
6074
6075 // Smooth
6076 for (i = 0; i < MAX_MB_PLANE; i++) {
6077 xd->plane[i].dst.buf = dst_buf[i];
6078 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006079 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006080 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6081 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6082 PARTITION_HORZ, i);
6083 }
6084 }
6085 }
6086 break;
6087 case PARTITION_VERT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006088 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006089 // First half
6090 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6091 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006092 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006093 if (bsize < top_bsize)
6094 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006095 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006096
6097 // Second half
6098 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6099 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006100 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006101 if (bsize < top_bsize)
6102 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006103 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006104
6105 // Smooth
6106 xd->plane[0].dst.buf = dst_buf[0];
6107 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006108 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006109 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6110 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6111 0);
6112 } else {
6113 // bsize: not important, not useful
6114 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6115 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006116 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 if (bsize < top_bsize)
6118 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006119 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006120 else
6121 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006122 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123
6124 if (mi_col + hbs < cm->mi_cols) {
6125 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6126 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006127 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006128 if (bsize < top_bsize)
6129 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006130 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6131 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006132 else
6133 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006134 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6135 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006136
6137 for (i = 0; i < MAX_MB_PLANE; i++) {
6138 xd->plane[i].dst.buf = dst_buf[i];
6139 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006140 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006141 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6142 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6143 PARTITION_VERT, i);
6144 }
6145 }
6146 }
6147 break;
6148 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006149 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006150 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6151 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006152 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6154 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006155 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006156 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6157 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006158 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6160 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006161 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006162
6163 if (bsize < top_bsize) {
6164 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006165 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006166 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006167 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006169 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006170 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006171 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006172 }
6173 } else {
6174 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006175 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6176 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006177 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6178 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006179 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6180 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006181 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6182 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006183 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6184 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006185 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6186 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006187 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006188 top_bsize, dst_buf3, dst_stride3,
6189 pc_tree->split[3]);
6190 }
6191 for (i = 0; i < MAX_MB_PLANE; i++) {
Jingning Han9e0976a2016-12-27 17:52:42 -08006192#if !CONFIG_CB4X4
Jingning Han24f24a52016-12-27 10:13:28 -08006193 if (bsize == BLOCK_8X8 && i != 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006194 continue; // Skip <4x4 chroma smoothing
Jingning Han9e0976a2016-12-27 17:52:42 -08006195#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006197 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6199 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6200 PARTITION_VERT, i);
6201 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006202 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6204 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6205 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006206 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006207 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6208 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6209 PARTITION_HORZ, i);
6210 }
6211 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Jingning Han24f24a52016-12-27 10:13:28 -08006212 if (bsize == BLOCK_8X8 && i != 0)
6213 continue; // Skip <4x4 chroma smoothing
6214
Yaowu Xuf883b422016-08-30 14:01:10 -07006215 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006216 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6217 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6218 PARTITION_HORZ, i);
6219 }
6220 }
6221 break;
6222#if CONFIG_EXT_PARTITION_TYPES
6223 case PARTITION_HORZ_A:
6224 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6225 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006226 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006228 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006229
6230 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6231 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006232 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006233 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006234 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006235
6236 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6237 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006238 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006239 if (bsize < top_bsize)
6240 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006241 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006242 else
6243 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006244 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006245
6246 for (i = 0; i < MAX_MB_PLANE; i++) {
6247 xd->plane[i].dst.buf = dst_buf[i];
6248 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006249 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006250 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6251 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6252 i);
6253 }
6254 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006255 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006256 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6257 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6258 i);
6259 }
6260
6261 break;
6262 case PARTITION_VERT_A:
6263
6264 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6265 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006266 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006267 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006268 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006269
6270 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6271 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006272 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006273 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006274 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006275
6276 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6277 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006278 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 if (bsize < top_bsize)
6280 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006281 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006282 else
6283 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006284 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006285
6286 for (i = 0; i < MAX_MB_PLANE; i++) {
6287 xd->plane[i].dst.buf = dst_buf[i];
6288 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006289 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006290 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6291 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6292 i);
6293 }
6294 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006295 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006296 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6297 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6298 i);
6299 }
6300 break;
6301 case PARTITION_HORZ_B:
6302
6303 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6304 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006305 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006306 if (bsize < top_bsize)
6307 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006308 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006309 else
6310 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006311 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006312
6313 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6314 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006315 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006317 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006318
6319 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6320 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006321 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006322 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006323 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006324 dst_stride2);
6325
6326 for (i = 0; i < MAX_MB_PLANE; i++) {
6327 xd->plane[i].dst.buf = dst_buf1[i];
6328 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006329 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006330 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6331 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6332 PARTITION_VERT, i);
6333 }
6334 for (i = 0; i < MAX_MB_PLANE; i++) {
6335 xd->plane[i].dst.buf = dst_buf[i];
6336 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006337 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006338 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6339 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6340 i);
6341 }
6342 break;
6343 case PARTITION_VERT_B:
6344
6345 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6346 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006347 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006348 if (bsize < top_bsize)
6349 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006350 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006351 else
6352 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006353 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354
6355 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6356 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006357 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006358 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006359 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006360
6361 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6362 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006363 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006364 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006365 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006366 dst_stride2);
6367
6368 for (i = 0; i < MAX_MB_PLANE; i++) {
6369 xd->plane[i].dst.buf = dst_buf1[i];
6370 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006371 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006372 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6373 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6374 PARTITION_HORZ, i);
6375 }
6376 for (i = 0; i < MAX_MB_PLANE; i++) {
6377 xd->plane[i].dst.buf = dst_buf[i];
6378 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006379 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006380 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6381 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6382 i);
6383 }
6384 break;
6385#endif // CONFIG_EXT_PARTITION_TYPES
6386 default: assert(0);
6387 }
6388
6389#if CONFIG_EXT_PARTITION_TYPES
6390 if (bsize < top_bsize)
6391 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6392#else
6393 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6394 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6395#endif // CONFIG_EXT_PARTITION_TYPES
6396}
6397
Urvang Joshi52648442016-10-13 17:27:51 -07006398static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006399 const TileInfo *const tile, int mi_row, int mi_col,
6400 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6401 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006402 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006403 MACROBLOCK *const x = &td->mb;
6404 MACROBLOCKD *const xd = &x->e_mbd;
6405 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6406 base_rate = *tmp_rate;
6407 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6408 uint8_t *dst_buf[3];
6409 int dst_stride[3];
6410 TX_SIZE tx_size;
6411 MB_MODE_INFO *mbmi;
6412 TX_TYPE tx_type, best_tx_nostx;
6413#if CONFIG_EXT_TX
6414 int ext_tx_set;
6415#endif // CONFIG_EXT_TX
6416 int tmp_rate_tx = 0, skip_tx = 0;
6417 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6418
6419 set_skip_context(xd, mi_row, mi_col);
6420 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006421 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006422 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006423 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6424 dst_buf[plane] = xd->plane[plane].dst.buf;
6425 dst_stride[plane] = xd->plane[plane].dst.stride;
6426 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006427 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006428 bsize, dst_buf, dst_stride, pc_tree);
6429
6430 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6431 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6432
6433 mbmi = &xd->mi[0]->mbmi;
6434 best_tx_nostx = mbmi->tx_type;
6435
6436 *best_tx = DCT_DCT;
6437
6438 // chroma
6439 skippable_uv = 1;
6440 rate_uv = 0;
6441 dist_uv = 0;
6442 sse_uv = 0;
6443 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6444#if CONFIG_VAR_TX
6445 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6446 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6447 const struct macroblockd_plane *const pd = &xd->plane[plane];
6448 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006449 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006450 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006451
6452 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006453 tx_size =
6454 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006455 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006456 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6457
Yaowu Xuf883b422016-08-30 14:01:10 -07006458 av1_subtract_plane(x, bsize, plane);
6459 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006460 get_plane_block_size(bsize, pd), coeff_ctx,
6461 &this_rd_stats);
6462
6463 this_rate = this_rd_stats.rate;
6464 this_dist = this_rd_stats.dist;
6465 pnsse = this_rd_stats.sse;
6466 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006467#else
6468 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006469 tx_size =
6470 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006471 av1_subtract_plane(x, bsize, plane);
6472 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6473 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006474#endif // CONFIG_VAR_TX
6475
6476 rate_uv += this_rate;
6477 dist_uv += this_dist;
6478 sse_uv += pnsse;
6479 skippable_uv &= pnskip;
6480 }
6481
6482 // luma
6483 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006484 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006485#if CONFIG_EXT_TX
6486 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6487#endif // CONFIG_EXT_TX
6488 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6489#if CONFIG_VAR_TX
6490 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6491 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6492 const struct macroblockd_plane *const pd = &xd->plane[0];
6493 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006494 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006495#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006496
Yaowu Xuc27fc142016-08-22 16:08:15 -07006497#if CONFIG_EXT_TX
6498 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6499#else
6500 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6501#endif // CONFIG_EXT_TX
6502 mbmi->tx_type = tx_type;
6503
6504#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006505 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006506
Yaowu Xuf883b422016-08-30 14:01:10 -07006507 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006508 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006509 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6510 &this_rd_stats);
6511
6512 this_rate = this_rd_stats.rate;
6513 this_dist = this_rd_stats.dist;
6514 pnsse = this_rd_stats.sse;
6515 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006516#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006517 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6518 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006519#endif // CONFIG_VAR_TX
6520
6521#if CONFIG_EXT_TX
6522 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6523 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6524 if (ext_tx_set > 0)
6525 this_rate +=
6526 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6527 }
6528#else
6529 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6530 this_rate != INT_MAX) {
6531 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6532 }
6533#endif // CONFIG_EXT_TX
6534 *tmp_rate = rate_uv + this_rate;
6535 *tmp_dist = dist_uv + this_dist;
6536 sse = sse_uv + pnsse;
6537 skippable = skippable_uv && pnskip;
6538 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006539 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540 x->skip = 1;
6541 } else {
6542 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6543 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006544 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006545 x->skip = 0;
6546 } else {
6547 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006548 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006549 x->skip = 1;
6550 }
6551 }
6552 *tmp_rate += base_rate;
6553 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6554 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6555 *best_tx = tx_type;
6556 bestrd_tx = rd_tx;
6557 tmp_rate_tx = *tmp_rate;
6558 tmp_dist_tx = *tmp_dist;
6559 skip_tx = x->skip;
6560 }
6561 }
6562 *tmp_rate = tmp_rate_tx;
6563 *tmp_dist = tmp_dist_tx;
6564 x->skip = skip_tx;
6565#if CONFIG_VAR_TX
6566 for (plane = 0; plane < 1; ++plane)
6567 memset(x->blk_skip[plane], x->skip,
6568 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6569#endif // CONFIG_VAR_TX
6570 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6571}
6572#endif // CONFIG_SUPERTX