blob: 545a95d0d7d2f297d4f73b9c9d14ecbe9167c394 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./av1_rtcd.h"
17#include "./aom_dsp_rtcd.h"
18#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom_dsp/aom_dsp_common.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "aom_ports/mem.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070022#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "aom_ports/system_state.h"
24
25#include "av1/common/common.h"
26#include "av1/common/entropy.h"
27#include "av1/common/entropymode.h"
28#include "av1/common/idct.h"
29#include "av1/common/mvref_common.h"
30#include "av1/common/pred_common.h"
31#include "av1/common/quant_common.h"
32#include "av1/common/reconintra.h"
33#include "av1/common/reconinter.h"
34#include "av1/common/seg_common.h"
35#include "av1/common/tile_common.h"
36
37#include "av1/encoder/aq_complexity.h"
38#include "av1/encoder/aq_cyclicrefresh.h"
39#include "av1/encoder/aq_variance.h"
40#if CONFIG_SUPERTX
41#include "av1/encoder/cost.h"
42#endif
Yue Chen69f18e12016-09-08 14:48:15 -070043#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -070044#include "av1/common/warped_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070045#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
46#if CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/encoder/global_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070048#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070049#include "av1/encoder/encodeframe.h"
50#include "av1/encoder/encodemb.h"
51#include "av1/encoder/encodemv.h"
52#include "av1/encoder/ethread.h"
53#include "av1/encoder/extend.h"
54#include "av1/encoder/rd.h"
55#include "av1/encoder/rdopt.h"
56#include "av1/encoder/segmentation.h"
57#include "av1/encoder/tokenize.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070058#if CONFIG_PVQ
Yushin Cho70669122016-12-08 09:53:14 -100059#include "av1/common/pvq.h"
Yushin Cho77bba8d2016-11-04 16:36:56 -070060#include "av1/encoder/pvq_encoder.h"
61#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070062#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070063#define IF_HBD(...) __VA_ARGS__
64#else
65#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070066#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070067
Urvang Joshi52648442016-10-13 17:27:51 -070068static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
69 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
70 int mi_col, BLOCK_SIZE bsize,
71 PICK_MODE_CONTEXT *ctx, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070072
73#if CONFIG_SUPERTX
74static int check_intra_b(PICK_MODE_CONTEXT *ctx);
75
Urvang Joshi52648442016-10-13 17:27:51 -070076static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
77 int mi_row, int mi_col, BLOCK_SIZE bsize,
78 PC_TREE *pc_tree);
79static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070080#if CONFIG_EXT_INTER
81 int mi_row_ori, int mi_col_ori,
82#endif // CONFIG_EXT_INTER
83 int mi_row_pred, int mi_col_pred,
84 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
85static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
86 PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070087static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 const TileInfo *const tile, int mi_row,
89 int mi_col, int mi_row_ori, int mi_col_ori,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070090 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
92 int dst_stride[3], PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070093static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070094 const TileInfo *const tile, int mi_row,
95 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070096 RUN_TYPE dry_run, PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070097static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070098 const TileInfo *const tile, int mi_row, int mi_col,
99 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
100 TX_TYPE *best_tx, PC_TREE *pc_tree);
101#endif // CONFIG_SUPERTX
102
103// This is used as a reference when computing the source variance for the
104// purposes of activity masking.
105// Eventually this should be replaced by custom no-reference routines,
106// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700107static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700108 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
109 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
110 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
111 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
113#if CONFIG_EXT_PARTITION
114 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
116 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
117 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
118 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
119#endif // CONFIG_EXT_PARTITION
120};
121
Yaowu Xuf883b422016-08-30 14:01:10 -0700122#if CONFIG_AOM_HIGHBITDEPTH
123static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
125 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
126 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
127 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
129#if CONFIG_EXT_PARTITION
130 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
131 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
132 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
133 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
134 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
135#endif // CONFIG_EXT_PARTITION
136};
137
Yaowu Xuf883b422016-08-30 14:01:10 -0700138static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700139 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
140 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
141 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
142 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
143 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
144 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
145 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
146 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
147#if CONFIG_EXT_PARTITION
148 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
149 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
150 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
151 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
152 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
153 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
154 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
155 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
156#endif // CONFIG_EXT_PARTITION
157};
158
Yaowu Xuf883b422016-08-30 14:01:10 -0700159static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
161 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
162 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
163 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
164 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
165 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
166 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
167 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
168 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
169 128 * 16,
170#if CONFIG_EXT_PARTITION
171 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
172 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
173 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
174 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
175 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
176 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
177 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
178 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
179 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
180 128 * 16
181#endif // CONFIG_EXT_PARTITION
182};
Yaowu Xuf883b422016-08-30 14:01:10 -0700183#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700184
Urvang Joshi52648442016-10-13 17:27:51 -0700185unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700186 const struct buf_2d *ref,
187 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700188 unsigned int sse;
189 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700190 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700191 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
192}
193
Yaowu Xuf883b422016-08-30 14:01:10 -0700194#if CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700195unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700196 const struct buf_2d *ref,
197 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700198 unsigned int var, sse;
199 switch (bd) {
200 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700201 var =
202 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
203 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 break;
205 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700206 var =
207 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
208 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700209 break;
210 case 8:
211 default:
212 var =
213 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700214 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700215 break;
216 }
217 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
218}
Yaowu Xuf883b422016-08-30 14:01:10 -0700219#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700220
Urvang Joshi52648442016-10-13 17:27:51 -0700221static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 const struct buf_2d *ref,
223 int mi_row, int mi_col,
224 BLOCK_SIZE bs) {
225 unsigned int sse, var;
226 uint8_t *last_y;
227 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
228
229 assert(last != NULL);
230 last_y =
231 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
232 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
233 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
234}
235
Yaowu Xuf883b422016-08-30 14:01:10 -0700236static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
237 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700238 unsigned int var = get_sby_perpixel_diff_variance(
239 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
240 if (var < 8)
241 return BLOCK_64X64;
242 else if (var < 128)
243 return BLOCK_32X32;
244 else if (var < 2048)
245 return BLOCK_16X16;
246 else
247 return BLOCK_8X8;
248}
249
250// Lighter version of set_offsets that only sets the mode info
251// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700252static void set_mode_info_offsets(const AV1_COMP *const cpi,
253 MACROBLOCK *const x, MACROBLOCKD *const xd,
254 int mi_row, int mi_col) {
255 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256 const int idx_str = xd->mi_stride * mi_row + mi_col;
257 xd->mi = cm->mi_grid_visible + idx_str;
258 xd->mi[0] = cm->mi + idx_str;
259 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
260}
261
Urvang Joshi52648442016-10-13 17:27:51 -0700262static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263 const TileInfo *const tile,
264 MACROBLOCK *const x, int mi_row,
265 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700266 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800268 const int mi_width = mi_size_wide[bsize];
269 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700270
271 set_skip_context(xd, mi_row, mi_col);
272
273 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
274
275#if CONFIG_VAR_TX
276 xd->above_txfm_context = cm->above_txfm_context + mi_col;
277 xd->left_txfm_context =
278 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
279 xd->max_tx_size = max_txsize_lookup[bsize];
280#endif
281
282 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700283 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700284
285 // Set up limit values for MV components.
286 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700287 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
288 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
289 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
290 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700291
Jingning Hanfaad0e12016-12-07 10:54:57 -0800292 set_plane_n4(xd, mi_width, mi_height);
Jingning Hana6923f72016-07-15 08:50:14 -0700293
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294 // Set up distance of MB to edge of frame in 1/8th pel units.
295 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800296#if CONFIG_DEPENDENT_HORZTILES
297 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
298 cm->mi_cols, cm->dependent_horz_tiles);
299#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
301 cm->mi_cols);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800302#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700303
304 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700305 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306
307 // R/D setup.
308 x->rddiv = cpi->rd.RDDIV;
309 x->rdmult = cpi->rd.RDMULT;
310
Yaowu Xuf883b422016-08-30 14:01:10 -0700311 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 xd->tile = *tile;
313}
314
Urvang Joshi52648442016-10-13 17:27:51 -0700315static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700316 MACROBLOCK *const x, int mi_row, int mi_col,
317 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700318 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700319 MACROBLOCKD *const xd = &x->e_mbd;
320 MB_MODE_INFO *mbmi;
321 const struct segmentation *const seg = &cm->seg;
322
323 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
324
325 mbmi = &xd->mi[0]->mbmi;
326
327 // Setup segment ID.
328 if (seg->enabled) {
329 if (!cpi->vaq_refresh) {
330 const uint8_t *const map =
331 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
332 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
333 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700334 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700335 } else {
336 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700337 }
338
339#if CONFIG_SUPERTX
340 mbmi->segment_id_supertx = MAX_SEGMENTS;
341#endif // CONFIG_SUPERTX
342}
343
344#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700345static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 const TileInfo *const tile, int mi_row,
347 int mi_col, BLOCK_SIZE bsize) {
348 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700349 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800351 const int mi_width = mi_size_wide[bsize];
352 const int mi_height = mi_size_high[bsize];
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800353#if CONFIG_DEPENDENT_HORZTILES
354 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col, cm->dependent_horz_tiles);
355#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700356 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800357#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700358
359 // Set up distance of MB to edge of frame in 1/8th pel units.
360 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
361 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
362 cm->mi_cols);
363}
364
Urvang Joshi52648442016-10-13 17:27:51 -0700365static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 const TileInfo *const tile, int mi_row_pred,
367 int mi_col_pred, int mi_row_ori, int mi_col_ori,
368 BLOCK_SIZE bsize_pred) {
369 // Used in supertx
370 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
371 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
372 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700373 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700374 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Han5b7706a2016-12-21 09:55:10 -0800375 const int mi_width = mi_size_wide[bsize_pred];
376 const int mi_height = mi_size_high[bsize_pred];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700377
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800378#if CONFIG_DEPENDENT_HORZTILES
379 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori,
380 cm->dependent_horz_tiles);
381#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700382 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800383#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700384
385 // Set up limit values for MV components.
386 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700387 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
388 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
389 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
390 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700391
Jingning Hanfeb517c2016-12-21 16:02:07 -0800392// Set up distance of MB to edge of frame in 1/8th pel units.
393#if !CONFIG_CB4X4
Jingning Han5b7706a2016-12-21 09:55:10 -0800394 assert(!(mi_col_pred & (mi_width - mi_size_wide[BLOCK_8X8])) &&
395 !(mi_row_pred & (mi_height - mi_size_high[BLOCK_8X8])));
Jingning Hanfeb517c2016-12-21 16:02:07 -0800396#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
398 cm->mi_rows, cm->mi_cols);
399 xd->up_available = (mi_row_ori > tile->mi_row_start);
400 xd->left_available = (mi_col_ori > tile->mi_col_start);
401
402 // R/D setup.
403 x->rddiv = cpi->rd.RDDIV;
404 x->rdmult = cpi->rd.RDMULT;
405}
406
Yaowu Xuf883b422016-08-30 14:01:10 -0700407static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 MACROBLOCK *const x, const int mi_row,
409 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700410 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700411 const struct segmentation *seg = &cm->seg;
Jingning Han5b7706a2016-12-21 09:55:10 -0800412 const int miw = AOMMIN(mi_size_wide[bsize], cm->mi_cols - mi_col);
413 const int mih = AOMMIN(mi_size_high[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414 const int mi_offset = mi_row * cm->mi_stride + mi_col;
415 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
416 int r, c;
417 int seg_id_supertx = MAX_SEGMENTS;
418
419 if (!seg->enabled) {
420 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421 } else {
422 // Find the minimum segment_id
423 for (r = 0; r < mih; r++)
424 for (c = 0; c < miw; c++)
425 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700426 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
428
429 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700430 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700431 }
432
433 // Assign the the segment_id back to segment_id_supertx
434 for (r = 0; r < mih; r++)
435 for (c = 0; c < miw; c++)
436 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
437}
438#endif // CONFIG_SUPERTX
439
Yaowu Xuf883b422016-08-30 14:01:10 -0700440static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 MACROBLOCKD *const xd, int mi_row, int mi_col,
442 BLOCK_SIZE bsize) {
443 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
444 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
445 xd->mi[0]->mbmi.sb_type = bsize;
446 }
447}
448
Yaowu Xuf883b422016-08-30 14:01:10 -0700449static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700450 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
451 int mi_col, const int64_t *const threshold,
452 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700453 AV1_COMMON *const cm = &cpi->common;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800454 const int hbw = mi_size_wide[vt->bsize] / 2;
455 const int hbh = mi_size_high[vt->bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700456 const int has_cols = mi_col + hbw < cm->mi_cols;
457 const int has_rows = mi_row + hbh < cm->mi_rows;
458
459 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
460
461 assert(vt->bsize >= BLOCK_8X8);
462
463 assert(hbh == hbw);
464
465 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
466 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
467 return;
468 }
469
470 if (vt->force_split || (!has_cols && !has_rows)) goto split;
471
472 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
473 // variance is below threshold, otherwise split will be selected.
474 // No check for vert/horiz split as too few samples for variance.
475 if (vt->bsize == bsize_min[0]) {
476 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
477 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
478 return;
479 } else {
480 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
481 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
482 if (vt->bsize > BLOCK_8X8) {
483 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
484 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
485 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
486 }
487 return;
488 }
489 } else if (vt->bsize > bsize_min[0]) {
490 // For key frame: take split for bsize above 32X32 or very high variance.
491 if (cm->frame_type == KEY_FRAME &&
492 (vt->bsize > BLOCK_32X32 ||
493 vt->variances.none.variance > (threshold[0] << 4))) {
494 goto split;
495 }
496 // If variance is low, take the bsize (no split).
497 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
498 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
499 return;
500 }
501
502 // Check vertical split.
503 if (has_rows) {
504 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
505 if (vt->variances.vert[0].variance < threshold[0] &&
506 vt->variances.vert[1].variance < threshold[0] &&
507 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
508 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
509 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
510 return;
511 }
512 }
513 // Check horizontal split.
514 if (has_cols) {
515 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
516 if (vt->variances.horz[0].variance < threshold[0] &&
517 vt->variances.horz[1].variance < threshold[0] &&
518 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
519 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
520 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
521 return;
522 }
523 }
524 }
525
526split : {
527 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
528 bsize_min + 1);
529 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
530 threshold + 1, bsize_min + 1);
531 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
532 threshold + 1, bsize_min + 1);
533 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
534 threshold + 1, bsize_min + 1);
535 return;
536}
537}
538
539// Set the variance split thresholds for following the block sizes:
540// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
541// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
542// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700543static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
544 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700545 const int is_key_frame = (cm->frame_type == KEY_FRAME);
546 const int threshold_multiplier = is_key_frame ? 20 : 1;
547 const int64_t threshold_base =
548 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
549 if (is_key_frame) {
550 thresholds[1] = threshold_base;
551 thresholds[2] = threshold_base >> 2;
552 thresholds[3] = threshold_base >> 2;
553 thresholds[4] = threshold_base << 2;
554 } else {
555 thresholds[2] = threshold_base;
556 if (cm->width <= 352 && cm->height <= 288) {
557 thresholds[1] = threshold_base >> 2;
558 thresholds[3] = threshold_base << 3;
559 } else {
560 thresholds[1] = threshold_base;
561 thresholds[2] = (5 * threshold_base) >> 2;
562 if (cm->width >= 1920 && cm->height >= 1080)
563 thresholds[2] = (7 * threshold_base) >> 2;
564 thresholds[3] = threshold_base << cpi->oxcf.speed;
565 }
566 }
567 thresholds[0] = INT64_MIN;
568}
569
Yaowu Xuf883b422016-08-30 14:01:10 -0700570void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
571 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700572 SPEED_FEATURES *const sf = &cpi->sf;
573 const int is_key_frame = (cm->frame_type == KEY_FRAME);
574 if (sf->partition_search_type != VAR_BASED_PARTITION &&
575 sf->partition_search_type != REFERENCE_PARTITION) {
576 return;
577 } else {
578 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
579 // The thresholds below are not changed locally.
580 if (is_key_frame) {
581 cpi->vbp_threshold_sad = 0;
582 cpi->vbp_bsize_min = BLOCK_8X8;
583 } else {
584 if (cm->width <= 352 && cm->height <= 288)
585 cpi->vbp_threshold_sad = 100;
586 else
587 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
588 ? (cpi->y_dequant[q][1] << 1)
589 : 1000;
590 cpi->vbp_bsize_min = BLOCK_16X16;
591 }
592 cpi->vbp_threshold_minmax = 15 + (q >> 3);
593 }
594}
595
596// Compute the minmax over the 8x8 subblocks.
597static int compute_minmax_8x8(const uint8_t *src, int src_stride,
598 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700599#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700600 int highbd,
601#endif
602 int pixels_wide, int pixels_high) {
603 int k;
604 int minmax_max = 0;
605 int minmax_min = 255;
606 // Loop over the 4 8x8 subblocks.
607 for (k = 0; k < 4; k++) {
608 const int x8_idx = ((k & 1) << 3);
609 const int y8_idx = ((k >> 1) << 3);
610 int min = 0;
611 int max = 0;
612 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
613 const int src_offset = y8_idx * src_stride + x8_idx;
614 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700615#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700616 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700617 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618 ref_stride, &min, &max);
619 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700620 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621 ref_stride, &min, &max);
622 }
623#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700624 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700625 &min, &max);
626#endif
627 if ((max - min) > minmax_max) minmax_max = (max - min);
628 if ((max - min) < minmax_min) minmax_min = (max - min);
629 }
630 }
631 return (minmax_max - minmax_min);
632}
633
Yaowu Xuf883b422016-08-30 14:01:10 -0700634#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635static INLINE int avg_4x4(const uint8_t *const src, const int stride,
636 const int highbd) {
637 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700640 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 }
642}
643#else
644static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700645 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646}
647#endif
648
Yaowu Xuf883b422016-08-30 14:01:10 -0700649#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700650static INLINE int avg_8x8(const uint8_t *const src, const int stride,
651 const int highbd) {
652 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700653 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700654 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700655 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700656 }
657}
658#else
659static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700660 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700661}
662#endif
663
664static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700665#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 const int highbd,
667#endif
668 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
669 const int width, const int height,
670 const uint8_t *const src, const int src_stride,
671 const uint8_t *const ref, const int ref_stride) {
672 assert(bsize >= leaf_size);
673
674 vt->bsize = bsize;
675
676 vt->force_split = 0;
677
678 vt->src = src;
679 vt->src_stride = src_stride;
680 vt->ref = ref;
681 vt->ref_stride = ref_stride;
682
683 vt->width = width;
684 vt->height = height;
685
Yaowu Xuf883b422016-08-30 14:01:10 -0700686#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689
690 if (bsize > leaf_size) {
691 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800692 const int px = block_size_wide[subsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700693
694 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700695#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700697#endif // CONFIG_AOM_HIGHBITDEPTH
698 subsize, leaf_size, AOMMIN(px, width),
699 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700701#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700703#endif // CONFIG_AOM_HIGHBITDEPTH
704 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705 src + px, src_stride, ref + px, ref_stride);
706 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700707#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700708 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700709#endif // CONFIG_AOM_HIGHBITDEPTH
710 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 src + px * src_stride, src_stride, ref + px * ref_stride,
712 ref_stride);
713 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700714#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700715 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700716#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717 subsize, leaf_size, width - px, height - px,
718 src + px * src_stride + px, src_stride,
719 ref + px * ref_stride + px, ref_stride);
720 }
721}
722
723// Fill the variance tree based on averaging pixel values (sub-sampling), at
724// the leaf node size.
725static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
726 if (vt->bsize > leaf_size) {
727 fill_variance_tree(vt->split[0], leaf_size);
728 fill_variance_tree(vt->split[1], leaf_size);
729 fill_variance_tree(vt->split[2], leaf_size);
730 fill_variance_tree(vt->split[3], leaf_size);
731 fill_variance_node(vt);
732 } else if (vt->width <= 0 || vt->height <= 0) {
733 fill_variance(0, 0, 0, &vt->variances.none);
734 } else {
735 unsigned int sse = 0;
736 int sum = 0;
737 int src_avg;
738 int ref_avg;
739 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
740 if (leaf_size == BLOCK_4X4) {
741 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
742 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
743 } else {
744 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
745 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
746 }
747 sum = src_avg - ref_avg;
748 sse = sum * sum;
749 fill_variance(sse, sum, 0, &vt->variances.none);
750 }
751}
752
753static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
754 if (vt->bsize >= BLOCK_8X8) {
755 if (vt->bsize == BLOCK_16X16) {
756 if (vt->variances.none.variance <= threshold)
757 return;
758 else
759 vt->force_split = 0;
760 }
761
762 refine_variance_tree(vt->split[0], threshold);
763 refine_variance_tree(vt->split[1], threshold);
764 refine_variance_tree(vt->split[2], threshold);
765 refine_variance_tree(vt->split[3], threshold);
766
767 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
768 } else if (vt->width <= 0 || vt->height <= 0) {
769 fill_variance(0, 0, 0, &vt->variances.none);
770 } else {
771 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
772 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
773 const int sum = src_avg - ref_avg;
774 const unsigned int sse = sum * sum;
775 assert(vt->bsize == BLOCK_4X4);
776 fill_variance(sse, sum, 0, &vt->variances.none);
777 }
778}
779
780static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
781 if (vt->bsize == BLOCK_32X32) {
782 vt->force_split = vt->variances.none.variance > threshold;
783 } else {
784 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
785 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
786 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
787 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
788 }
789 return vt->force_split;
790}
791
Yaowu Xuf883b422016-08-30 14:01:10 -0700792static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700793 const int segment_id, const int64_t *const thresholds) {
794 if (vt->bsize == BLOCK_16X16) {
795 vt->force_split = vt->variances.none.variance > thresholds[0];
796 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
797 !cyclic_refresh_segment_id_boosted(segment_id)) {
798 // We have some nominal amount of 16x16 variance (based on average),
799 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
800 // force split to 8x8 block for this 16x16 block.
801 int minmax =
802 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700803#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700804 vt->highbd,
805#endif
806 vt->width, vt->height);
807 vt->force_split = minmax > cpi->vbp_threshold_minmax;
808 }
809 } else {
810 vt->force_split |=
811 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
812 vt->force_split |=
813 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
814 vt->force_split |=
815 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
816 vt->force_split |=
817 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
818
819 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
820 vt->force_split = vt->variances.none.variance > thresholds[0];
821 }
822 }
823
824 return vt->force_split;
825}
826
827// This function chooses partitioning based on the variance between source and
828// reconstructed last (or golden), where variance is computed for down-sampled
829// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700830static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831 const TileInfo *const tile, MACROBLOCK *const x,
832 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700833 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700834 MACROBLOCKD *const xd = &x->e_mbd;
835 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700836#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700837 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700838#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700839 const uint8_t *src;
840 const uint8_t *ref;
841 int src_stride;
842 int ref_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800843 int pixels_wide = MI_SIZE * mi_size_wide[cm->sb_size];
844 int pixels_high = MI_SIZE * mi_size_high[cm->sb_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700845 int64_t thresholds[5] = {
846 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
847 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
848 };
849 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
850 cpi->vbp_bsize_min, BLOCK_8X8 };
851 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
852 const int64_t *const thre = thresholds + start_level;
853 const BLOCK_SIZE *const bmin = bsize_min + start_level;
854
855 const int is_key_frame = (cm->frame_type == KEY_FRAME);
856 const int low_res = (cm->width <= 352 && cm->height <= 288);
857
858 int segment_id = CR_SEGMENT_ID_BASE;
859
860 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
861 const uint8_t *const map =
862 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
863 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
864
865 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700866 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867 set_vbp_thresholds(cpi, thresholds, q);
868 }
869 }
870
871 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
872
873 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
874 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
875
876 src = x->plane[0].src.buf;
877 src_stride = x->plane[0].src.stride;
878
879 if (!is_key_frame) {
880 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700881 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
882 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
883 unsigned int y_sad, y_sad_g;
884
885 const int hbs = cm->mib_size / 2;
886 const int split_vert = mi_col + hbs >= cm->mi_cols;
887 const int split_horz = mi_row + hbs >= cm->mi_rows;
888 BLOCK_SIZE bsize;
889
890 if (split_vert && split_horz)
891 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
892 else if (split_vert)
893 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
894 else if (split_horz)
895 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
896 else
897 bsize = cm->sb_size;
898
899 assert(yv12 != NULL);
900
901 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700902 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
903 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904 y_sad_g = cpi->fn_ptr[bsize].sdf(
905 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
906 xd->plane[0].pre[0].stride);
907 } else {
908 y_sad_g = UINT_MAX;
909 }
910
Yaowu Xuf883b422016-08-30 14:01:10 -0700911 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
912 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700913 mbmi->ref_frame[0] = LAST_FRAME;
Emil Keyder01770b32017-01-20 18:03:11 -0500914 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 mbmi->sb_type = cm->sb_size;
916 mbmi->mv[0].as_int = 0;
917#if CONFIG_DUAL_FILTER
918 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
919#else
920 mbmi->interp_filter = BILINEAR;
921#endif
922
Yaowu Xuf883b422016-08-30 14:01:10 -0700923 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924
925 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700926 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
927 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 mbmi->ref_frame[0] = GOLDEN_FRAME;
929 mbmi->mv[0].as_int = 0;
930 y_sad = y_sad_g;
931 } else {
932 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
933 }
934
David Barkerac37fa32016-12-02 12:30:21 +0000935 av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700936
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 ref = xd->plane[0].dst.buf;
938 ref_stride = xd->plane[0].dst.stride;
939
940 // If the y_sad is very small, take the largest partition and exit.
941 // Don't check on boosted segment for now, as largest is suppressed there.
942 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
943 if (!split_vert && !split_horz) {
944 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
945 return;
946 }
947 }
948 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700949 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700950 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700951#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
953 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700954 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
955 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700957 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958 }
959 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700960#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700961 }
962
963 init_variance_tree(
964 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700965#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700967#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700968 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
969 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
970
971 // Fill in the entire tree of variances and compute splits.
972 if (is_key_frame) {
973 fill_variance_tree(vt, BLOCK_4X4);
974 check_split_key_frame(vt, thre[1]);
975 } else {
976 fill_variance_tree(vt, BLOCK_8X8);
977 check_split(cpi, vt, segment_id, thre);
978 if (low_res) {
979 refine_variance_tree(vt, thre[1] << 1);
980 }
981 }
982
983 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
984 mi_row + cm->mib_size > cm->mi_rows;
985
986 // Now go through the entire structure, splitting every block size until
987 // we get to one that's got a variance lower than our threshold.
988 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
989}
990
991#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700992static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700993 MB_MODE_INFO *mbmi) {
994 int dir;
995 for (dir = 0; dir < 2; ++dir) {
996 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
Emil Keyder01770b32017-01-20 18:03:11 -0500997 (mbmi->ref_frame[1] == NONE_FRAME ||
Yaowu Xuc27fc142016-08-22 16:08:15 -0700998 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
999 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
1000 ? EIGHTTAP_REGULAR
1001 : cm->interp_filter;
1002 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
1003 }
1004}
1005
1006static void update_filter_type_count(FRAME_COUNTS *counts,
1007 const MACROBLOCKD *xd,
1008 const MB_MODE_INFO *mbmi) {
1009 int dir;
1010 for (dir = 0; dir < 2; ++dir) {
1011 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
1012 (mbmi->ref_frame[1] > INTRA_FRAME &&
1013 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001014 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1016 }
1017 }
1018}
1019#endif
1020#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001021static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001022 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Sarah Parkerc2d38712017-01-24 15:15:41 -08001023 if (mode == ZEROMV
1024#if CONFIG_EXT_INTER
1025 || mode == ZERO_ZEROMV
1026#endif
1027 ) {
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001028 const int num_4x4s = bsize >= BLOCK_8X8
1029 ? num_4x4_blocks_wide_lookup[bsize] *
1030 num_4x4_blocks_high_lookup[bsize]
1031 : 1;
Sarah Parkerc2d38712017-01-24 15:15:41 -08001032 int ref;
1033 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
1034 ++cpi->global_motion_used[mbmi->ref_frame[ref]][0];
1035 cpi->global_motion_used[mbmi->ref_frame[ref]][1] += num_4x4s;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001036 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001037 }
1038}
1039#endif // CONFIG_GLOBAL_MOTION
1040
Urvang Joshi52648442016-10-13 17:27:51 -07001041static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1042 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1043 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001044 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001045 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001046 RD_COUNTS *const rdc = &td->rd_counts;
1047 MACROBLOCK *const x = &td->mb;
1048 MACROBLOCKD *const xd = &x->e_mbd;
1049 struct macroblock_plane *const p = x->plane;
1050 struct macroblockd_plane *const pd = xd->plane;
1051 MODE_INFO *mi = &ctx->mic;
1052 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1053 MODE_INFO *mi_addr = xd->mi[0];
1054 const struct segmentation *const seg = &cm->seg;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001055 const int bw = mi_size_wide[mi->mbmi.sb_type];
1056 const int bh = mi_size_high[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001057 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1058 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1060 int w, h;
1061
1062 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08001063 const int mi_width = mi_size_wide[bsize];
1064 const int mi_height = mi_size_high[bsize];
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001065 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001066
1067#if CONFIG_REF_MV
1068 int8_t rf_type;
1069#endif
1070
1071#if !CONFIG_SUPERTX
1072 assert(mi->mbmi.sb_type == bsize);
1073#endif
1074
1075 *mi_addr = *mi;
1076 *x->mbmi_ext = ctx->mbmi_ext;
1077
1078#if CONFIG_DUAL_FILTER
1079 reset_intmv_filter_type(cm, xd, mbmi);
1080#endif
1081
1082#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001083 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001084 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1085 (mbmi->sb_type >= BLOCK_8X8 || unify_bsize) && mbmi->mode == NEWMV) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001086 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1087 int_mv this_mv =
1088 (i == 0)
1089 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1090 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001091 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1092 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001093 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1094 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001095 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 }
1097 }
1098#endif
1099
1100 // If segmentation in use
1101 if (seg->enabled) {
1102 // For in frame complexity AQ copy the segment id from the segment map.
1103 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1104 const uint8_t *const map =
1105 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1106 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1107 }
1108 // Else for cyclic refresh mode update the segment map, set the segment id
1109 // and then update the quantizer.
1110 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001111 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1112 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 }
1114 }
1115
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001116 for (i = 0; i < MAX_MB_PLANE; ++i) {
1117 p[i].coeff = ctx->coeff[i];
1118 p[i].qcoeff = ctx->qcoeff[i];
1119 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001120#if CONFIG_PVQ
1121 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1122#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001123 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001124 }
Urvang Joshib100db72016-10-12 16:28:56 -07001125#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001126 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001127#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001128
1129 // Restore the coding context of the MB to that that was in place
1130 // when the mode was picked for it
1131 for (y = 0; y < mi_height; y++)
1132 for (x_idx = 0; x_idx < mi_width; x_idx++)
1133 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1134 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1135 xd->mi[x_idx + y * mis] = mi_addr;
1136 }
1137
Arild Fuldseth07441162016-08-15 15:07:52 +02001138#if CONFIG_DELTA_Q
1139 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001140 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001141#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001142 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001143 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001144#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001145
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001146 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001147 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1148 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1149 }
1150
1151 x->skip = ctx->skip;
1152
1153#if CONFIG_VAR_TX
1154 for (i = 0; i < 1; ++i)
1155 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1156 sizeof(uint8_t) * ctx->num_4x4_blk);
1157#endif
1158
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001159 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160
1161#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001162 {
1163 unsigned int *const mode_chosen_counts =
1164 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1165 if (frame_is_intra_only(cm)) {
1166 static const int kf_mode_index[] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -07001167 THR_DC /*DC_PRED*/,
1168 THR_V_PRED /*V_PRED*/,
1169 THR_H_PRED /*H_PRED*/,
1170 THR_D45_PRED /*D45_PRED*/,
1171 THR_D135_PRED /*D135_PRED*/,
1172 THR_D117_PRED /*D117_PRED*/,
1173 THR_D153_PRED /*D153_PRED*/,
1174 THR_D207_PRED /*D207_PRED*/,
1175 THR_D63_PRED /*D63_PRED*/,
1176#if CONFIG_ALT_INTRA
1177 THR_SMOOTH, /*SMOOTH_PRED*/
1178#endif // CONFIG_ALT_INTRA
1179 THR_TM /*TM_PRED*/,
Urvang Joshi52648442016-10-13 17:27:51 -07001180 };
1181 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1182 } else {
1183 // Note how often each mode chosen as best
1184 ++mode_chosen_counts[ctx->best_mode_index];
1185 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001186 }
1187#endif
1188 if (!frame_is_intra_only(cm)) {
1189 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001190 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001191#if CONFIG_GLOBAL_MOTION
1192 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001193 // TODO(sarahparker): global motion stats need to be handled per-tile
1194 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001195 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001196 } else {
1197 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1198 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1199 int idx, idy;
1200 for (idy = 0; idy < 2; idy += num_4x4_h) {
1201 for (idx = 0; idx < 2; idx += num_4x4_w) {
1202 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001203 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
James Zernaf322e12016-10-22 12:43:15 -07001204 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205 }
1206 }
1207 }
1208#endif // CONFIG_GLOBAL_MOTION
1209 if (cm->interp_filter == SWITCHABLE
Yue Chen69f18e12016-09-08 14:48:15 -07001210#if CONFIG_WARPED_MOTION
1211 && mbmi->motion_mode != WARPED_CAUSAL
1212#endif // CONFIG_WARPED_MOTION
Yue Chen19e7aa82016-11-30 14:05:39 -08001213#if CONFIG_GLOBAL_MOTION
1214 && !is_nontrans_global_motion(xd)
1215#endif // CONFIG_GLOBAL_MOTION
1216 ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217#if CONFIG_DUAL_FILTER
1218 update_filter_type_count(td->counts, xd, mbmi);
1219#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001220 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1221 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001222#endif
1223 }
1224 }
1225
1226 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1227 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1228 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1229 }
1230
1231 for (h = 0; h < y_mis; ++h) {
1232 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1233 for (w = 0; w < x_mis; ++w) {
1234 MV_REF *const mv = frame_mv + w;
1235 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1236 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1237 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1238 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1239 }
1240 }
1241}
1242
1243#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001244static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001245 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001246 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001247 int y, x_idx;
1248#if CONFIG_VAR_TX || CONFIG_REF_MV
1249 int i;
1250#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001251 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001252 RD_COUNTS *const rdc = &td->rd_counts;
1253 MACROBLOCK *const x = &td->mb;
1254 MACROBLOCKD *const xd = &x->e_mbd;
1255 MODE_INFO *mi = &ctx->mic;
1256 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1257 MODE_INFO *mi_addr = xd->mi[0];
1258 const struct segmentation *const seg = &cm->seg;
1259 const int mis = cm->mi_stride;
Jingning Han5b7706a2016-12-21 09:55:10 -08001260 const int mi_width = mi_size_wide[bsize];
1261 const int mi_height = mi_size_high[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001262 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1263 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1265 int w, h;
1266
1267#if CONFIG_REF_MV
1268 int8_t rf_type;
1269#endif
1270
1271 *mi_addr = *mi;
1272 *x->mbmi_ext = ctx->mbmi_ext;
1273 assert(is_inter_block(mbmi));
1274 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1275
1276#if CONFIG_DUAL_FILTER
1277 reset_intmv_filter_type(cm, xd, mbmi);
1278#endif
1279
1280#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001281 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Jingning Han38b1bc42016-12-22 15:51:04 -08001282 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
1283#if !CONFIG_CB4X4
1284 mbmi->sb_type >= BLOCK_8X8 &&
1285#endif // !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001286 mbmi->mode == NEWMV) {
1287 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1288 int_mv this_mv =
1289 (i == 0)
1290 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1291 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
Jingning Hanff6ee6a2016-12-07 09:55:21 -08001292 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1293 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001294 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1295 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1296 mbmi->pred_mv[i] = this_mv;
1297 }
1298 }
1299#endif
1300
1301 // If segmentation in use
1302 if (seg->enabled) {
1303 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001304 const int energy =
1305 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1306 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001307 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1308 // For cyclic refresh mode, now update the segment map
1309 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001310 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1311 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001312 } else {
1313 // Otherwise just set the segment id based on the current segment map
1314 const uint8_t *const map =
1315 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1316 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1317 }
1318 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1319 }
1320
1321 // Restore the coding context of the MB to that that was in place
1322 // when the mode was picked for it
1323 for (y = 0; y < mi_height; y++)
1324 for (x_idx = 0; x_idx < mi_width; x_idx++)
1325 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1326 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1327 xd->mi[x_idx + y * mis] = mi_addr;
1328 }
1329
Jingning Han38b1bc42016-12-22 15:51:04 -08001330#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1332 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1333 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1334 }
Jingning Han38b1bc42016-12-22 15:51:04 -08001335#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001336
1337 x->skip = ctx->skip;
1338
1339#if CONFIG_VAR_TX
1340 for (i = 0; i < 1; ++i)
1341 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1342 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001343
1344 if (!is_inter_block(mbmi) || mbmi->skip)
1345 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001346#endif // CONFIG_VAR_TX
1347
1348#if CONFIG_VAR_TX
1349 {
1350 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001351 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1352 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001353 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001354 mbmi->inter_tx_size[0][0] = mtx;
1355 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1356 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1357 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001358 }
1359#endif // CONFIG_VAR_TX
1360 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001361 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001362
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001363 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001364
1365 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001366 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001367
David Barker03bd2102016-11-17 14:55:04 +00001368#if CONFIG_GLOBAL_MOTION
1369 if (is_inter_block(mbmi)) {
1370 if (bsize >= BLOCK_8X8) {
1371 // TODO(sarahparker): global motion stats need to be handled per-tile
1372 // to be compatible with tile-based threading.
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001373 update_global_motion_used(mbmi->mode, bsize, mbmi, (AV1_COMP *)cpi);
David Barker03bd2102016-11-17 14:55:04 +00001374 } else {
1375 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1376 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1377 int idx, idy;
1378 for (idy = 0; idy < 2; idy += num_4x4_h) {
1379 for (idx = 0; idx < 2; idx += num_4x4_w) {
1380 const int j = idy * 2 + idx;
Debargha Mukherjee705544c2016-11-22 08:55:49 -08001381 update_global_motion_used(mi->bmi[j].as_mode, bsize, mbmi,
David Barker03bd2102016-11-17 14:55:04 +00001382 (AV1_COMP *)cpi);
1383 }
1384 }
1385 }
1386 }
1387#endif // CONFIG_GLOBAL_MOTION
1388
Yaowu Xuc27fc142016-08-22 16:08:15 -07001389 if (cm->interp_filter == SWITCHABLE
Yue Chen19e7aa82016-11-30 14:05:39 -08001390#if CONFIG_GLOBAL_MOTION
1391 && !is_nontrans_global_motion(xd)
1392#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001393 ) {
1394#if CONFIG_DUAL_FILTER
1395 update_filter_type_count(td->counts, xd, mbmi);
1396#else
James Zern9ca190c2016-10-22 12:42:43 -07001397 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1398 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001399#endif
1400 }
1401
1402 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1403 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1404 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1405 }
1406
1407 for (h = 0; h < y_mis; ++h) {
1408 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1409 for (w = 0; w < x_mis; ++w) {
1410 MV_REF *const mv = frame_mv + w;
1411 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1412 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1413 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1414 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1415 }
1416 }
1417}
1418
Urvang Joshi52648442016-10-13 17:27:51 -07001419static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 const TileInfo *const tile, int mi_row,
1421 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001422 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001423 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001424 MACROBLOCK *const x = &td->mb;
1425 MACROBLOCKD *const xd = &x->e_mbd;
1426 struct macroblock_plane *const p = x->plane;
1427 struct macroblockd_plane *const pd = xd->plane;
Jingning Han5b7706a2016-12-21 09:55:10 -08001428 int hbs = mi_size_wide[bsize] / 2;
Jingning Hanfeb517c2016-12-21 16:02:07 -08001429#if CONFIG_CB4X4
1430 const int unify_bsize = 1;
1431#else
1432 const int unify_bsize = 0;
1433#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001434 PARTITION_TYPE partition = pc_tree->partitioning;
1435 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1436 int i;
1437#if CONFIG_EXT_PARTITION_TYPES
1438 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1439#endif
1440 PICK_MODE_CONTEXT *pmc = NULL;
1441
1442 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1443
1444 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001445 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001446
1447 switch (partition) {
1448 case PARTITION_NONE:
1449 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1450 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001451 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001452 break;
1453 case PARTITION_VERT:
1454 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1455 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001456 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001457 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001458 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1459 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001460 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001461 }
1462 pmc = &pc_tree->vertical_supertx;
1463 break;
1464 case PARTITION_HORZ:
1465 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1466 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001467 subsize, dry_run);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001468 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001469 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1470 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001471 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 }
1473 pmc = &pc_tree->horizontal_supertx;
1474 break;
1475 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001476 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001477 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1478 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001479 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001480 } else {
1481 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001482 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1483 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001484 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1485 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001486 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001487 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1488 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001489 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001490 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1491 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001492 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001493 }
1494 pmc = &pc_tree->split_supertx;
1495 break;
1496#if CONFIG_EXT_PARTITION_TYPES
1497 case PARTITION_HORZ_A:
1498 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1499 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001500 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001501 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1502 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001503 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1505 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001506 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001507 pmc = &pc_tree->horizontala_supertx;
1508 break;
1509 case PARTITION_HORZ_B:
1510 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1511 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001512 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001513 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1514 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001515 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001516 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1517 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001518 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001519 pmc = &pc_tree->horizontalb_supertx;
1520 break;
1521 case PARTITION_VERT_A:
1522 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1523 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001524 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001525 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1526 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001527 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001528 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1529 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001530 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001531 pmc = &pc_tree->verticala_supertx;
1532 break;
1533 case PARTITION_VERT_B:
1534 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1535 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001536 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001537 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1538 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001539 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001540 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1541 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001542 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001543 pmc = &pc_tree->verticalb_supertx;
1544 break;
1545#endif // CONFIG_EXT_PARTITION_TYPES
1546 default: assert(0);
1547 }
1548
1549 for (i = 0; i < MAX_MB_PLANE; ++i) {
1550 if (pmc != NULL) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001551 p[i].coeff = pmc->coeff[i];
1552 p[i].qcoeff = pmc->qcoeff[i];
1553 pd[i].dqcoeff = pmc->dqcoeff[i];
1554 p[i].eobs = pmc->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001555 } else {
1556 // These should never be used
1557 p[i].coeff = NULL;
1558 p[i].qcoeff = NULL;
1559 pd[i].dqcoeff = NULL;
1560 p[i].eobs = NULL;
1561 }
1562 }
1563}
1564
1565static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1566 int best_tx, TX_SIZE supertx_size) {
1567 MACROBLOCK *const x = &td->mb;
1568#if CONFIG_VAR_TX
1569 int i;
1570
1571 for (i = 0; i < 1; ++i)
1572 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1573 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001574 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001575#endif // CONFIG_VAR_TX
1576 ctx->mic.mbmi.tx_size = supertx_size;
1577 ctx->skip = x->skip;
1578 ctx->mic.mbmi.tx_type = best_tx;
1579}
1580
Urvang Joshi52648442016-10-13 17:27:51 -07001581static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1582 int mi_row, int mi_col, BLOCK_SIZE bsize,
1583 int best_tx, TX_SIZE supertx_size,
1584 PC_TREE *pc_tree) {
1585 const AV1_COMMON *const cm = &cpi->common;
Jingning Han5b7706a2016-12-21 09:55:10 -08001586 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001587 PARTITION_TYPE partition = pc_tree->partitioning;
1588 BLOCK_SIZE subsize = get_subsize(bsize, partition);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001589#if CONFIG_CB4X4
1590 const int unify_bsize = 1;
1591#else
1592 const int unify_bsize = 0;
1593#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001594#if CONFIG_EXT_PARTITION_TYPES
1595 int i;
1596#endif
1597
1598 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1599
1600 switch (partition) {
1601 case PARTITION_NONE:
1602 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1603 break;
1604 case PARTITION_VERT:
1605 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001606 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001607 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1608 break;
1609 case PARTITION_HORZ:
1610 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
Jingning Hanfeb517c2016-12-21 16:02:07 -08001611 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize))
Yaowu Xuc27fc142016-08-22 16:08:15 -07001612 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1613 supertx_size);
1614 break;
1615 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08001616 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001617 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1618 } else {
1619 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1620 supertx_size, pc_tree->split[0]);
1621 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1622 supertx_size, pc_tree->split[1]);
1623 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1624 supertx_size, pc_tree->split[2]);
1625 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1626 best_tx, supertx_size, pc_tree->split[3]);
1627 }
1628 break;
1629#if CONFIG_EXT_PARTITION_TYPES
1630 case PARTITION_HORZ_A:
1631 for (i = 0; i < 3; i++)
1632 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1633 supertx_size);
1634 break;
1635 case PARTITION_HORZ_B:
1636 for (i = 0; i < 3; i++)
1637 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1638 supertx_size);
1639 break;
1640 case PARTITION_VERT_A:
1641 for (i = 0; i < 3; i++)
1642 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1643 break;
1644 case PARTITION_VERT_B:
1645 for (i = 0; i < 3; i++)
1646 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1647 break;
1648#endif // CONFIG_EXT_PARTITION_TYPES
1649 default: assert(0);
1650 }
1651}
1652#endif // CONFIG_SUPERTX
1653
Yue Chenf27b1602017-01-13 11:11:43 -08001654#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
1655static void set_mode_info_b(const AV1_COMP *const cpi,
1656 const TileInfo *const tile, ThreadData *td,
1657 int mi_row, int mi_col, BLOCK_SIZE bsize,
1658 PICK_MODE_CONTEXT *ctx) {
1659 MACROBLOCK *const x = &td->mb;
1660 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
1661 update_state(cpi, td, ctx, mi_row, mi_col, bsize, 1);
1662}
1663
1664static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
1665 const TileInfo *const tile, TOKENEXTRA **tp,
1666 int mi_row, int mi_col, BLOCK_SIZE bsize,
1667 PC_TREE *pc_tree) {
1668 const AV1_COMMON *const cm = &cpi->common;
Jingning Han91f01fd2017-01-18 17:16:40 -08001669 const int hbs = mi_size_wide[bsize] / 2;
Yue Chenf27b1602017-01-13 11:11:43 -08001670 const PARTITION_TYPE partition = pc_tree->partitioning;
1671 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1672#if CONFIG_EXT_PARTITION_TYPES
1673 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1674#endif
1675#if CONFIG_CB4X4
1676 const int unify_bsize = 1;
1677#else
1678 const int unify_bsize = 0;
1679 assert(bsize >= BLOCK_8X8);
1680#endif
1681
1682 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1683
1684 switch (partition) {
1685 case PARTITION_NONE:
1686 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize, &pc_tree->none);
1687 break;
1688 case PARTITION_VERT:
1689 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1690 &pc_tree->vertical[0]);
1691 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
1692 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1693 &pc_tree->vertical[1]);
1694 }
1695 break;
1696 case PARTITION_HORZ:
1697 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1698 &pc_tree->horizontal[0]);
1699 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
1700 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1701 &pc_tree->horizontal[1]);
1702 }
1703 break;
1704 case PARTITION_SPLIT:
1705 if (bsize == BLOCK_8X8 && !unify_bsize) {
1706 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1707 pc_tree->leaf_split[0]);
1708 } else {
1709 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col, subsize,
1710 pc_tree->split[0]);
1711 set_mode_info_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, subsize,
1712 pc_tree->split[1]);
1713 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, subsize,
1714 pc_tree->split[2]);
1715 set_mode_info_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, subsize,
1716 pc_tree->split[3]);
1717 }
1718 break;
1719#if CONFIG_EXT_PARTITION_TYPES
1720 case PARTITION_HORZ_A:
1721 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1722 &pc_tree->horizontala[0]);
1723 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1724 &pc_tree->horizontala[1]);
1725 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, subsize,
1726 &pc_tree->horizontala[2]);
1727 break;
1728 case PARTITION_HORZ_B:
1729 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1730 &pc_tree->horizontalb[0]);
1731 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1732 &pc_tree->horizontalb[1]);
1733 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1734 &pc_tree->horizontalb[2]);
1735 break;
1736 case PARTITION_VERT_A:
1737 set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
1738 &pc_tree->verticala[0]);
1739 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col, bsize2,
1740 &pc_tree->verticala[1]);
1741 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, subsize,
1742 &pc_tree->verticala[2]);
1743 break;
1744 case PARTITION_VERT_B:
1745 set_mode_info_b(cpi, tile, td, mi_row, mi_col, subsize,
1746 &pc_tree->verticalb[0]);
1747 set_mode_info_b(cpi, tile, td, mi_row, mi_col + hbs, bsize2,
1748 &pc_tree->verticalb[1]);
1749 set_mode_info_b(cpi, tile, td, mi_row + hbs, mi_col + hbs, bsize2,
1750 &pc_tree->verticalb[2]);
1751 break;
1752#endif // CONFIG_EXT_PARTITION_TYPES
1753 default: assert(0 && "Invalid partition type."); break;
1754 }
1755}
1756#endif
1757
Yaowu Xuf883b422016-08-30 14:01:10 -07001758void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1759 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001760 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1761 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1762 src->uv_crop_width };
1763 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1764 src->uv_crop_height };
1765 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1766 int i;
1767
1768 // Set current frame pointer.
1769 x->e_mbd.cur_buf = src;
1770
1771 for (i = 0; i < MAX_MB_PLANE; i++)
1772 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1773 strides[i], mi_row, mi_col, NULL,
1774 x->e_mbd.plane[i].subsampling_x,
1775 x->e_mbd.plane[i].subsampling_y);
1776}
1777
Urvang Joshi52648442016-10-13 17:27:51 -07001778static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001779 int8_t segment_id) {
1780 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001781 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001782 av1_init_plane_quantizers(cpi, x, segment_id);
1783 aom_clear_system_state();
1784 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1785 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001786}
1787
Urvang Joshi52648442016-10-13 17:27:51 -07001788static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001789 MACROBLOCK *const x, int mi_row, int mi_col,
1790 RD_COST *rd_cost,
1791#if CONFIG_SUPERTX
1792 int *totalrate_nocoef,
1793#endif
1794#if CONFIG_EXT_PARTITION_TYPES
1795 PARTITION_TYPE partition,
1796#endif
1797 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1798 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001799 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001800 TileInfo *const tile_info = &tile_data->tile_info;
1801 MACROBLOCKD *const xd = &x->e_mbd;
1802 MB_MODE_INFO *mbmi;
1803 struct macroblock_plane *const p = x->plane;
1804 struct macroblockd_plane *const pd = xd->plane;
1805 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1806 int i, orig_rdmult;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001807 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001808
Yaowu Xuf883b422016-08-30 14:01:10 -07001809 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001810
Yushin Cho77bba8d2016-11-04 16:36:56 -07001811#if CONFIG_PVQ
1812 x->pvq_speed = 1;
1813 x->pvq_coded = 0;
1814#endif
1815
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1817 mbmi = &xd->mi[0]->mbmi;
1818 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001819#if CONFIG_RD_DEBUG
1820 mbmi->mi_row = mi_row;
1821 mbmi->mi_col = mi_col;
1822#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001823#if CONFIG_SUPERTX
1824 // We set tx_size here as skip blocks would otherwise not set it.
1825 // tx_size needs to be set at this point as supertx_enable in
1826 // write_modes_sb is computed based on this, and if the garbage in memory
1827 // just happens to be the supertx_size, then the packer will code this
1828 // block as a supertx block, even if rdopt did not pick it as such.
1829 mbmi->tx_size = max_txsize_lookup[bsize];
1830#endif
1831#if CONFIG_EXT_PARTITION_TYPES
1832 mbmi->partition = partition;
1833#endif
1834
1835 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001836 p[i].coeff = ctx->coeff[i];
1837 p[i].qcoeff = ctx->qcoeff[i];
1838 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001839#if CONFIG_PVQ
1840 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1841#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001842 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001843 }
1844
Urvang Joshib100db72016-10-12 16:28:56 -07001845#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001846 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001847#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848
Yaowu Xuc27fc142016-08-22 16:08:15 -07001849 ctx->skippable = 0;
1850 ctx->pred_pixel_ready = 0;
1851
1852 // Set to zero to make sure we do not use the previous encoded frame stats
1853 mbmi->skip = 0;
1854
Jingning Han8efdbc82017-02-19 14:40:03 -08001855#if CONFIG_CB4X4
1856 x->skip_chroma_rd =
1857 (bsize < BLOCK_8X8) && !is_chroma_reference(mi_row, mi_col);
1858#endif
1859
Yaowu Xuf883b422016-08-30 14:01:10 -07001860#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001861 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001862 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001863 cpi, &x->plane[0].src, bsize, xd->bd);
1864 } else {
1865 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001866 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001867 }
1868#else
1869 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001870 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1871#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001872
1873 // Save rdmult before it might be changed, so it can be restored later.
1874 orig_rdmult = x->rdmult;
1875
1876 if (aq_mode == VARIANCE_AQ) {
1877 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001878 const int energy =
1879 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1880 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001881 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001882 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 }
1884 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1885 } else if (aq_mode == COMPLEXITY_AQ) {
1886 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1887 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1888 // If segment is boosted, use rdmult for that segment.
1889 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001890 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891 }
1892
1893 // Find best coding mode & reconstruct the MB so it is available
1894 // as a predictor for MBs that follow in the SB
1895 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001896 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001897#if CONFIG_SUPERTX
1898 *totalrate_nocoef = 0;
1899#endif // CONFIG_SUPERTX
1900 } else {
Jingning Hanbf9c6b72016-12-14 14:50:45 -08001901 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001903 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1904 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905#if CONFIG_SUPERTX
1906 *totalrate_nocoef = rd_cost->rate;
1907#endif // CONFIG_SUPERTX
1908 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001909 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001911 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001913 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914#if CONFIG_SUPERTX
1915 assert(*totalrate_nocoef >= 0);
1916#endif // CONFIG_SUPERTX
1917 }
1918 } else {
1919 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1920 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1921 rd_cost->rate = INT_MAX;
1922 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001923 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1924 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001925#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001926 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001927#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001928 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001929#if CONFIG_SUPERTX
1930 assert(*totalrate_nocoef >= 0);
1931#endif // CONFIG_SUPERTX
1932 }
1933 }
1934 }
1935
1936 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1937 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1938 (bsize >= BLOCK_16X16) &&
1939 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1940 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001941 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001942 }
1943
1944 x->rdmult = orig_rdmult;
1945
1946 // TODO(jingning) The rate-distortion optimization flow needs to be
1947 // refactored to provide proper exit/return handle.
1948 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1949
1950 ctx->rate = rd_cost->rate;
1951 ctx->dist = rd_cost->dist;
1952}
1953
1954#if CONFIG_REF_MV
1955static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1956#if CONFIG_EXT_INTER
1957 int is_compound,
1958#endif // CONFIG_EXT_INTER
1959 int16_t mode_context) {
1960 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1961#if CONFIG_EXT_INTER
1962 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1963 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1964#else
1965 if (mode == NEWMV) {
1966#endif // CONFIG_EXT_INTER
1967 ++counts->newmv_mode[mode_ctx][0];
1968 return;
1969 } else {
1970 ++counts->newmv_mode[mode_ctx][1];
1971
1972 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1973 return;
1974 }
1975
1976 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1977 if (mode == ZEROMV) {
1978 ++counts->zeromv_mode[mode_ctx][0];
1979 return;
1980 } else {
1981 ++counts->zeromv_mode[mode_ctx][1];
1982 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1983
1984 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1985 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1986 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1987
1988 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1989 }
1990 }
1991}
1992#endif
1993
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001994static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1995 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07001996#if CONFIG_SUPERTX
1997 ,
1998 int supertx_enabled
1999#endif
2000 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01002001#if CONFIG_DELTA_Q
2002 MACROBLOCK *x = &td->mb;
2003 MACROBLOCKD *const xd = &x->e_mbd;
2004#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002005 const MACROBLOCK *x = &td->mb;
2006 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01002007#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008 const MODE_INFO *const mi = xd->mi[0];
2009 const MB_MODE_INFO *const mbmi = &mi->mbmi;
2010 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
2011 const BLOCK_SIZE bsize = mbmi->sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002012 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002013
Thomas Daviesf6936102016-09-05 16:51:31 +01002014#if CONFIG_DELTA_Q
2015 // delta quant applies to both intra and inter
2016 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
2017
2018 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
2019 super_block_upper_left) {
2020 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
2021 const int absdq = abs(dq);
2022 int i;
2023 for (i = 0; i < absdq; ++i) {
2024 td->counts->delta_q[i][1]++;
2025 }
2026 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
2027 xd->prev_qindex = mbmi->current_q_index;
2028 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002029#else
2030 (void)mi_row;
2031 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01002032#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033 if (!frame_is_intra_only(cm)) {
2034 FRAME_COUNTS *const counts = td->counts;
2035 const int inter_block = is_inter_block(mbmi);
2036 const int seg_ref_active =
2037 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
2038 if (!seg_ref_active) {
2039#if CONFIG_SUPERTX
2040 if (!supertx_enabled)
2041#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07002042 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002043 // If the segment reference feature is enabled we have only a single
2044 // reference frame allowed for the segment so exclude it from
2045 // the reference frame counts used to work out probabilities.
2046 if (inter_block) {
2047 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
2048#if CONFIG_EXT_REFS
2049 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
2050#endif // CONFIG_EXT_REFS
2051
2052 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07002053 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
2054 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055
2056 if (has_second_ref(mbmi)) {
2057#if CONFIG_EXT_REFS
2058 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
2059
Yaowu Xuf883b422016-08-30 14:01:10 -07002060 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002061 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07002062 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
2063 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002064 } else {
clang-format67948d32016-09-07 22:40:40 -07002065 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
2066 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002067 }
2068
clang-format67948d32016-09-07 22:40:40 -07002069 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
2070 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002071#else
clang-format67948d32016-09-07 22:40:40 -07002072 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
2073 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002074#endif // CONFIG_EXT_REFS
2075 } else {
2076#if CONFIG_EXT_REFS
2077 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
2078
Yaowu Xuf883b422016-08-30 14:01:10 -07002079 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002080 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07002081 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
2082 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 } else {
2084 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format55ce9e02017-02-15 22:27:12 -08002085 counts
2086 ->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002087 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07002088 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
2089 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090 } else {
clang-format67948d32016-09-07 22:40:40 -07002091 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
2092 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002093 }
2094 }
2095#else
clang-format67948d32016-09-07 22:40:40 -07002096 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
2097 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002098 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07002099 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
2100 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101 }
2102#endif // CONFIG_EXT_REFS
2103 }
2104
2105#if CONFIG_EXT_INTER
2106 if (cm->reference_mode != COMPOUND_REFERENCE &&
2107#if CONFIG_SUPERTX
2108 !supertx_enabled &&
2109#endif
2110 is_interintra_allowed(mbmi)) {
2111 const int bsize_group = size_group_lookup[bsize];
2112 if (mbmi->ref_frame[1] == INTRA_FRAME) {
2113 counts->interintra[bsize_group][1]++;
2114 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
2115 if (is_interintra_wedge_used(bsize))
2116 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
2117 } else {
2118 counts->interintra[bsize_group][0]++;
2119 }
2120 }
2121#endif // CONFIG_EXT_INTER
2122
Yue Chencb60b182016-10-13 15:18:22 -07002123#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002124#if CONFIG_SUPERTX
2125 if (!supertx_enabled)
2126#endif // CONFIG_SUPERTX
2127#if CONFIG_EXT_INTER
2128 if (mbmi->ref_frame[1] != INTRA_FRAME)
2129#endif // CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07002130#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
2131 {
2132 if (motion_mode_allowed(mbmi) == WARPED_CAUSAL)
Yue Chencb60b182016-10-13 15:18:22 -07002133 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
Yue Chen69f18e12016-09-08 14:48:15 -07002134 else if (motion_mode_allowed(mbmi) == OBMC_CAUSAL)
2135 counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
2136 }
2137#else
2138 if (motion_mode_allowed(mbmi) > SIMPLE_TRANSLATION)
2139 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
2140#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yue Chencb60b182016-10-13 15:18:22 -07002141#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002142
2143#if CONFIG_EXT_INTER
2144 if (cm->reference_mode != SINGLE_REFERENCE &&
Sarah Parker6fdc8532016-11-16 17:47:13 -08002145 is_inter_compound_mode(mbmi->mode)
Yue Chencb60b182016-10-13 15:18:22 -07002146#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002147 && mbmi->motion_mode == SIMPLE_TRANSLATION
Yue Chencb60b182016-10-13 15:18:22 -07002148#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Sarah Parker6fdc8532016-11-16 17:47:13 -08002149 ) {
2150 counts->compound_interinter[bsize]
2151 [mbmi->interinter_compound_data.type]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002152 }
2153#endif // CONFIG_EXT_INTER
2154 }
2155 }
2156
2157 if (inter_block &&
2158 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xub0d0d002016-11-22 09:26:43 -08002159 int16_t mode_ctx;
2160#if !CONFIG_REF_MV
2161 mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
2162#endif
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002163 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002164 const PREDICTION_MODE mode = mbmi->mode;
2165#if CONFIG_REF_MV
2166#if CONFIG_EXT_INTER
2167 if (has_second_ref(mbmi)) {
2168 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
2169 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2170 } else {
2171#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002172 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2173 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002174 update_inter_mode_stats(counts, mode,
2175#if CONFIG_EXT_INTER
2176 has_second_ref(mbmi),
2177#endif // CONFIG_EXT_INTER
2178 mode_ctx);
2179
2180 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002181 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002182 int idx;
2183
2184 for (idx = 0; idx < 2; ++idx) {
2185 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2186 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002187 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002188 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
2189
2190 if (mbmi->ref_mv_idx == idx) break;
2191 }
2192 }
2193 }
2194
2195 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002196 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002197 int idx;
2198
2199 for (idx = 1; idx < 3; ++idx) {
2200 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2201 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002202 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002203 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2204
2205 if (mbmi->ref_mv_idx == idx - 1) break;
2206 }
2207 }
2208 }
2209#if CONFIG_EXT_INTER
2210 }
2211#endif // CONFIG_EXT_INTER
2212#else
2213#if CONFIG_EXT_INTER
2214 if (is_inter_compound_mode(mode))
2215 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2216 else
2217#endif // CONFIG_EXT_INTER
2218 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2219#endif
2220 } else {
2221 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2222 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2223 int idx, idy;
2224 for (idy = 0; idy < 2; idy += num_4x4_h) {
2225 for (idx = 0; idx < 2; idx += num_4x4_w) {
2226 const int j = idy * 2 + idx;
2227 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2228#if CONFIG_REF_MV
2229#if CONFIG_EXT_INTER
2230 if (has_second_ref(mbmi)) {
2231 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002232 ++counts->inter_compound_mode[mode_ctx]
2233 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002234 } else {
2235#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002236 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2237 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238 update_inter_mode_stats(counts, b_mode,
2239#if CONFIG_EXT_INTER
2240 has_second_ref(mbmi),
2241#endif // CONFIG_EXT_INTER
2242 mode_ctx);
2243#if CONFIG_EXT_INTER
2244 }
2245#endif // CONFIG_EXT_INTER
2246#else
2247#if CONFIG_EXT_INTER
2248 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002249 ++counts->inter_compound_mode[mode_ctx]
2250 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002251 else
2252#endif // CONFIG_EXT_INTER
2253 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2254#endif
2255 }
2256 }
2257 }
2258 }
2259 }
2260}
2261
2262typedef struct {
2263 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2264 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2265 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2266 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2267#if CONFIG_VAR_TX
2268 TXFM_CONTEXT *p_ta;
2269 TXFM_CONTEXT *p_tl;
2270 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2271 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2272#endif
2273} RD_SEARCH_MACROBLOCK_CONTEXT;
2274
2275static void restore_context(MACROBLOCK *x,
2276 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002277 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002278#if CONFIG_PVQ
2279 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002280#endif
2281 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002282 MACROBLOCKD *xd = &x->e_mbd;
2283 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002284 const int num_4x4_blocks_wide =
2285 block_size_wide[bsize] >> tx_size_wide_log2[0];
2286 const int num_4x4_blocks_high =
2287 block_size_high[bsize] >> tx_size_high_log2[0];
2288 int mi_width = mi_size_wide[bsize];
2289 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002290 for (p = 0; p < MAX_MB_PLANE; p++) {
2291 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2292 ctx->a + num_4x4_blocks_wide * p,
2293 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2294 xd->plane[p].subsampling_x);
2295 memcpy(xd->left_context[p] +
2296 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2297 ctx->l + num_4x4_blocks_high * p,
2298 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2299 xd->plane[p].subsampling_y);
2300 }
2301 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2302 sizeof(*xd->above_seg_context) * mi_width);
2303 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2304 sizeof(xd->left_seg_context[0]) * mi_height);
2305#if CONFIG_VAR_TX
2306 xd->above_txfm_context = ctx->p_ta;
2307 xd->left_txfm_context = ctx->p_tl;
2308 memcpy(xd->above_txfm_context, ctx->ta,
2309 sizeof(*xd->above_txfm_context) * mi_width);
2310 memcpy(xd->left_txfm_context, ctx->tl,
2311 sizeof(*xd->left_txfm_context) * mi_height);
2312#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002313#if CONFIG_PVQ
2314 od_encode_rollback(&x->daala_enc, rdo_buf);
2315#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002316}
2317
2318static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002319 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002320#if CONFIG_PVQ
2321 od_rollback_buffer *rdo_buf,
2322#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002323 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002324 const MACROBLOCKD *xd = &x->e_mbd;
2325 int p;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002326 const int num_4x4_blocks_wide =
2327 block_size_wide[bsize] >> tx_size_wide_log2[0];
2328 const int num_4x4_blocks_high =
2329 block_size_high[bsize] >> tx_size_high_log2[0];
2330 int mi_width = mi_size_wide[bsize];
2331 int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002332
2333 // buffer the above/left context information of the block in search.
2334 for (p = 0; p < MAX_MB_PLANE; ++p) {
2335 memcpy(ctx->a + num_4x4_blocks_wide * p,
2336 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2337 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2338 xd->plane[p].subsampling_x);
2339 memcpy(ctx->l + num_4x4_blocks_high * p,
2340 xd->left_context[p] +
2341 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2342 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2343 xd->plane[p].subsampling_y);
2344 }
2345 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2346 sizeof(*xd->above_seg_context) * mi_width);
2347 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2348 sizeof(xd->left_seg_context[0]) * mi_height);
2349#if CONFIG_VAR_TX
2350 memcpy(ctx->ta, xd->above_txfm_context,
2351 sizeof(*xd->above_txfm_context) * mi_width);
2352 memcpy(ctx->tl, xd->left_txfm_context,
2353 sizeof(*xd->left_txfm_context) * mi_height);
2354 ctx->p_ta = xd->above_txfm_context;
2355 ctx->p_tl = xd->left_txfm_context;
2356#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002357#if CONFIG_PVQ
2358 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2359#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002360}
2361
Urvang Joshi52648442016-10-13 17:27:51 -07002362static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2363 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2364 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002365#if CONFIG_EXT_PARTITION_TYPES
2366 PARTITION_TYPE partition,
2367#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002368 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002369 MACROBLOCK *const x = &td->mb;
Yue Chenf27b1602017-01-13 11:11:43 -08002370#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2371 MACROBLOCKD *xd = &x->e_mbd;
2372 MB_MODE_INFO *mbmi;
2373 int check_ncobmc;
2374#endif
2375
Yaowu Xuc27fc142016-08-22 16:08:15 -07002376 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2377#if CONFIG_EXT_PARTITION_TYPES
2378 x->e_mbd.mi[0]->mbmi.partition = partition;
2379#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002380 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
Yue Chenf27b1602017-01-13 11:11:43 -08002381#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
2382 mbmi = &xd->mi[0]->mbmi;
2383 check_ncobmc =
2384 is_inter_block(mbmi) && motion_mode_allowed(mbmi) >= OBMC_CAUSAL;
2385 if (!dry_run && check_ncobmc) {
2386 av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
2387 av1_setup_dst_planes(x->e_mbd.plane, get_frame_new_buffer(&cpi->common),
2388 mi_row, mi_col);
2389 }
2390#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002391 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002392
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002393 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002394#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002395 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002396#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002397 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002398#endif
2399 }
2400}
2401
Urvang Joshi52648442016-10-13 17:27:51 -07002402static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2403 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2404 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2405 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002406 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002407 MACROBLOCK *const x = &td->mb;
2408 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse55c6bde2017-01-12 15:55:31 -08002409 const int hbs = mi_size_wide[bsize] / 2;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002410 const int is_partition_root = bsize >= BLOCK_8X8;
2411 const int ctx = is_partition_root
Alex Converse55c6bde2017-01-12 15:55:31 -08002412 ? partition_plane_context(xd, mi_row, mi_col,
2413#if CONFIG_UNPOISON_PARTITION_CTX
2414 mi_row + hbs < cm->mi_rows,
2415 mi_col + hbs < cm->mi_cols,
2416#endif
2417 bsize)
2418 : -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002419 const PARTITION_TYPE partition = pc_tree->partitioning;
2420 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2421#if CONFIG_EXT_PARTITION_TYPES
2422 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2423#endif
2424
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002425#if CONFIG_CB4X4
2426 const int unify_bsize = 1;
2427#else
2428 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002429 assert(bsize >= BLOCK_8X8);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002430#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431
2432 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2433
Alex Converse55c6bde2017-01-12 15:55:31 -08002434 if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435
2436#if CONFIG_SUPERTX
2437 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2438 partition != PARTITION_NONE && !xd->lossless[0]) {
2439 int supertx_enabled;
2440 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2441 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2442 if (supertx_enabled) {
Jingning Han5b7706a2016-12-21 09:55:10 -08002443 const int mi_width = mi_size_wide[bsize];
2444 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002445 int x_idx, y_idx, i;
2446 uint8_t *dst_buf[3];
2447 int dst_stride[3];
2448 set_skip_context(xd, mi_row, mi_col);
2449 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002450 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2451 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002452
Yaowu Xuf883b422016-08-30 14:01:10 -07002453 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002454 for (i = 0; i < MAX_MB_PLANE; i++) {
2455 dst_buf[i] = xd->plane[i].dst.buf;
2456 dst_stride[i] = xd->plane[i].dst.stride;
2457 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002458 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2459 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460
2461 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2462 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2463
2464 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002465 int this_rate = 0;
Angie Chiangff6d8902016-10-21 11:02:09 -07002466 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002467 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2468 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002469 } else {
2470 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002471 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002472 reset_skip_context(xd, bsize);
2473 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002474 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475 for (y_idx = 0; y_idx < mi_height; y_idx++)
2476 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2477 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2478 x_idx &&
2479 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2480 y_idx) {
2481 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2482 xd->mi[0]->mbmi.skip;
2483 }
2484 }
2485 td->counts->supertx[partition_supertx_context_lookup[partition]]
2486 [supertx_size][1]++;
2487 td->counts->supertx_size[supertx_size]++;
2488#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08002489 if (get_ext_tx_types(supertx_size, bsize, 1, cm->reduced_tx_set_used) >
2490 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 !xd->mi[0]->mbmi.skip) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08002492 const int eset =
2493 get_ext_tx_set(supertx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494 if (eset > 0) {
clang-format55ce9e02017-02-15 22:27:12 -08002495 ++td->counts
2496 ->inter_ext_tx[eset][supertx_size][xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002497 }
2498 }
2499#else
2500 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2501 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2502 }
2503#endif // CONFIG_EXT_TX
2504 }
2505#if CONFIG_EXT_PARTITION_TYPES
2506 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2507 partition);
2508#else
2509 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2510 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2511#endif
2512#if CONFIG_VAR_TX
Yaowu Xu52a17632016-11-17 15:48:21 -08002513 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd->mi[0]->mbmi.skip,
2514 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002515#endif // CONFIG_VAR_TX
2516 return;
2517 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002518 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002519 td->counts->supertx[partition_supertx_context_lookup[partition]]
2520 [supertx_size][0]++;
2521 }
2522 }
2523 }
2524#endif // CONFIG_SUPERTX
2525
2526 switch (partition) {
2527 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002528 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529#if CONFIG_EXT_PARTITION_TYPES
2530 partition,
2531#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002532 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002533 break;
2534 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002535 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002536#if CONFIG_EXT_PARTITION_TYPES
2537 partition,
2538#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002539 &pc_tree->vertical[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002540 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002541 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002542#if CONFIG_EXT_PARTITION_TYPES
2543 partition,
2544#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002545 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 }
2547 break;
2548 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002549 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002550#if CONFIG_EXT_PARTITION_TYPES
2551 partition,
2552#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002553 &pc_tree->horizontal[0], rate);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002554 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002555 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556#if CONFIG_EXT_PARTITION_TYPES
2557 partition,
2558#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002559 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002560 }
2561 break;
2562 case PARTITION_SPLIT:
Jingning Hanbf9c6b72016-12-14 14:50:45 -08002563 if (bsize == BLOCK_8X8 && !unify_bsize) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002564 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002565#if CONFIG_EXT_PARTITION_TYPES
2566 partition,
2567#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002568 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002570 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2571 pc_tree->split[0], rate);
2572 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2573 pc_tree->split[1], rate);
2574 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2575 pc_tree->split[2], rate);
2576 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2577 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002578 }
2579 break;
2580#if CONFIG_EXT_PARTITION_TYPES
2581 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002582 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2583 &pc_tree->horizontala[0], rate);
2584 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2585 partition, &pc_tree->horizontala[1], rate);
2586 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2587 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 break;
2589 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002590 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2591 &pc_tree->horizontalb[0], rate);
2592 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2593 partition, &pc_tree->horizontalb[1], rate);
2594 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2595 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002596 break;
2597 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002598 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2599 &pc_tree->verticala[0], rate);
2600 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2601 partition, &pc_tree->verticala[1], rate);
2602 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2603 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002604
2605 break;
2606 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002607 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2608 &pc_tree->verticalb[0], rate);
2609 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2610 partition, &pc_tree->verticalb[1], rate);
2611 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2612 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002613 break;
2614#endif // CONFIG_EXT_PARTITION_TYPES
2615 default: assert(0 && "Invalid partition type."); break;
2616 }
2617
2618#if CONFIG_EXT_PARTITION_TYPES
2619 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2620#else
2621 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2622 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2623#endif // CONFIG_EXT_PARTITION_TYPES
2624}
2625
2626// Check to see if the given partition size is allowed for a specified number
2627// of mi block rows and columns remaining in the image.
2628// If not then return the largest allowed partition size
2629static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2630 int cols_left, int *bh, int *bw) {
2631 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002632 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002633 } else {
2634 for (; bsize > 0; bsize -= 3) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08002635 *bh = mi_size_high[bsize];
2636 *bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002637 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2638 break;
2639 }
2640 }
2641 }
2642 return bsize;
2643}
2644
Yaowu Xuf883b422016-08-30 14:01:10 -07002645static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646 int bh_in, int bw_in,
2647 int mi_rows_remaining,
2648 int mi_cols_remaining, BLOCK_SIZE bsize,
2649 MODE_INFO **mib) {
2650 int bh = bh_in;
2651 int r, c;
2652 for (r = 0; r < cm->mib_size; r += bh) {
2653 int bw = bw_in;
2654 for (c = 0; c < cm->mib_size; c += bw) {
2655 const int index = r * cm->mi_stride + c;
2656 mib[index] = mi + index;
2657 mib[index]->mbmi.sb_type = find_partition_size(
2658 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2659 }
2660 }
2661}
2662
2663// This function attempts to set all mode info entries in a given superblock
2664// to the same block partition size.
2665// However, at the bottom and right borders of the image the requested size
2666// may not be allowed in which case this code attempts to choose the largest
2667// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002668static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002669 MODE_INFO **mib, int mi_row, int mi_col,
2670 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002671 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2673 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2674 int block_row, block_col;
2675 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002676 int bh = mi_size_high[bsize];
2677 int bw = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002678
2679 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2680
2681 // Apply the requested partition size to the SB if it is all "in image"
2682 if ((mi_cols_remaining >= cm->mib_size) &&
2683 (mi_rows_remaining >= cm->mib_size)) {
2684 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2685 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2686 int index = block_row * cm->mi_stride + block_col;
2687 mib[index] = mi_upper_left + index;
2688 mib[index]->mbmi.sb_type = bsize;
2689 }
2690 }
2691 } else {
2692 // Else this is a partial SB.
2693 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2694 mi_cols_remaining, bsize, mib);
2695 }
2696}
2697
Yaowu Xuf883b422016-08-30 14:01:10 -07002698static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002699 TileDataEnc *tile_data, MODE_INFO **mib,
2700 TOKENEXTRA **tp, int mi_row, int mi_col,
2701 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2702#if CONFIG_SUPERTX
2703 int *rate_nocoef,
2704#endif
2705 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002706 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002707 TileInfo *const tile_info = &tile_data->tile_info;
2708 MACROBLOCK *const x = &td->mb;
2709 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08002710 const int bs = mi_size_wide[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002711 const int hbs = bs / 2;
2712 int i;
Alex Converse55c6bde2017-01-12 15:55:31 -08002713 const int pl = partition_plane_context(xd, mi_row, mi_col,
2714#if CONFIG_UNPOISON_PARTITION_CTX
2715 mi_row + hbs < cm->mi_rows,
2716 mi_col + hbs < cm->mi_cols,
2717#endif
2718 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002719 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2720 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2721 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2722 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2723 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2724 int splits_below = 0;
2725 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2726 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002727 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002728#if CONFIG_SUPERTX
2729 int last_part_rate_nocoef = INT_MAX;
2730 int none_rate_nocoef = INT_MAX;
2731 int chosen_rate_nocoef = INT_MAX;
2732#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002733#if CONFIG_PVQ
2734 od_rollback_buffer pre_rdo_buf;
2735#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002736 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2737
2738 assert(num_4x4_blocks_wide_lookup[bsize] ==
2739 num_4x4_blocks_high_lookup[bsize]);
2740
Yaowu Xuf883b422016-08-30 14:01:10 -07002741 av1_rd_cost_reset(&last_part_rdc);
2742 av1_rd_cost_reset(&none_rdc);
2743 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002744
2745 pc_tree->partitioning = partition;
2746
2747#if CONFIG_VAR_TX
2748 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2749 xd->left_txfm_context =
2750 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2751#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002752#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002753 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002754#else
2755 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2756#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757
2758 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2759 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002760 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002761 }
2762
2763 if (do_partition_search &&
2764 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2765 cpi->sf.adjust_partitioning_from_last_frame) {
2766 // Check if any of the sub blocks are further split.
2767 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2768 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2769 splits_below = 1;
2770 for (i = 0; i < 4; i++) {
2771 int jj = i >> 1, ii = i & 0x01;
2772 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2773 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2774 splits_below = 0;
2775 }
2776 }
2777 }
2778
2779 // If partition is not none try none unless each of the 4 splits are split
2780 // even further..
2781 if (partition != PARTITION_NONE && !splits_below &&
2782 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2783 pc_tree->partitioning = PARTITION_NONE;
2784 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2785#if CONFIG_SUPERTX
2786 &none_rate_nocoef,
2787#endif
2788#if CONFIG_EXT_PARTITION_TYPES
2789 PARTITION_NONE,
2790#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002791 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002792
2793 if (none_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08002794 none_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
2795 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002796 none_rdc.rdcost =
2797 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2798#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08002799 none_rate_nocoef +=
2800 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
2801 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002802#endif
2803 }
2804
Yushin Cho77bba8d2016-11-04 16:36:56 -07002805#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002806 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002807#else
2808 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2809#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002810 mib[0]->mbmi.sb_type = bs_type;
2811 pc_tree->partitioning = partition;
2812 }
2813 }
2814
2815 switch (partition) {
2816 case PARTITION_NONE:
2817 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2818#if CONFIG_SUPERTX
2819 &last_part_rate_nocoef,
2820#endif
2821#if CONFIG_EXT_PARTITION_TYPES
2822 PARTITION_NONE,
2823#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002824 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 break;
2826 case PARTITION_HORZ:
2827 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2828#if CONFIG_SUPERTX
2829 &last_part_rate_nocoef,
2830#endif
2831#if CONFIG_EXT_PARTITION_TYPES
2832 PARTITION_HORZ,
2833#endif
2834 subsize, &pc_tree->horizontal[0], INT64_MAX);
2835 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2836 mi_row + hbs < cm->mi_rows) {
2837 RD_COST tmp_rdc;
2838#if CONFIG_SUPERTX
2839 int rt_nocoef = 0;
2840#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002841 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002842 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002843 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002844 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002845 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2847#if CONFIG_SUPERTX
2848 &rt_nocoef,
2849#endif
2850#if CONFIG_EXT_PARTITION_TYPES
2851 PARTITION_HORZ,
2852#endif
2853 subsize, &pc_tree->horizontal[1], INT64_MAX);
2854 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002855 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002856#if CONFIG_SUPERTX
2857 last_part_rate_nocoef = INT_MAX;
2858#endif
2859 break;
2860 }
2861 last_part_rdc.rate += tmp_rdc.rate;
2862 last_part_rdc.dist += tmp_rdc.dist;
2863 last_part_rdc.rdcost += tmp_rdc.rdcost;
2864#if CONFIG_SUPERTX
2865 last_part_rate_nocoef += rt_nocoef;
2866#endif
2867 }
2868 break;
2869 case PARTITION_VERT:
2870 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2871#if CONFIG_SUPERTX
2872 &last_part_rate_nocoef,
2873#endif
2874#if CONFIG_EXT_PARTITION_TYPES
2875 PARTITION_VERT,
2876#endif
2877 subsize, &pc_tree->vertical[0], INT64_MAX);
2878 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2879 mi_col + hbs < cm->mi_cols) {
2880 RD_COST tmp_rdc;
2881#if CONFIG_SUPERTX
2882 int rt_nocoef = 0;
2883#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002884 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002885 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002886 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002887 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002888 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002889 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2890#if CONFIG_SUPERTX
2891 &rt_nocoef,
2892#endif
2893#if CONFIG_EXT_PARTITION_TYPES
2894 PARTITION_VERT,
2895#endif
2896 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2897 INT64_MAX);
2898 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002899 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002900#if CONFIG_SUPERTX
2901 last_part_rate_nocoef = INT_MAX;
2902#endif
2903 break;
2904 }
2905 last_part_rdc.rate += tmp_rdc.rate;
2906 last_part_rdc.dist += tmp_rdc.dist;
2907 last_part_rdc.rdcost += tmp_rdc.rdcost;
2908#if CONFIG_SUPERTX
2909 last_part_rate_nocoef += rt_nocoef;
2910#endif
2911 }
2912 break;
2913 case PARTITION_SPLIT:
2914 if (bsize == BLOCK_8X8) {
2915 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2916#if CONFIG_SUPERTX
2917 &last_part_rate_nocoef,
2918#endif
2919#if CONFIG_EXT_PARTITION_TYPES
2920 PARTITION_SPLIT,
2921#endif
2922 subsize, pc_tree->leaf_split[0], INT64_MAX);
2923 break;
2924 }
2925 last_part_rdc.rate = 0;
2926 last_part_rdc.dist = 0;
2927 last_part_rdc.rdcost = 0;
2928#if CONFIG_SUPERTX
2929 last_part_rate_nocoef = 0;
2930#endif
2931 for (i = 0; i < 4; i++) {
2932 int x_idx = (i & 1) * hbs;
2933 int y_idx = (i >> 1) * hbs;
2934 int jj = i >> 1, ii = i & 0x01;
2935 RD_COST tmp_rdc;
2936#if CONFIG_SUPERTX
2937 int rt_nocoef;
2938#endif
2939 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2940 continue;
2941
Yaowu Xuf883b422016-08-30 14:01:10 -07002942 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002943 rd_use_partition(cpi, td, tile_data,
2944 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2945 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2946 &tmp_rdc.dist,
2947#if CONFIG_SUPERTX
2948 &rt_nocoef,
2949#endif
2950 i != 3, pc_tree->split[i]);
2951 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002952 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953#if CONFIG_SUPERTX
2954 last_part_rate_nocoef = INT_MAX;
2955#endif
2956 break;
2957 }
2958 last_part_rdc.rate += tmp_rdc.rate;
2959 last_part_rdc.dist += tmp_rdc.dist;
2960#if CONFIG_SUPERTX
2961 last_part_rate_nocoef += rt_nocoef;
2962#endif
2963 }
2964 break;
2965#if CONFIG_EXT_PARTITION_TYPES
2966 case PARTITION_VERT_A:
2967 case PARTITION_VERT_B:
2968 case PARTITION_HORZ_A:
2969 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2970#endif // CONFIG_EXT_PARTITION_TYPES
2971 default: assert(0); break;
2972 }
2973
2974 if (last_part_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08002975 last_part_rdc.rate +=
2976 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002977 last_part_rdc.rdcost =
2978 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2979#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08002980 last_part_rate_nocoef +=
2981 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002982#endif
2983 }
2984
2985 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2986 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2987 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2988 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2989 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2990 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2991 chosen_rdc.rate = 0;
2992 chosen_rdc.dist = 0;
2993#if CONFIG_SUPERTX
2994 chosen_rate_nocoef = 0;
2995#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002996#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002997 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002998#else
2999 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3000#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001 pc_tree->partitioning = PARTITION_SPLIT;
3002
3003 // Split partition.
3004 for (i = 0; i < 4; i++) {
3005 int x_idx = (i & 1) * hbs;
3006 int y_idx = (i >> 1) * hbs;
3007 RD_COST tmp_rdc;
3008#if CONFIG_SUPERTX
3009 int rt_nocoef = 0;
3010#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003011#if CONFIG_PVQ
3012 od_rollback_buffer buf;
3013#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003014 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
3015 continue;
3016
Yushin Cho77bba8d2016-11-04 16:36:56 -07003017#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003018 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003019#else
3020 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
3021#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003022 pc_tree->split[i]->partitioning = PARTITION_NONE;
3023 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
3024 &tmp_rdc,
3025#if CONFIG_SUPERTX
3026 &rt_nocoef,
3027#endif
3028#if CONFIG_EXT_PARTITION_TYPES
3029 PARTITION_SPLIT,
3030#endif
3031 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
3032
Yushin Cho77bba8d2016-11-04 16:36:56 -07003033#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003034 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003035#else
3036 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
3037#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003038 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003039 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003040#if CONFIG_SUPERTX
3041 chosen_rate_nocoef = INT_MAX;
3042#endif
3043 break;
3044 }
3045
3046 chosen_rdc.rate += tmp_rdc.rate;
3047 chosen_rdc.dist += tmp_rdc.dist;
3048#if CONFIG_SUPERTX
3049 chosen_rate_nocoef += rt_nocoef;
3050#endif
3051
3052 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003053 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
3054 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055
Alex Converse55c6bde2017-01-12 15:55:31 -08003056 chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3057 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003058#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003059 chosen_rate_nocoef +=
3060 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3061 [PARTITION_SPLIT];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003062#endif
3063 }
3064 if (chosen_rdc.rate < INT_MAX) {
Alex Converse55c6bde2017-01-12 15:55:31 -08003065 chosen_rdc.rate += cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3066 [PARTITION_SPLIT];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003067 chosen_rdc.rdcost =
3068 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
3069#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003070 chosen_rate_nocoef +=
3071 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX]
3072 [PARTITION_NONE];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003073#endif
3074 }
3075 }
3076
3077 // If last_part is better set the partitioning to that.
3078 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
3079 mib[0]->mbmi.sb_type = bsize;
3080 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
3081 chosen_rdc = last_part_rdc;
3082#if CONFIG_SUPERTX
3083 chosen_rate_nocoef = last_part_rate_nocoef;
3084#endif
3085 }
3086 // If none was better set the partitioning to that.
3087 if (none_rdc.rdcost < chosen_rdc.rdcost) {
3088 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
3089 chosen_rdc = none_rdc;
3090#if CONFIG_SUPERTX
3091 chosen_rate_nocoef = none_rate_nocoef;
3092#endif
3093 }
3094
Yushin Cho77bba8d2016-11-04 16:36:56 -07003095#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003096 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003097#else
3098 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3099#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003100
3101 // We must have chosen a partitioning and encoding or we'll fail later on.
3102 // No other opportunities for success.
3103 if (bsize == cm->sb_size)
3104 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
3105
3106 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003107 if (bsize == cm->sb_size) {
3108 // NOTE: To get estimate for rate due to the tokens, use:
3109 // int rate_coeffs = 0;
3110 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
3111 // bsize, pc_tree, &rate_coeffs);
3112 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
3113 pc_tree, NULL);
3114 } else {
3115 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
3116 pc_tree, NULL);
3117 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07003118 }
3119
3120 *rate = chosen_rdc.rate;
3121 *dist = chosen_rdc.dist;
3122#if CONFIG_SUPERTX
3123 *rate_nocoef = chosen_rate_nocoef;
3124#endif
3125}
3126
3127/* clang-format off */
3128static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003129#if CONFIG_CB4X4
3130 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3131#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003132 BLOCK_4X4, // 4x4
3133 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
3134 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
3135 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
3136 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
3137#if CONFIG_EXT_PARTITION
3138 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
3139#endif // CONFIG_EXT_PARTITION
3140};
3141
3142static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003143#if CONFIG_CB4X4
3144 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 2x2, 2x4, 4x2
3145#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146 BLOCK_8X8, // 4x4
3147 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
3148 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
3149 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
3150 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
3151#if CONFIG_EXT_PARTITION
3152 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
3153#endif // CONFIG_EXT_PARTITION
3154};
3155
3156// Next square block size less or equal than current block size.
3157static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
Jingning Hanf1702dd2016-11-30 21:17:59 -08003158#if CONFIG_CB4X4
3159 BLOCK_2X2, BLOCK_2X2, BLOCK_2X2, // 2x2, 2x4, 4x2
3160#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003161 BLOCK_4X4, // 4x4
3162 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
3163 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
3164 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
3165 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
3166#if CONFIG_EXT_PARTITION
3167 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
3168#endif // CONFIG_EXT_PARTITION
3169};
3170/* clang-format on */
3171
3172// Look at all the mode_info entries for blocks that are part of this
3173// partition and find the min and max values for sb_type.
3174// At the moment this is designed to work on a superblock but could be
3175// adjusted to use a size parameter.
3176//
3177// The min and max are assumed to have been initialized prior to calling this
3178// function so repeat calls can accumulate a min and max of more than one
3179// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07003180static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003181 MACROBLOCKD *xd, MODE_INFO **mib,
3182 BLOCK_SIZE *min_block_size,
3183 BLOCK_SIZE *max_block_size) {
3184 int i, j;
3185 int index = 0;
3186
3187 // Check the sb_type for each block that belongs to this region.
3188 for (i = 0; i < cm->mib_size; ++i) {
3189 for (j = 0; j < cm->mib_size; ++j) {
3190 MODE_INFO *mi = mib[index + j];
3191 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07003192 *min_block_size = AOMMIN(*min_block_size, sb_type);
3193 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003194 }
3195 index += xd->mi_stride;
3196 }
3197}
3198
3199// Look at neighboring blocks and set a min and max partition size based on
3200// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07003201static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003202 MACROBLOCKD *const xd, int mi_row,
3203 int mi_col, BLOCK_SIZE *min_block_size,
3204 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003205 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003206 MODE_INFO **mi = xd->mi;
3207 const int left_in_image = xd->left_available && mi[-1];
3208 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
3209 const int mi_rows_remaining = tile->mi_row_end - mi_row;
3210 const int mi_cols_remaining = tile->mi_col_end - mi_col;
3211 int bh, bw;
3212 BLOCK_SIZE min_size = BLOCK_4X4;
3213 BLOCK_SIZE max_size = BLOCK_LARGEST;
3214
3215 // Trap case where we do not have a prediction.
3216 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
3217 // Default "min to max" and "max to min"
3218 min_size = BLOCK_LARGEST;
3219 max_size = BLOCK_4X4;
3220
3221 // NOTE: each call to get_sb_partition_size_range() uses the previous
3222 // passed in values for min and max as a starting point.
3223 // Find the min and max partition used in previous frame at this location
3224 if (cm->frame_type != KEY_FRAME) {
3225 MODE_INFO **prev_mi =
3226 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
3227 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
3228 }
3229 // Find the min and max partition sizes used in the left superblock
3230 if (left_in_image) {
3231 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
3232 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
3233 }
3234 // Find the min and max partition sizes used in the above suprblock.
3235 if (above_in_image) {
3236 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
3237 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
3238 }
3239
3240 // Adjust observed min and max for "relaxed" auto partition case.
3241 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
3242 min_size = min_partition_size[min_size];
3243 max_size = max_partition_size[max_size];
3244 }
3245 }
3246
3247 // Check border cases where max and min from neighbors may not be legal.
3248 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
3249 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07003250 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003251
3252 // Test for blocks at the edge of the active image.
3253 // This may be the actual edge of the image or where there are formatting
3254 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003255 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003256 min_size = BLOCK_4X4;
3257 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003258 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003259 }
3260
3261 // When use_square_partition_only is true, make sure at least one square
3262 // partition is allowed by selecting the next smaller square size as
3263 // *min_block_size.
3264 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003265 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003266 }
3267
Yaowu Xuf883b422016-08-30 14:01:10 -07003268 *min_block_size = AOMMIN(min_size, cm->sb_size);
3269 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003270}
3271
3272// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003273static void set_partition_range(const AV1_COMMON *const cm,
3274 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003275 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003276 BLOCK_SIZE *const min_bs,
3277 BLOCK_SIZE *const max_bs) {
Jingning Hanc709e1f2016-12-06 14:48:09 -08003278 const int mi_width = mi_size_wide[bsize];
3279 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003280 int idx, idy;
3281
Yaowu Xuc27fc142016-08-22 16:08:15 -07003282 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003283 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3284 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3285 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003286
3287 if (prev_mi) {
3288 for (idy = 0; idy < mi_height; ++idy) {
3289 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003290 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3291 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003292 min_size = AOMMIN(min_size, bs);
3293 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003294 }
3295 }
3296 }
3297
3298 if (xd->left_available) {
3299 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003300 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3301 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003302 min_size = AOMMIN(min_size, bs);
3303 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003304 }
3305 }
3306
3307 if (xd->up_available) {
3308 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003309 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3310 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003311 min_size = AOMMIN(min_size, bs);
3312 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003313 }
3314 }
3315
3316 if (min_size == max_size) {
3317 min_size = min_partition_size[min_size];
3318 max_size = max_partition_size[max_size];
3319 }
3320
Yaowu Xuf883b422016-08-30 14:01:10 -07003321 *min_bs = AOMMIN(min_size, cm->sb_size);
3322 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003323}
3324
3325static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3326 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3327}
3328
3329static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3330 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3331}
3332
3333#if CONFIG_FP_MB_STATS
3334const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3335 0,
3336 10,
3337 10,
3338 30,
3339 40,
3340 40,
3341 60,
3342 80,
3343 80,
3344 90,
3345 100,
3346 100,
3347 120,
3348#if CONFIG_EXT_PARTITION
3349 // TODO(debargha): What are the correct numbers here?
3350 130,
3351 130,
3352 150
3353#endif // CONFIG_EXT_PARTITION
3354};
3355const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3356 0,
3357 3,
3358 3,
3359 7,
3360 15,
3361 15,
3362 30,
3363 40,
3364 40,
3365 60,
3366 80,
3367 80,
3368 120,
3369#if CONFIG_EXT_PARTITION
3370 // TODO(debargha): What are the correct numbers here?
3371 160,
3372 160,
3373 240
3374#endif // CONFIG_EXT_PARTITION
3375};
3376const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3377 1,
3378 1,
3379 1,
3380 1,
3381 1,
3382 1,
3383 1,
3384 1,
3385 1,
3386 1,
3387 4,
3388 4,
Yaowu Xu17fd2f22016-11-17 18:23:28 -08003389 6,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003390#if CONFIG_EXT_PARTITION
3391 // TODO(debargha): What are the correct numbers here?
3392 8,
3393 8,
3394 10
3395#endif // CONFIG_EXT_PARTITION
3396};
3397
3398typedef enum {
3399 MV_ZERO = 0,
3400 MV_LEFT = 1,
3401 MV_UP = 2,
3402 MV_RIGHT = 3,
3403 MV_DOWN = 4,
3404 MV_INVALID
3405} MOTION_DIRECTION;
3406
3407static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3408 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3409 return MV_ZERO;
3410 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3411 return MV_LEFT;
3412 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3413 return MV_RIGHT;
3414 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3415 return MV_UP;
3416 } else {
3417 return MV_DOWN;
3418 }
3419}
3420
3421static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3422 MOTION_DIRECTION that_mv) {
3423 if (this_mv == that_mv) {
3424 return 0;
3425 } else {
3426 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3427 }
3428}
3429#endif
3430
3431#if CONFIG_EXT_PARTITION_TYPES
3432static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003433 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3434 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3435 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3436 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003437#if CONFIG_SUPERTX
3438 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3439#endif
3440 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3441 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3442 MACROBLOCK *const x = &td->mb;
3443 MACROBLOCKD *const xd = &x->e_mbd;
3444 RD_COST this_rdc, sum_rdc;
3445#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003446 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003447 TileInfo *const tile_info = &tile_data->tile_info;
3448 int this_rate_nocoef, sum_rate_nocoef;
3449 int abort_flag;
3450 const int supertx_allowed = !frame_is_intra_only(cm) &&
3451 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3452 !xd->lossless[0];
3453#endif
3454 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3455
3456 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3457#if CONFIG_SUPERTX
3458 &sum_rate_nocoef,
3459#endif
3460#if CONFIG_EXT_PARTITION_TYPES
3461 partition,
3462#endif
3463 subsize0, &ctxs[0], best_rdc->rdcost);
3464#if CONFIG_SUPERTX
3465 abort_flag = sum_rdc.rdcost >= best_rd;
3466#endif
3467
3468#if CONFIG_SUPERTX
3469 if (sum_rdc.rdcost < INT64_MAX) {
3470#else
3471 if (sum_rdc.rdcost < best_rdc->rdcost) {
3472#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003473 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3474 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003475 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003476 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003477
Urvang Joshi368fbc92016-10-17 16:31:34 -07003478 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003479
3480#if CONFIG_SUPERTX
3481 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3482 &this_rate_nocoef,
3483#if CONFIG_EXT_PARTITION_TYPES
3484 partition,
3485#endif
3486 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3487#else
3488 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3489#if CONFIG_EXT_PARTITION_TYPES
3490 partition,
3491#endif
3492 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3493#endif // CONFIG_SUPERTX
3494
3495 if (this_rdc.rate == INT_MAX) {
3496 sum_rdc.rdcost = INT64_MAX;
3497#if CONFIG_SUPERTX
3498 sum_rate_nocoef = INT_MAX;
3499#endif
3500 } else {
3501 sum_rdc.rate += this_rdc.rate;
3502 sum_rdc.dist += this_rdc.dist;
3503 sum_rdc.rdcost += this_rdc.rdcost;
3504#if CONFIG_SUPERTX
3505 sum_rate_nocoef += this_rate_nocoef;
3506#endif
3507 }
3508
3509#if CONFIG_SUPERTX
3510 if (sum_rdc.rdcost < INT64_MAX) {
3511#else
3512 if (sum_rdc.rdcost < best_rdc->rdcost) {
3513#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003514 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3515 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003516 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003517 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003518
Urvang Joshi368fbc92016-10-17 16:31:34 -07003519 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520
3521#if CONFIG_SUPERTX
3522 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3523 &this_rate_nocoef,
3524#if CONFIG_EXT_PARTITION_TYPES
3525 partition,
3526#endif
3527 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3528#else
3529 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3530#if CONFIG_EXT_PARTITION_TYPES
3531 partition,
3532#endif
3533 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3534#endif // CONFIG_SUPERTX
3535
3536 if (this_rdc.rate == INT_MAX) {
3537 sum_rdc.rdcost = INT64_MAX;
3538#if CONFIG_SUPERTX
3539 sum_rate_nocoef = INT_MAX;
3540#endif
3541 } else {
3542 sum_rdc.rate += this_rdc.rate;
3543 sum_rdc.dist += this_rdc.dist;
3544 sum_rdc.rdcost += this_rdc.rdcost;
3545#if CONFIG_SUPERTX
3546 sum_rate_nocoef += this_rate_nocoef;
3547#endif
3548 }
3549
3550#if CONFIG_SUPERTX
3551 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3552 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3553 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3554 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003555 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3557 [supertx_size],
3558 0);
3559 sum_rdc.rdcost =
3560 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3561
3562 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3563 TX_TYPE best_tx = DCT_DCT;
3564 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3565
3566 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3567
3568 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3569 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3570
Yaowu Xuf883b422016-08-30 14:01:10 -07003571 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003572 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3573 [supertx_size],
3574 1);
3575 tmp_rdc.rdcost =
3576 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3577 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3578 sum_rdc = tmp_rdc;
3579 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3580 supertx_size, pc_tree);
3581 }
3582 }
3583
3584 pc_tree->partitioning = best_partition;
3585 }
3586#endif // CONFIG_SUPERTX
3587
3588 if (sum_rdc.rdcost < best_rdc->rdcost) {
Alex Converse55c6bde2017-01-12 15:55:31 -08003589 int pl = partition_plane_context(xd, mi_row, mi_col,
3590#if CONFIG_UNPOISON_PARTITION_CTX
3591 has_rows, has_cols,
3592#endif
3593 bsize);
3594 sum_rdc.rate +=
3595 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003596 sum_rdc.rdcost =
3597 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3598#if CONFIG_SUPERTX
Alex Converse55c6bde2017-01-12 15:55:31 -08003599 sum_rate_nocoef +=
3600 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX][partition];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003601#endif
3602 if (sum_rdc.rdcost < best_rdc->rdcost) {
3603#if CONFIG_SUPERTX
3604 *best_rate_nocoef = sum_rate_nocoef;
3605 assert(*best_rate_nocoef >= 0);
3606#endif
3607 *best_rdc = sum_rdc;
3608 pc_tree->partitioning = partition;
3609 }
3610 }
3611 }
3612 }
3613}
3614#endif // CONFIG_EXT_PARTITION_TYPES
3615
3616// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3617// unlikely to be selected depending on previous rate-distortion optimization
3618// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003619static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 TileDataEnc *tile_data, TOKENEXTRA **tp,
3621 int mi_row, int mi_col, BLOCK_SIZE bsize,
3622 RD_COST *rd_cost,
3623#if CONFIG_SUPERTX
3624 int *rate_nocoef,
3625#endif
3626 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003627 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003628 TileInfo *const tile_info = &tile_data->tile_info;
3629 MACROBLOCK *const x = &td->mb;
3630 MACROBLOCKD *const xd = &x->e_mbd;
Jingning Hanc709e1f2016-12-06 14:48:09 -08003631 const int mi_step = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003633 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003634 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Alex Converse55c6bde2017-01-12 15:55:31 -08003635#if CONFIG_UNPOISON_PARTITION_CTX
3636 const int hbs = mi_size_wide[bsize] / 2;
3637 const int has_rows = mi_row + hbs < cm->mi_rows;
3638 const int has_cols = mi_col + hbs < cm->mi_cols;
3639#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07003640 int tmp_partition_cost[PARTITION_TYPES];
Alex Converse55c6bde2017-01-12 15:55:31 -08003641#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003642 BLOCK_SIZE subsize;
3643 RD_COST this_rdc, sum_rdc, best_rdc;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003644 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3645 int do_square_split = bsize_at_least_8x8;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003646#if CONFIG_CB4X4
3647 const int unify_bsize = 1;
3648 const int pl = bsize_at_least_8x8
Alex Converse55c6bde2017-01-12 15:55:31 -08003649 ? partition_plane_context(xd, mi_row, mi_col,
3650#if CONFIG_UNPOISON_PARTITION_CTX
3651 has_rows, has_cols,
3652#endif
3653 bsize)
3654 : -1;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003655#else
3656 const int unify_bsize = 0;
Alex Converse55c6bde2017-01-12 15:55:31 -08003657 const int pl = partition_plane_context(xd, mi_row, mi_col,
3658#if CONFIG_UNPOISON_PARTITION_CTX
3659 has_rows, has_cols,
3660#endif
3661 bsize);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003662#endif // CONFIG_CB4X4
Alex Converse55c6bde2017-01-12 15:55:31 -08003663 const int *partition_cost =
3664 cpi->partition_cost[pl + CONFIG_UNPOISON_PARTITION_CTX];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003665#if CONFIG_SUPERTX
3666 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3667 int abort_flag;
3668 const int supertx_allowed = !frame_is_intra_only(cm) &&
3669 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3670 !xd->lossless[0];
3671#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003672
Urvang Joshi52648442016-10-13 17:27:51 -07003673 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003674#if CONFIG_EXT_PARTITION_TYPES
3675 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3676#endif
3677
3678 // Override skipping rectangular partition operations for edge blocks
3679 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3680 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3681 const int xss = x->e_mbd.plane[1].subsampling_x;
3682 const int yss = x->e_mbd.plane[1].subsampling_y;
3683
3684 BLOCK_SIZE min_size = x->min_partition_size;
3685 BLOCK_SIZE max_size = x->max_partition_size;
3686
3687#if CONFIG_FP_MB_STATS
3688 unsigned int src_diff_var = UINT_MAX;
3689 int none_complexity = 0;
3690#endif
3691
3692 int partition_none_allowed = !force_horz_split && !force_vert_split;
3693 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003694 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003695 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003696 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003697
3698#if CONFIG_PVQ
3699 od_rollback_buffer pre_rdo_buf;
3700#endif
3701
Yaowu Xuc27fc142016-08-22 16:08:15 -07003702 (void)*tp_orig;
3703
Alex Converse55c6bde2017-01-12 15:55:31 -08003704#if !CONFIG_UNPOISON_PARTITION_CTX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003705 if (force_horz_split || force_vert_split) {
3706 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3707
3708 if (!force_vert_split) { // force_horz_split only
3709 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3710 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003711 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003712 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003713 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714 } else if (!force_horz_split) { // force_vert_split only
3715 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3716 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003717 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003718 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003719 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003720 } else { // force_ horz_split && force_vert_split horz_split
3721 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3722 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3723 tmp_partition_cost[PARTITION_SPLIT] = 0;
3724 }
3725
3726 partition_cost = tmp_partition_cost;
3727 }
Alex Converse55c6bde2017-01-12 15:55:31 -08003728#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003729
3730#if CONFIG_VAR_TX
3731#ifndef NDEBUG
3732 // Nothing should rely on the default value of this array (which is just
3733 // leftover from encoding the previous block. Setting it to magic number
3734 // when debugging.
3735 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3736#endif // NDEBUG
3737#endif // CONFIG_VAR_TX
3738
Jingning Hanc709e1f2016-12-06 14:48:09 -08003739 assert(mi_size_wide[bsize] == mi_size_high[bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003740
Yaowu Xuf883b422016-08-30 14:01:10 -07003741 av1_rd_cost_init(&this_rdc);
3742 av1_rd_cost_init(&sum_rdc);
3743 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003744 best_rdc.rdcost = best_rd;
3745
3746 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3747
3748 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003749 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003750
3751 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003752 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003753 ((pc_tree->index == 0 || pc_tree->index == 3) +
3754 get_chessboard_index(cm->current_video_frame)) &
3755 0x1;
3756
3757 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3758 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3759 }
3760
3761 // Determine partition types in search according to the speed features.
3762 // The threshold set here has to be of square block size.
3763 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003764 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3765 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3766 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3767 partition_none_allowed &= no_partition_allowed;
3768 partition_horz_allowed &= partition_allowed || force_horz_split;
3769 partition_vert_allowed &= partition_allowed || force_vert_split;
3770 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003771 }
3772 if (cpi->sf.use_square_partition_only) {
3773 partition_horz_allowed &= force_horz_split;
3774 partition_vert_allowed &= force_vert_split;
3775 }
3776
3777#if CONFIG_VAR_TX
3778 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3779 xd->left_txfm_context =
3780 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3781#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003782#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003783 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003784#else
3785 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3786#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003787
3788#if CONFIG_FP_MB_STATS
3789 if (cpi->use_fp_mb_stats) {
3790 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3791 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3792 mi_col, bsize);
3793 }
3794#endif
3795
3796#if CONFIG_FP_MB_STATS
3797 // Decide whether we shall split directly and skip searching NONE by using
3798 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003799 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003800 partition_none_allowed && src_diff_var > 4 &&
3801 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3802 int mb_row = mi_row >> 1;
3803 int mb_col = mi_col >> 1;
3804 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003805 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003806 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003807 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003808 int r, c;
3809
3810 // compute a complexity measure, basically measure inconsistency of motion
3811 // vectors obtained from the first pass in the current block
3812 for (r = mb_row; r < mb_row_end; r++) {
3813 for (c = mb_col; c < mb_col_end; c++) {
3814 const int mb_index = r * cm->mb_cols + c;
3815
3816 MOTION_DIRECTION this_mv;
3817 MOTION_DIRECTION right_mv;
3818 MOTION_DIRECTION bottom_mv;
3819
3820 this_mv =
3821 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3822
3823 // to its right
3824 if (c != mb_col_end - 1) {
3825 right_mv = get_motion_direction_fp(
3826 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3827 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3828 }
3829
3830 // to its bottom
3831 if (r != mb_row_end - 1) {
3832 bottom_mv = get_motion_direction_fp(
3833 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3834 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3835 }
3836
3837 // do not count its left and top neighbors to avoid double counting
3838 }
3839 }
3840
3841 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3842 partition_none_allowed = 0;
3843 }
3844 }
3845#endif
3846
3847 // PARTITION_NONE
3848 if (partition_none_allowed) {
3849 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3850#if CONFIG_SUPERTX
3851 &this_rate_nocoef,
3852#endif
3853#if CONFIG_EXT_PARTITION_TYPES
3854 PARTITION_NONE,
3855#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003856 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003858 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003859 this_rdc.rate += partition_cost[PARTITION_NONE];
3860 this_rdc.rdcost =
3861 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3862#if CONFIG_SUPERTX
3863 this_rate_nocoef += partition_cost[PARTITION_NONE];
3864#endif
3865 }
3866
3867 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003868 // Adjust dist breakout threshold according to the partition size.
3869 const int64_t dist_breakout_thr =
3870 cpi->sf.partition_search_breakout_dist_thr >>
3871 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3872 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3873 const int rate_breakout_thr =
3874 cpi->sf.partition_search_breakout_rate_thr *
3875 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003876
3877 best_rdc = this_rdc;
3878#if CONFIG_SUPERTX
3879 best_rate_nocoef = this_rate_nocoef;
3880 assert(best_rate_nocoef >= 0);
3881#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003882 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003883
3884 // If all y, u, v transform blocks in this partition are skippable, and
3885 // the dist & rate are within the thresholds, the partition search is
3886 // terminated for current branch of the partition search tree.
3887 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3888 // early termination at that speed.
3889 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003890 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003892 do_square_split = 0;
3893 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894 }
3895
3896#if CONFIG_FP_MB_STATS
3897 // Check if every 16x16 first pass block statistics has zero
3898 // motion and the corresponding first pass residue is small enough.
3899 // If that is the case, check the difference variance between the
3900 // current frame and the last frame. If the variance is small enough,
3901 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003902 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3904 int mb_row = mi_row >> 1;
3905 int mb_col = mi_col >> 1;
3906 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003907 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003908 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003909 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910 int r, c;
3911
3912 int skip = 1;
3913 for (r = mb_row; r < mb_row_end; r++) {
3914 for (c = mb_col; c < mb_col_end; c++) {
3915 const int mb_index = r * cm->mb_cols + c;
3916 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3917 FPMB_MOTION_ZERO_MASK) ||
3918 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3919 FPMB_ERROR_SMALL_MASK)) {
3920 skip = 0;
3921 break;
3922 }
3923 }
3924 if (skip == 0) {
3925 break;
3926 }
3927 }
3928 if (skip) {
3929 if (src_diff_var == UINT_MAX) {
3930 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3931 src_diff_var = get_sby_perpixel_diff_variance(
3932 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3933 }
3934 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003935 do_square_split = 0;
3936 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937 }
3938 }
3939 }
3940#endif
3941 }
3942 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003943#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003944 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003945#else
3946 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3947#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003948 }
3949
3950 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003951 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003952
3953 // PARTITION_SPLIT
3954 // TODO(jingning): use the motion vectors given by the above search as
3955 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003956 if (do_square_split) {
3957 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003958 subsize = get_subsize(bsize, PARTITION_SPLIT);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08003959 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960#if CONFIG_DUAL_FILTER
3961 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3962 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003963 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003964#else
3965 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3966 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003967 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003968#endif
3969#if CONFIG_SUPERTX
3970 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3971 &sum_rate_nocoef,
3972#if CONFIG_EXT_PARTITION_TYPES
3973 PARTITION_SPLIT,
3974#endif
3975 subsize, pc_tree->leaf_split[0], INT64_MAX);
3976#else
3977 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3978#if CONFIG_EXT_PARTITION_TYPES
3979 PARTITION_SPLIT,
3980#endif
3981 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3982#endif // CONFIG_SUPERTX
3983 if (sum_rdc.rate == INT_MAX) {
3984 sum_rdc.rdcost = INT64_MAX;
3985#if CONFIG_SUPERTX
3986 sum_rate_nocoef = INT_MAX;
3987#endif
3988 }
3989#if CONFIG_SUPERTX
3990 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3991 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3992 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3993
3994 pc_tree->partitioning = PARTITION_SPLIT;
3995
clang-format55ce9e02017-02-15 22:27:12 -08003996 sum_rdc.rate += av1_cost_bit(
3997 cm->fc->supertx_prob[partition_supertx_context_lookup
3998 [PARTITION_SPLIT]][supertx_size],
3999 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004000 sum_rdc.rdcost =
4001 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4002
4003 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
4004 TX_TYPE best_tx = DCT_DCT;
4005 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4006
4007 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4008
4009 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
4010 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
4011
Yaowu Xuf883b422016-08-30 14:01:10 -07004012 tmp_rdc.rate += av1_cost_bit(
clang-format55ce9e02017-02-15 22:27:12 -08004013 cm->fc->supertx_prob[partition_supertx_context_lookup
4014 [PARTITION_SPLIT]][supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004015 1);
4016 tmp_rdc.rdcost =
4017 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4018 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4019 sum_rdc = tmp_rdc;
4020 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4021 supertx_size, pc_tree);
4022 }
4023 }
4024
4025 pc_tree->partitioning = best_partition;
4026 }
4027#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004028 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004029 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07004030 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004031#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004032 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004033#else
Urvang Joshi52648442016-10-13 17:27:51 -07004034 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004035#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004036 const int x_idx = (idx & 1) * mi_step;
4037 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004038
4039 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
4040 continue;
4041
Urvang Joshi454280d2016-10-14 16:51:44 -07004042 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004043
Urvang Joshi52648442016-10-13 17:27:51 -07004044 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004045#if CONFIG_SUPERTX
4046 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
4047 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07004048 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004049#else
Urvang Joshi52648442016-10-13 17:27:51 -07004050 rd_pick_partition(
4051 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
4052 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004053#endif // CONFIG_SUPERTX
4054
4055 if (this_rdc.rate == INT_MAX) {
4056 sum_rdc.rdcost = INT64_MAX;
4057#if CONFIG_SUPERTX
4058 sum_rate_nocoef = INT_MAX;
4059#endif // CONFIG_SUPERTX
4060 break;
4061 } else {
4062 sum_rdc.rate += this_rdc.rate;
4063 sum_rdc.dist += this_rdc.dist;
4064 sum_rdc.rdcost += this_rdc.rdcost;
4065#if CONFIG_SUPERTX
4066 sum_rate_nocoef += this_rate_nocoef;
4067#endif // CONFIG_SUPERTX
4068 }
4069 }
Urvang Joshi52648442016-10-13 17:27:51 -07004070 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004071#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004072 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004073 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4074 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4075
4076 pc_tree->partitioning = PARTITION_SPLIT;
4077
clang-format55ce9e02017-02-15 22:27:12 -08004078 sum_rdc.rate += av1_cost_bit(
4079 cm->fc->supertx_prob[partition_supertx_context_lookup
4080 [PARTITION_SPLIT]][supertx_size],
4081 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004082 sum_rdc.rdcost =
4083 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4084
4085 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4086 TX_TYPE best_tx = DCT_DCT;
4087 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4088
4089 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4090
4091 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
4092 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
4093
Yaowu Xuf883b422016-08-30 14:01:10 -07004094 tmp_rdc.rate += av1_cost_bit(
clang-format55ce9e02017-02-15 22:27:12 -08004095 cm->fc->supertx_prob[partition_supertx_context_lookup
4096 [PARTITION_SPLIT]][supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097 1);
4098 tmp_rdc.rdcost =
4099 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4100 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4101 sum_rdc = tmp_rdc;
4102 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4103 supertx_size, pc_tree);
4104 }
4105 }
4106
4107 pc_tree->partitioning = best_partition;
4108 }
4109#endif // CONFIG_SUPERTX
4110 }
4111
Urvang Joshi52648442016-10-13 17:27:51 -07004112 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004113 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
4114 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4115#if CONFIG_SUPERTX
4116 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
4117#endif // CONFIG_SUPERTX
4118
4119 if (sum_rdc.rdcost < best_rdc.rdcost) {
4120 best_rdc = sum_rdc;
4121#if CONFIG_SUPERTX
4122 best_rate_nocoef = sum_rate_nocoef;
4123 assert(best_rate_nocoef >= 0);
4124#endif // CONFIG_SUPERTX
4125 pc_tree->partitioning = PARTITION_SPLIT;
4126 }
Urvang Joshi52648442016-10-13 17:27:51 -07004127 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004128 // skip rectangular partition test when larger block size
4129 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07004130 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004131 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004132#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004133 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004134#else
4135 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4136#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004137 } // if (do_split)
4138
4139 // PARTITION_HORZ
4140 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004141 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07004143 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004144#if CONFIG_DUAL_FILTER
4145 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4146 partition_none_allowed)
4147 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004148 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004149#else
4150 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4151 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004152 pc_tree->horizontal[0].pred_interp_filter =
4153 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004154#endif
4155 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4156#if CONFIG_SUPERTX
4157 &sum_rate_nocoef,
4158#endif // CONFIG_SUPERTX
4159#if CONFIG_EXT_PARTITION_TYPES
4160 PARTITION_HORZ,
4161#endif
4162 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
4163
4164#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08004165 abort_flag =
4166 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4167 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168 if (sum_rdc.rdcost < INT64_MAX &&
4169#else
4170 if (sum_rdc.rdcost < best_rdc.rdcost &&
4171#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004172 !force_horz_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Urvang Joshi454280d2016-10-14 16:51:44 -07004173 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
4174 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004175 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07004176 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004177
Urvang Joshi454280d2016-10-14 16:51:44 -07004178 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004179
4180#if CONFIG_DUAL_FILTER
4181 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4182 partition_none_allowed)
4183 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004184 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004185#else
4186 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4187 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004188 pc_tree->horizontal[1].pred_interp_filter =
4189 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004190#endif
4191#if CONFIG_SUPERTX
4192 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4193 &this_rate_nocoef,
4194#if CONFIG_EXT_PARTITION_TYPES
4195 PARTITION_HORZ,
4196#endif
4197 subsize, &pc_tree->horizontal[1], INT64_MAX);
4198#else
4199 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
4200#if CONFIG_EXT_PARTITION_TYPES
4201 PARTITION_HORZ,
4202#endif
4203 subsize, &pc_tree->horizontal[1],
4204 best_rdc.rdcost - sum_rdc.rdcost);
4205#endif // CONFIG_SUPERTX
4206 if (this_rdc.rate == INT_MAX) {
4207 sum_rdc.rdcost = INT64_MAX;
4208#if CONFIG_SUPERTX
4209 sum_rate_nocoef = INT_MAX;
4210#endif // CONFIG_SUPERTX
4211 } else {
4212 sum_rdc.rate += this_rdc.rate;
4213 sum_rdc.dist += this_rdc.dist;
4214 sum_rdc.rdcost += this_rdc.rdcost;
4215#if CONFIG_SUPERTX
4216 sum_rate_nocoef += this_rate_nocoef;
4217#endif // CONFIG_SUPERTX
4218 }
4219 }
4220
4221#if CONFIG_SUPERTX
4222 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4223 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4224 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4225
4226 pc_tree->partitioning = PARTITION_HORZ;
4227
Yaowu Xuf883b422016-08-30 14:01:10 -07004228 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004229 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4230 [supertx_size],
4231 0);
4232 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4233
4234 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4235 TX_TYPE best_tx = DCT_DCT;
4236 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4237
4238 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4239
4240 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4241 &tmp_rdc.dist, &best_tx, pc_tree);
4242
Yaowu Xuf883b422016-08-30 14:01:10 -07004243 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004244 cm->fc
4245 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
4246 [supertx_size],
4247 1);
4248 tmp_rdc.rdcost =
4249 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4250 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4251 sum_rdc = tmp_rdc;
4252 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4253 supertx_size, pc_tree);
4254 }
4255 }
4256
4257 pc_tree->partitioning = best_partition;
4258 }
4259#endif // CONFIG_SUPERTX
4260
4261 if (sum_rdc.rdcost < best_rdc.rdcost) {
4262 sum_rdc.rate += partition_cost[PARTITION_HORZ];
4263 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4264#if CONFIG_SUPERTX
4265 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
4266#endif // CONFIG_SUPERTX
4267 if (sum_rdc.rdcost < best_rdc.rdcost) {
4268 best_rdc = sum_rdc;
4269#if CONFIG_SUPERTX
4270 best_rate_nocoef = sum_rate_nocoef;
4271 assert(best_rate_nocoef >= 0);
4272#endif // CONFIG_SUPERTX
4273 pc_tree->partitioning = PARTITION_HORZ;
4274 }
4275 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004276#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004277 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004278#else
4279 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4280#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004281 }
4282
4283 // PARTITION_VERT
4284 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004285 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286 subsize = get_subsize(bsize, PARTITION_VERT);
4287
Urvang Joshi454280d2016-10-14 16:51:44 -07004288 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004289
4290#if CONFIG_DUAL_FILTER
4291 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4292 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004293 pc_tree->vertical[0].pred_interp_filter =
4294 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004295#else
4296 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4297 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004298 pc_tree->vertical[0].pred_interp_filter =
4299 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004300#endif
4301 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4302#if CONFIG_SUPERTX
4303 &sum_rate_nocoef,
4304#endif // CONFIG_SUPERTX
4305#if CONFIG_EXT_PARTITION_TYPES
4306 PARTITION_VERT,
4307#endif
4308 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4309#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08004310 abort_flag =
4311 (sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
4312 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004313 if (sum_rdc.rdcost < INT64_MAX &&
4314#else
4315 if (sum_rdc.rdcost < best_rdc.rdcost &&
4316#endif // CONFIG_SUPERTX
Jingning Hanbf9c6b72016-12-14 14:50:45 -08004317 !force_vert_split && (bsize > BLOCK_8X8 || unify_bsize)) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004318 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4319 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4320 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004321
Urvang Joshi454280d2016-10-14 16:51:44 -07004322 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323
4324#if CONFIG_DUAL_FILTER
4325 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4326 partition_none_allowed)
4327 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004328 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004329#else
4330 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4331 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004332 pc_tree->vertical[1].pred_interp_filter =
4333 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004334#endif
4335#if CONFIG_SUPERTX
4336 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4337 &this_rate_nocoef,
4338#if CONFIG_EXT_PARTITION_TYPES
4339 PARTITION_VERT,
4340#endif
4341 subsize, &pc_tree->vertical[1],
4342 INT64_MAX - sum_rdc.rdcost);
4343#else
4344 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4345#if CONFIG_EXT_PARTITION_TYPES
4346 PARTITION_VERT,
4347#endif
4348 subsize, &pc_tree->vertical[1],
4349 best_rdc.rdcost - sum_rdc.rdcost);
4350#endif // CONFIG_SUPERTX
4351 if (this_rdc.rate == INT_MAX) {
4352 sum_rdc.rdcost = INT64_MAX;
4353#if CONFIG_SUPERTX
4354 sum_rate_nocoef = INT_MAX;
4355#endif // CONFIG_SUPERTX
4356 } else {
4357 sum_rdc.rate += this_rdc.rate;
4358 sum_rdc.dist += this_rdc.dist;
4359 sum_rdc.rdcost += this_rdc.rdcost;
4360#if CONFIG_SUPERTX
4361 sum_rate_nocoef += this_rate_nocoef;
4362#endif // CONFIG_SUPERTX
4363 }
4364 }
4365#if CONFIG_SUPERTX
4366 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4367 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4368 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4369
4370 pc_tree->partitioning = PARTITION_VERT;
4371
Yaowu Xuf883b422016-08-30 14:01:10 -07004372 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004373 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4374 [supertx_size],
4375 0);
4376 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4377
4378 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4379 TX_TYPE best_tx = DCT_DCT;
4380 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4381
4382 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4383
4384 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4385 &tmp_rdc.dist, &best_tx, pc_tree);
4386
Yaowu Xuf883b422016-08-30 14:01:10 -07004387 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004388 cm->fc
4389 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4390 [supertx_size],
4391 1);
4392 tmp_rdc.rdcost =
4393 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4394 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4395 sum_rdc = tmp_rdc;
4396 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4397 supertx_size, pc_tree);
4398 }
4399 }
4400
4401 pc_tree->partitioning = best_partition;
4402 }
4403#endif // CONFIG_SUPERTX
4404
4405 if (sum_rdc.rdcost < best_rdc.rdcost) {
4406 sum_rdc.rate += partition_cost[PARTITION_VERT];
4407 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4408#if CONFIG_SUPERTX
4409 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4410#endif // CONFIG_SUPERTX
4411 if (sum_rdc.rdcost < best_rdc.rdcost) {
4412 best_rdc = sum_rdc;
4413#if CONFIG_SUPERTX
4414 best_rate_nocoef = sum_rate_nocoef;
4415 assert(best_rate_nocoef >= 0);
4416#endif // CONFIG_SUPERTX
4417 pc_tree->partitioning = PARTITION_VERT;
4418 }
4419 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004420#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004421 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004422#else
4423 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4424#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004425 }
4426
4427#if CONFIG_EXT_PARTITION_TYPES
4428 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004429 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004430 partition_none_allowed) {
4431 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4432 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004433 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434 PARTITION_HORZ_A,
4435#if CONFIG_SUPERTX
4436 best_rd, &best_rate_nocoef, &x_ctx,
4437#endif
4438 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4439 mi_row + mi_step, mi_col, subsize);
4440 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4441 }
4442 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004443 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004444 partition_none_allowed) {
4445 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4446 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004447 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004448 PARTITION_HORZ_B,
4449#if CONFIG_SUPERTX
4450 best_rd, &best_rate_nocoef, &x_ctx,
4451#endif
4452 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4453 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4454 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4455 }
4456 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004457 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004458 partition_none_allowed) {
4459 subsize = get_subsize(bsize, PARTITION_VERT_A);
4460 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004461 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004462 PARTITION_VERT_A,
4463#if CONFIG_SUPERTX
4464 best_rd, &best_rate_nocoef, &x_ctx,
4465#endif
4466 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4467 mi_row, mi_col + mi_step, subsize);
4468 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4469 }
4470 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004471 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004472 partition_none_allowed) {
4473 subsize = get_subsize(bsize, PARTITION_VERT_B);
4474 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004475 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004476 PARTITION_VERT_B,
4477#if CONFIG_SUPERTX
4478 best_rd, &best_rate_nocoef, &x_ctx,
4479#endif
4480 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4481 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4482 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4483 }
4484#endif // CONFIG_EXT_PARTITION_TYPES
4485
4486 // TODO(jbb): This code added so that we avoid static analysis
4487 // warning related to the fact that best_rd isn't used after this
4488 // point. This code should be refactored so that the duplicate
4489 // checks occur in some sub function and thus are used...
4490 (void)best_rd;
4491 *rd_cost = best_rdc;
4492#if CONFIG_SUPERTX
4493 *rate_nocoef = best_rate_nocoef;
4494#endif // CONFIG_SUPERTX
4495
4496 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4497 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004498 if (bsize == cm->sb_size) {
Yue Chenf27b1602017-01-13 11:11:43 -08004499#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
4500 set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
4501#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004502 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4503 pc_tree, NULL);
4504 } else {
4505 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4506 pc_tree, NULL);
4507 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 }
4509
4510 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004511#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004512 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004513#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004514 assert(best_rdc.rate < INT_MAX);
4515 assert(best_rdc.dist < INT64_MAX);
4516 } else {
4517 assert(tp_orig == *tp);
4518 }
4519}
4520
Yaowu Xuf883b422016-08-30 14:01:10 -07004521static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004522 TileDataEnc *tile_data, int mi_row,
4523 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004524 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004525 const TileInfo *const tile_info = &tile_data->tile_info;
4526 MACROBLOCK *const x = &td->mb;
4527 MACROBLOCKD *const xd = &x->e_mbd;
4528 SPEED_FEATURES *const sf = &cpi->sf;
4529 int mi_col;
4530#if CONFIG_EXT_PARTITION
4531 const int leaf_nodes = 256;
4532#else
4533 const int leaf_nodes = 64;
4534#endif // CONFIG_EXT_PARTITION
4535
4536 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004537 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004538
Thomas Daviesf6936102016-09-05 16:51:31 +01004539#if CONFIG_DELTA_Q
4540 // Reset delta for every tile
4541 if (cm->delta_q_present_flag)
4542 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4543#endif
4544
Yaowu Xuc27fc142016-08-22 16:08:15 -07004545 // Code each SB in the row
4546 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4547 mi_col += cm->mib_size) {
4548 const struct segmentation *const seg = &cm->seg;
4549 int dummy_rate;
4550 int64_t dummy_dist;
4551 RD_COST dummy_rdc;
4552#if CONFIG_SUPERTX
4553 int dummy_rate_nocoef;
4554#endif // CONFIG_SUPERTX
4555 int i;
4556 int seg_skip = 0;
4557
4558 const int idx_str = cm->mi_stride * mi_row + mi_col;
4559 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4560 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4561
Ryan Lei9b02b0e2017-01-30 15:52:20 -08004562 av1_update_boundary_info(cm, tile_info, mi_row, mi_col);
4563
Yaowu Xuc27fc142016-08-22 16:08:15 -07004564 if (sf->adaptive_pred_interp_filter) {
4565 for (i = 0; i < leaf_nodes; ++i)
4566 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4567
4568 for (i = 0; i < leaf_nodes; ++i) {
4569 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4570 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4571 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4572 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4573 }
4574 }
4575
Yaowu Xuf883b422016-08-30 14:01:10 -07004576 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004577 pc_root->index = 0;
4578
4579 if (seg->enabled) {
4580 const uint8_t *const map =
4581 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4582 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4583 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4584 }
4585
Arild Fuldseth07441162016-08-15 15:07:52 +02004586#if CONFIG_DELTA_Q
4587 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004588 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004589 int sb_row = mi_row >> 3;
4590 int sb_col = mi_col >> 3;
4591 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4592 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004593
4594 // Ensure divisibility of delta_qindex by delta_q_res
4595 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4596 int qmask = ~(cm->delta_q_res - 1);
4597 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4598 cm->delta_q_res, 256 - cm->delta_q_res);
4599 current_qindex =
4600 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4601 cm->base_qindex;
4602
Arild Fuldseth07441162016-08-15 15:07:52 +02004603 xd->delta_qindex = current_qindex - cm->base_qindex;
4604 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4605 xd->mi[0]->mbmi.current_q_index = current_qindex;
4606 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004607 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004608 }
4609#endif
4610
Yaowu Xuc27fc142016-08-22 16:08:15 -07004611 x->source_variance = UINT_MAX;
4612 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4613 BLOCK_SIZE bsize;
4614 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4615 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4616 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4617 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4618 &dummy_rate, &dummy_dist,
4619#if CONFIG_SUPERTX
4620 &dummy_rate_nocoef,
4621#endif // CONFIG_SUPERTX
4622 1, pc_root);
4623 } else if (cpi->partition_search_skippable_frame) {
4624 BLOCK_SIZE bsize;
4625 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4626 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4627 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4628 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4629 &dummy_rate, &dummy_dist,
4630#if CONFIG_SUPERTX
4631 &dummy_rate_nocoef,
4632#endif // CONFIG_SUPERTX
4633 1, pc_root);
4634 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4635 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4636 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4637 &dummy_rate, &dummy_dist,
4638#if CONFIG_SUPERTX
4639 &dummy_rate_nocoef,
4640#endif // CONFIG_SUPERTX
4641 1, pc_root);
4642 } else {
4643 // If required set upper and lower partition size limits
4644 if (sf->auto_min_max_partition_size) {
4645 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4646 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4647 &x->min_partition_size, &x->max_partition_size);
4648 }
4649 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4650 &dummy_rdc,
4651#if CONFIG_SUPERTX
4652 &dummy_rate_nocoef,
4653#endif // CONFIG_SUPERTX
4654 INT64_MAX, pc_root);
4655 }
4656 }
4657#if CONFIG_ENTROPY
4658 if (cm->do_subframe_update &&
4659 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
hui su0161a932017-01-24 14:12:11 -08004660 const int mi_rows_per_update =
4661 MI_SIZE * AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1);
4662 if ((mi_row + MI_SIZE) % mi_rows_per_update == 0 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663 mi_row + MI_SIZE < cm->mi_rows &&
4664 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4665 TX_SIZE t;
4666 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4667
Yaowu Xu6b763c92017-01-23 12:13:37 -08004668 for (t = 0; t < TX_SIZES; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004669 av1_full_to_model_counts(cpi->td.counts->coef[t],
4670 cpi->td.rd_counts.coef_counts[t]);
4671 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004673 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4674 cm->fc->coef_probs);
4675 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4676 cpi->td.rd_counts.coef_counts);
4677 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4678 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004679 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004680 }
4681 }
4682#endif // CONFIG_ENTROPY
4683}
4684
Yaowu Xuf883b422016-08-30 14:01:10 -07004685static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004686 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004687 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004688 MACROBLOCKD *const xd = &x->e_mbd;
4689
4690 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004691 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004692
Yaowu Xuf883b422016-08-30 14:01:10 -07004693 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004694}
4695
Zoe Liub05e5d12017-02-07 14:32:53 -08004696#if !CONFIG_REF_ADAPT
Yaowu Xuf883b422016-08-30 14:01:10 -07004697static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 const int ref_flags = cpi->ref_frame_flags;
4699
4700 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4701 return 0;
4702 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004703 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004704#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004705 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4706 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004707#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004708 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004709 }
4710}
Zoe Liub05e5d12017-02-07 14:32:53 -08004711#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07004712
4713#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004714static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004715 int mi_row, mi_col;
4716 const int mis = cm->mi_stride;
4717 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4718
4719 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4720 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4721 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4722 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4723 }
4724 }
4725}
4726#endif
4727
Yaowu Xuf883b422016-08-30 14:01:10 -07004728static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004729 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4730#if CONFIG_EXT_REFS
4731 // We will not update the golden frame with an internal overlay frame
4732 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4733 cpi->rc.is_src_frame_ext_arf)
4734#else
4735 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4736#endif
4737 return ALTREF_FRAME;
4738 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4739 return GOLDEN_FRAME;
4740 else
4741 // TODO(zoeliu): To investigate whether a frame_type other than
4742 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4743 return LAST_FRAME;
4744}
4745
Yaowu Xuf883b422016-08-30 14:01:10 -07004746static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yue Cheneeacc4c2017-01-17 17:29:17 -08004747 int i, all_lossless = 1;
4748
4749 if (cpi->common.seg.enabled) {
4750 for (i = 0; i < MAX_SEGMENTS; ++i) {
4751 if (!xd->lossless[i]) {
4752 all_lossless = 0;
4753 break;
4754 }
4755 }
4756 } else {
4757 all_lossless = xd->lossless[0];
4758 }
4759 if (all_lossless) return ONLY_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004760 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08004761 return ALLOW_32X32 + CONFIG_TX64X64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4763 cpi->sf.tx_size_search_method == USE_TX_8X8)
4764 return TX_MODE_SELECT;
4765 else
4766 return cpi->common.tx_mode;
4767}
4768
Yaowu Xuf883b422016-08-30 14:01:10 -07004769void av1_init_tile_data(AV1_COMP *cpi) {
4770 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004771 const int tile_cols = cm->tile_cols;
4772 const int tile_rows = cm->tile_rows;
4773 int tile_col, tile_row;
4774 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4775 unsigned int tile_tok = 0;
4776
4777 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004778 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4779 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004780 sizeof(*cpi->tile_data)));
4781 cpi->allocated_tiles = tile_cols * tile_rows;
4782
4783 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4784 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4785 TileDataEnc *const tile_data =
4786 &cpi->tile_data[tile_row * tile_cols + tile_col];
4787 int i, j;
4788 for (i = 0; i < BLOCK_SIZES; ++i) {
4789 for (j = 0; j < MAX_MODES; ++j) {
4790 tile_data->thresh_freq_fact[i][j] = 32;
4791 tile_data->mode_map[i][j] = j;
4792 }
4793 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004794#if CONFIG_PVQ
4795 // This will be dynamically increased as more pvq block is encoded.
4796 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004797 CHECK_MEM_ERROR(
4798 cm, tile_data->pvq_q.buf,
4799 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004800 tile_data->pvq_q.curr_pos = 0;
4801#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004802 }
4803 }
4804
4805 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4806 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4807 TileInfo *const tile_info =
4808 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004809 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004810
4811 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4812 pre_tok = cpi->tile_tok[tile_row][tile_col];
4813 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004814#if CONFIG_PVQ
4815 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4816#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004817 }
4818 }
4819}
4820
Yaowu Xuf883b422016-08-30 14:01:10 -07004821void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4822 int tile_col) {
4823 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 TileDataEnc *const this_tile =
4825 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4826 const TileInfo *const tile_info = &this_tile->tile_info;
4827 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4828 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004829#if CONFIG_PVQ
4830 od_adapt_ctx *adapt;
4831#endif
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004832#if CONFIG_DEPENDENT_HORZTILES
4833 if ((!cm->dependent_horz_tiles) || (tile_row == 0)) {
4834 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
4835 }
4836#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004837 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Fangwen Fu7b9f2b32017-01-17 14:01:52 -08004838#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004839
4840 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004841 this_tile->m_search_count = 0; // Count of motion search hits.
4842 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4843 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4844 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004845
Yushin Cho77bba8d2016-11-04 16:36:56 -07004846#if CONFIG_PVQ
4847 td->mb.pvq_q = &this_tile->pvq_q;
4848
Yushin Cho70669122016-12-08 09:53:14 -10004849 // TODO(yushin) : activity masking info needs be signaled by a bitstream
4850 td->mb.daala_enc.use_activity_masking = AV1_PVQ_ENABLE_ACTIVITY_MASKING;
4851
4852 if (td->mb.daala_enc.use_activity_masking)
4853 td->mb.daala_enc.qm = OD_HVS_QM; // Hard coded. Enc/dec required to sync.
4854 else
4855 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4856
Yushin Cho77bba8d2016-11-04 16:36:56 -07004857 {
4858 // FIXME: Multiple segments support
4859 int segment_id = 0;
4860 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4861 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4862 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4863 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4864 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4865 td->mb.daala_enc.pvq_norm_lambda =
4866 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4867 td->mb.daala_enc.pvq_norm_lambda_dc =
4868 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4869 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4870 }
4871 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4872 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
Yushin Cho70669122016-12-08 09:53:14 -10004873
4874 if (td->mb.daala_enc.use_activity_masking) {
4875 int pli;
4876 int use_masking = td->mb.daala_enc.use_activity_masking;
4877 int segment_id = 0;
4878 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4879
4880 for (pli = 0; pli < MAX_MB_PLANE; pli++) {
4881 int i;
4882 int q;
4883
4884 q = qindex;
4885 if (q <= OD_DEFAULT_QMS[use_masking][0][pli].interp_q << OD_COEFF_SHIFT) {
4886 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4887 &OD_DEFAULT_QMS[use_masking][0][pli], NULL);
4888 } else {
4889 i = 0;
4890 while (OD_DEFAULT_QMS[use_masking][i + 1][pli].qm_q4 != NULL &&
4891 q > OD_DEFAULT_QMS[use_masking][i + 1][pli].interp_q
4892 << OD_COEFF_SHIFT) {
4893 i++;
4894 }
4895 od_interp_qm(&td->mb.daala_enc.state.pvq_qm_q4[pli][0], q,
4896 &OD_DEFAULT_QMS[use_masking][i][pli],
4897 &OD_DEFAULT_QMS[use_masking][i + 1][pli]);
4898 }
4899 }
4900 }
4901
Nathan E. Egge6675be02016-12-21 13:02:43 -05004902#if CONFIG_DAALA_EC
4903 od_ec_enc_init(&td->mb.daala_enc.w.ec, 65025);
4904#else
4905#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4906#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004907
4908 adapt = &td->mb.daala_enc.state.adapt;
Nathan E. Egge6675be02016-12-21 13:02:43 -05004909
4910#if CONFIG_DAALA_EC
4911 od_ec_enc_reset(&td->mb.daala_enc.w.ec);
4912#else
4913#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4914#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004915 od_adapt_ctx_reset(adapt, 0);
Yushin Chob39378e2017-02-21 09:39:22 -08004916#endif // #if CONFIG_PVQ
4917
4918#if CONFIG_EC_ADAPT
Thomas Daviesf77d4ad2017-01-10 18:55:42 +00004919 this_tile->tctx = *cm->fc;
4920 td->mb.e_mbd.tile_ctx = &this_tile->tctx;
Yushin Chob39378e2017-02-21 09:39:22 -08004921#endif // #if CONFIG_EC_ADAPT
Yushin Cho77bba8d2016-11-04 16:36:56 -07004922
Yaowu Xuc27fc142016-08-22 16:08:15 -07004923 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4924 mi_row += cm->mib_size) {
4925 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4926 }
4927
4928 cpi->tok_count[tile_row][tile_col] =
4929 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4930 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004931#if CONFIG_PVQ
Nathan E. Egge6675be02016-12-21 13:02:43 -05004932#if CONFIG_DAALA_EC
4933 od_ec_enc_clear(&td->mb.daala_enc.w.ec);
4934#else
4935#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
4936#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07004937
4938 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4939 // rewind current position so that bitstream can be written
4940 // from the 1st pvq block
4941 td->mb.pvq_q->curr_pos = 0;
4942
4943 td->mb.pvq_q = NULL;
4944#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004945}
4946
Yaowu Xuf883b422016-08-30 14:01:10 -07004947static void encode_tiles(AV1_COMP *cpi) {
4948 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004949 int tile_col, tile_row;
4950
Yaowu Xuf883b422016-08-30 14:01:10 -07004951 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004952
4953 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4954 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004955 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004956}
4957
4958#if CONFIG_FP_MB_STATS
4959static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004960 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004961 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4962 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4963
4964 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4965
4966 *this_frame_mb_stats = mb_stats_in;
4967
4968 return 1;
4969}
4970#endif
4971
Yaowu Xuf883b422016-08-30 14:01:10 -07004972static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004973 ThreadData *const td = &cpi->td;
4974 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004975 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004976 MACROBLOCKD *const xd = &x->e_mbd;
4977 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4978 int i;
4979
Yaowu Xuf883b422016-08-30 14:01:10 -07004980 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4981 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Jingning Han24e0a182016-11-20 22:34:12 -08004982#if CONFIG_REF_MV
Dengca8d24d2016-10-17 14:06:35 +08004983 cm->setup_mi(cm);
4984#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004985
4986 xd->mi = cm->mi_grid_visible;
4987 xd->mi[0] = cm->mi;
4988
Yaowu Xuf883b422016-08-30 14:01:10 -07004989 av1_zero(*td->counts);
4990 av1_zero(rdc->coef_counts);
4991 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004992
4993#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004994 av1_zero(cpi->global_motion_used);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004995 if (cpi->common.frame_type == INTER_FRAME && cpi->Source &&
4996 !cpi->global_motion_search_done) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004997 YV12_BUFFER_CONFIG *ref_buf;
4998 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004999 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08005000 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07005001 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
5002 ref_buf = get_ref_frame_buffer(cpi, frame);
5003 if (ref_buf) {
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005004 TransformationType model;
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08005005 aom_clear_system_state();
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005006 for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
5007 if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
David Barker557ce7b2016-11-16 10:22:24 +00005008#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005009 cpi->common.bit_depth,
David Barker557ce7b2016-11-16 10:22:24 +00005010#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005011 params)) {
5012 convert_model_to_params(params, &cm->global_motion[frame]);
5013 if (cm->global_motion[frame].wmtype != IDENTITY) {
5014 erroradvantage = refine_integerized_param(
5015 &cm->global_motion[frame], cm->global_motion[frame].wmtype,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07005016#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005017 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Sarah Parkerf41a06b2016-10-25 14:42:47 -07005018#endif // CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005019 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
5020 ref_buf->y_stride, cpi->Source->y_buffer,
5021 cpi->Source->y_width, cpi->Source->y_height,
5022 cpi->Source->y_stride, 3);
5023 if (erroradvantage >
5024 gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
5025 set_default_gmparams(&cm->global_motion[frame]);
5026 }
Debargha Mukherjeee3e00792016-11-13 11:35:44 -08005027 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005028 }
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -08005029 if (cm->global_motion[frame].wmtype != IDENTITY) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005030 }
Debargha Mukherjee53291fa2016-11-14 18:29:03 -08005031 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005032 }
5033 }
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08005034 cpi->global_motion_search_done = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005035 }
5036#endif // CONFIG_GLOBAL_MOTION
5037
5038 for (i = 0; i < MAX_SEGMENTS; ++i) {
5039 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07005040 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005041 : cm->base_qindex;
5042 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
5043 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
Yue Cheneeacc4c2017-01-17 17:29:17 -08005044 xd->qindex[i] = qindex;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005045 }
5046
5047 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
5048
5049 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07005050 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005051
Yaowu Xuf883b422016-08-30 14:01:10 -07005052 av1_initialize_rd_consts(cpi);
5053 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005054 init_encode_frame_mb_context(cpi);
Fangwen Fu8d164de2016-12-14 13:40:54 -08005055#if CONFIG_TEMPMV_SIGNALING
5056 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
5057 if (last_fb_buf_idx != INVALID_IDX) {
5058 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
5059 cm->use_prev_frame_mvs &= !cm->error_resilient_mode &&
5060 cm->width == cm->prev_frame->buf.y_width &&
5061 cm->height == cm->prev_frame->buf.y_height &&
5062 !cm->intra_only && !cm->prev_frame->intra_only;
5063 }
5064#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005065 cm->use_prev_frame_mvs =
5066 !cm->error_resilient_mode && cm->width == cm->last_width &&
5067 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Fangwen Fu8d164de2016-12-14 13:40:54 -08005068#endif
Thomas Daviesf6936102016-09-05 16:51:31 +01005069
5070#if CONFIG_DELTA_Q
5071 // Fix delta q resolution for the moment
5072 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
5073#endif
5074
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075#if CONFIG_EXT_REFS
5076 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
5077 // show_exisiting_frame=1, nor can it take a frame not used as
5078 // a reference, it is probable that by the time it is being
5079 // referred to, the frame buffer it originally points to may
5080 // already get expired and have been reassigned to the current
5081 // newly coded frame. Hence, we need to check whether this is
5082 // the case, and if yes, we have 2 choices:
5083 // (1) Simply disable the use of previous frame mvs; or
5084 // (2) Have cm->prev_frame point to one reference frame buffer,
5085 // e.g. LAST_FRAME.
5086 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
5087 // Reassign the LAST_FRAME buffer to cm->prev_frame.
5088 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
5089 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
5090 }
5091#endif // CONFIG_EXT_REFS
5092
5093 // Special case: set prev_mi to NULL when the previous mode info
5094 // context cannot be used.
5095 cm->prev_mi =
5096 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
5097
5098#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005099 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005100#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07005101 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005102#endif
5103#endif
5104
5105 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
5106 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07005107 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108
5109 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005110 struct aom_usec_timer emr_timer;
5111 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005112
5113#if CONFIG_FP_MB_STATS
5114 if (cpi->use_fp_mb_stats) {
5115 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
5116 &cpi->twopass.this_frame_mb_stats);
5117 }
5118#endif
5119
5120 // If allowed, encoding tiles in parallel with one thread handling one tile.
5121 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
5122 // 1 tile rows, as it uses the single above_context et al arrays from
5123 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07005124 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
5125 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 else
5127 encode_tiles(cpi);
5128
Yaowu Xuf883b422016-08-30 14:01:10 -07005129 aom_usec_timer_mark(&emr_timer);
5130 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131 }
5132
5133#if 0
5134 // Keep record of the total distortion this time around for future use
5135 cpi->last_frame_distortion = cpi->frame_distortion;
5136#endif
5137}
5138
Yaowu Xuf883b422016-08-30 14:01:10 -07005139void av1_encode_frame(AV1_COMP *cpi) {
5140 AV1_COMMON *const cm = &cpi->common;
Sarah Parkere68a3e42017-02-16 14:03:24 -08005141#if CONFIG_EXT_TX
5142 // Indicates whether or not to use a default reduced set for ext-tx
5143 // rather than the potential full set of 16 transforms
5144 cm->reduced_tx_set_used = 0;
5145#endif // CONFIG_EXT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146
5147 // In the longer term the encoder should be generalized to match the
5148 // decoder such that we allow compound where one of the 3 buffers has a
5149 // different sign bias and that buffer is then the fixed ref. However, this
5150 // requires further work in the rd loop. For now the only supported encoder
5151 // side behavior is where the ALT ref buffer has opposite sign bias to
5152 // the other two.
5153 if (!frame_is_intra_only(cm)) {
5154 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5155 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
5156 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
5157 cm->ref_frame_sign_bias[LAST_FRAME])) {
5158 cpi->allow_comp_inter_inter = 0;
5159 } else {
5160 cpi->allow_comp_inter_inter = 1;
5161
5162#if CONFIG_EXT_REFS
5163 cm->comp_fwd_ref[0] = LAST_FRAME;
5164 cm->comp_fwd_ref[1] = LAST2_FRAME;
5165 cm->comp_fwd_ref[2] = LAST3_FRAME;
5166 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
5167 cm->comp_bwd_ref[0] = BWDREF_FRAME;
5168 cm->comp_bwd_ref[1] = ALTREF_FRAME;
5169#else
5170 cm->comp_fixed_ref = ALTREF_FRAME;
5171 cm->comp_var_ref[0] = LAST_FRAME;
5172 cm->comp_var_ref[1] = GOLDEN_FRAME;
5173#endif // CONFIG_EXT_REFS
5174 }
5175 } else {
5176 cpi->allow_comp_inter_inter = 0;
5177 }
5178
5179 if (cpi->sf.frame_parameter_update) {
5180 int i;
5181 RD_OPT *const rd_opt = &cpi->rd;
5182 FRAME_COUNTS *counts = cpi->td.counts;
5183 RD_COUNTS *const rdc = &cpi->td.rd_counts;
5184
5185 // This code does a single RD pass over the whole frame assuming
5186 // either compound, single or hybrid prediction as per whatever has
5187 // worked best for that type of frame in the past.
5188 // It also predicts whether another coding mode would have worked
5189 // better than this coding mode. If that is the case, it remembers
5190 // that for subsequent frames.
5191 // It does the same analysis for transform size selection also.
5192 //
5193 // TODO(zoeliu): To investigate whether a frame_type other than
5194 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
5195 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
5196 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
5197 const int is_alt_ref = frame_type == ALTREF_FRAME;
5198
Zoe Liub05e5d12017-02-07 14:32:53 -08005199/* prediction (compound, single or hybrid) mode selection */
5200#if CONFIG_REF_ADAPT
5201 // NOTE(zoeliu): "is_alt_ref" is true only for OVERLAY/INTNL_OVERLAY frames
5202 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5203 cm->reference_mode = SINGLE_REFERENCE;
5204 else
5205 cm->reference_mode = REFERENCE_MODE_SELECT;
5206#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005207 if (is_alt_ref || !cpi->allow_comp_inter_inter)
5208 cm->reference_mode = SINGLE_REFERENCE;
5209 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
5210 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
5211 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
5212 cm->reference_mode = COMPOUND_REFERENCE;
5213 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
5214 cm->reference_mode = SINGLE_REFERENCE;
5215 else
5216 cm->reference_mode = REFERENCE_MODE_SELECT;
Zoe Liub05e5d12017-02-07 14:32:53 -08005217#endif // CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005218
5219#if CONFIG_DUAL_FILTER
5220 cm->interp_filter = SWITCHABLE;
5221#endif
5222
5223 encode_frame_internal(cpi);
5224
5225 for (i = 0; i < REFERENCE_MODES; ++i)
5226 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
5227
5228 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5229 int single_count_zero = 0;
5230 int comp_count_zero = 0;
5231
5232 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5233 single_count_zero += counts->comp_inter[i][0];
5234 comp_count_zero += counts->comp_inter[i][1];
5235 }
5236
5237 if (comp_count_zero == 0) {
5238 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005239 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08005240#if !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005241 } else if (single_count_zero == 0) {
5242 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005243 av1_zero(counts->comp_inter);
Zoe Liub05e5d12017-02-07 14:32:53 -08005244#endif // !CONFIG_REF_ADAPT
Yaowu Xuc27fc142016-08-22 16:08:15 -07005245 }
5246 }
5247
Jingning Han9777afc2016-10-20 15:17:43 -07005248#if CONFIG_VAR_TX
5249 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005250 cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
Jingning Han9777afc2016-10-20 15:17:43 -07005251#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005252 if (cm->tx_mode == TX_MODE_SELECT) {
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005253#if CONFIG_TX64X64
5254 int count4x4 = 0;
5255 int count8x8_8x8p = 0, count8x8_lp = 0;
5256 int count16x16_16x16p = 0, count16x16_lp = 0;
5257 int count32x32_32x32p = 0, count32x32_lp = 0;
5258 int count64x64_64x64p = 0;
5259 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
5260 // counts->tx_size[max_depth][context_idx][this_depth_level]
5261 count4x4 += counts->tx_size[0][i][0];
5262 count4x4 += counts->tx_size[1][i][0];
5263 count4x4 += counts->tx_size[2][i][0];
5264 count4x4 += counts->tx_size[3][i][0];
5265
5266 count8x8_8x8p += counts->tx_size[0][i][1];
5267 count8x8_lp += counts->tx_size[1][i][1];
5268 count8x8_lp += counts->tx_size[2][i][1];
5269 count8x8_lp += counts->tx_size[3][i][1];
5270
5271 count16x16_16x16p += counts->tx_size[1][i][2];
5272 count16x16_lp += counts->tx_size[2][i][2];
5273 count16x16_lp += counts->tx_size[3][i][2];
5274
5275 count32x32_32x32p += counts->tx_size[2][i][3];
5276 count32x32_lp += counts->tx_size[3][i][3];
5277
5278 count64x64_64x64p += counts->tx_size[3][i][4];
5279 }
5280#if CONFIG_EXT_TX && CONFIG_RECT_TX
5281 count4x4 += counts->tx_size_implied[0][TX_4X4];
5282 count4x4 += counts->tx_size_implied[1][TX_4X4];
5283 count4x4 += counts->tx_size_implied[2][TX_4X4];
5284 count4x4 += counts->tx_size_implied[3][TX_4X4];
5285 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5286 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5287 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5288 count8x8_lp += counts->tx_size_implied[4][TX_8X8];
5289 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5290 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5291 count16x16_lp += counts->tx_size_implied[4][TX_16X16];
5292 count32x32_32x32p += counts->tx_size_implied[3][TX_32X32];
5293 count32x32_lp += counts->tx_size_implied[4][TX_32X32];
Debargha Mukherjee5a488a62016-11-22 22:24:10 -08005294 count64x64_64x64p += counts->tx_size_implied[4][TX_64X64];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005295#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5296 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5297 count32x32_lp == 0 && count32x32_32x32p == 0 &&
5298#if CONFIG_SUPERTX
5299 cm->counts.supertx_size[TX_16X16] == 0 &&
5300 cm->counts.supertx_size[TX_32X32] == 0 &&
5301 cm->counts.supertx_size[TX_64X64] == 0 &&
5302#endif
5303 count64x64_64x64p == 0) {
5304 cm->tx_mode = ALLOW_8X8;
5305 reset_skip_tx_size(cm, TX_8X8);
5306 } else if (count8x8_8x8p == 0 && count8x8_lp == 0 &&
5307 count16x16_16x16p == 0 && count16x16_lp == 0 &&
5308 count32x32_32x32p == 0 && count32x32_lp == 0 &&
5309#if CONFIG_SUPERTX
5310 cm->counts.supertx_size[TX_8X8] == 0 &&
5311 cm->counts.supertx_size[TX_16X16] == 0 &&
5312 cm->counts.supertx_size[TX_32X32] == 0 &&
5313 cm->counts.supertx_size[TX_64X64] == 0 &&
5314#endif
5315 count64x64_64x64p == 0) {
5316 cm->tx_mode = ONLY_4X4;
5317 reset_skip_tx_size(cm, TX_4X4);
5318 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5319 count32x32_lp == 0) {
5320 cm->tx_mode = ALLOW_64X64;
5321 } else if (count4x4 == 0 && count8x8_lp == 0 && count16x16_lp == 0 &&
5322#if CONFIG_SUPERTX
5323 cm->counts.supertx_size[TX_64X64] == 0 &&
5324#endif
5325 count64x64_64x64p == 0) {
5326 cm->tx_mode = ALLOW_32X32;
5327 reset_skip_tx_size(cm, TX_32X32);
5328 } else if (count4x4 == 0 && count8x8_lp == 0 && count32x32_lp == 0 &&
5329 count32x32_32x32p == 0 &&
5330#if CONFIG_SUPERTX
5331 cm->counts.supertx_size[TX_32X32] == 0 &&
5332 cm->counts.supertx_size[TX_64X64] == 0 &&
5333#endif
5334 count64x64_64x64p == 0) {
5335 cm->tx_mode = ALLOW_16X16;
5336 reset_skip_tx_size(cm, TX_16X16);
5337 }
5338
5339#else // CONFIG_TX64X64
5340
Yaowu Xuc27fc142016-08-22 16:08:15 -07005341 int count4x4 = 0;
5342 int count8x8_lp = 0, count8x8_8x8p = 0;
5343 int count16x16_16x16p = 0, count16x16_lp = 0;
5344 int count32x32 = 0;
5345 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005346 // counts->tx_size[max_depth][context_idx][this_depth_level]
5347 count4x4 += counts->tx_size[0][i][0];
5348 count4x4 += counts->tx_size[1][i][0];
5349 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005350
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005351 count8x8_8x8p += counts->tx_size[0][i][1];
Jingning Han2adcfb12016-10-27 11:19:53 -07005352 count8x8_lp += counts->tx_size[1][i][1];
5353 count8x8_lp += counts->tx_size[2][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005354
Jingning Han2adcfb12016-10-27 11:19:53 -07005355 count16x16_16x16p += counts->tx_size[1][i][2];
5356 count16x16_lp += counts->tx_size[2][i][2];
5357 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005358 }
5359#if CONFIG_EXT_TX && CONFIG_RECT_TX
5360 count4x4 += counts->tx_size_implied[0][TX_4X4];
5361 count4x4 += counts->tx_size_implied[1][TX_4X4];
5362 count4x4 += counts->tx_size_implied[2][TX_4X4];
5363 count4x4 += counts->tx_size_implied[3][TX_4X4];
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005364 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005365 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5366 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005367 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5368 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5369 count32x32 += counts->tx_size_implied[3][TX_32X32];
5370#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5371 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5372#if CONFIG_SUPERTX
5373 cm->counts.supertx_size[TX_16X16] == 0 &&
5374 cm->counts.supertx_size[TX_32X32] == 0 &&
5375#endif // CONFIG_SUPERTX
5376 count32x32 == 0) {
5377 cm->tx_mode = ALLOW_8X8;
5378 reset_skip_tx_size(cm, TX_8X8);
5379 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5380 count8x8_lp == 0 && count16x16_lp == 0 &&
5381#if CONFIG_SUPERTX
5382 cm->counts.supertx_size[TX_8X8] == 0 &&
5383 cm->counts.supertx_size[TX_16X16] == 0 &&
5384 cm->counts.supertx_size[TX_32X32] == 0 &&
5385#endif // CONFIG_SUPERTX
5386 count32x32 == 0) {
5387 cm->tx_mode = ONLY_4X4;
5388 reset_skip_tx_size(cm, TX_4X4);
5389 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5390 cm->tx_mode = ALLOW_32X32;
5391 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5392#if CONFIG_SUPERTX
5393 cm->counts.supertx_size[TX_32X32] == 0 &&
5394#endif // CONFIG_SUPERTX
5395 count4x4 == 0) {
5396 cm->tx_mode = ALLOW_16X16;
5397 reset_skip_tx_size(cm, TX_16X16);
5398 }
Debargha Mukherjee18d38f62016-11-17 20:30:16 -08005399#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07005400 }
5401#endif
5402 } else {
5403 encode_frame_internal(cpi);
5404 }
5405}
5406
5407static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5408 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
Jingning Han36fe3202017-02-20 22:31:49 -08005409 const int intraonly, const int mi_row,
5410 const int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005411 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5412 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5413 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005414 const int unify_bsize = CONFIG_CB4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005415
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005416 if (bsize < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 int idx, idy;
5418 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5419 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5420 for (idy = 0; idy < 2; idy += num_4x4_h)
5421 for (idx = 0; idx < 2; idx += num_4x4_w) {
5422 const int bidx = idy * 2 + idx;
5423 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5424 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005425 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5426 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005427 ++counts->kf_y_mode[a][l][bmode];
5428 } else {
5429 ++counts->y_mode[0][bmode];
5430 }
5431 }
5432 } else {
5433 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005434 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5435 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005436 ++counts->kf_y_mode[above][left][y_mode];
5437 } else {
5438 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5439 }
5440 }
5441
Jingning Han36fe3202017-02-20 22:31:49 -08005442#if CONFIG_CB4X4
5443 if (bsize < BLOCK_8X8 && !is_chroma_reference(mi_row, mi_col)) return;
5444#else
5445 (void)mi_row;
5446 (void)mi_col;
5447#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005448 ++counts->uv_mode[y_mode][uv_mode];
5449}
5450
5451#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005452static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005453 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005454 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005455 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5456 const int tx_row = blk_row >> 1;
5457 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005458 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5459 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005460 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005461 xd->left_txfm_context + tx_row,
5462 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005463 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5464
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5466
5467 if (tx_size == plane_tx_size) {
5468 ++counts->txfm_partition[ctx][0];
5469 mbmi->tx_size = tx_size;
5470 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005471 xd->left_txfm_context + tx_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005472 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005473 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5474 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005475 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005476
Yaowu Xuc27fc142016-08-22 16:08:15 -07005477 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005478 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005479
5480 if (tx_size == TX_8X8) {
5481 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5482 mbmi->tx_size = TX_4X4;
5483 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005484 xd->left_txfm_context + tx_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005485 return;
5486 }
5487
5488 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005489 int offsetr = (i >> 1) * bs;
5490 int offsetc = (i & 0x01) * bs;
5491 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5492 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005493 }
5494 }
5495}
5496
Jingning Han9777afc2016-10-20 15:17:43 -07005497static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5498 BLOCK_SIZE plane_bsize, int mi_row,
5499 int mi_col, FRAME_COUNTS *td_counts) {
5500 MACROBLOCKD *xd = &x->e_mbd;
Jingning Han9ca05b72017-01-03 14:41:36 -08005501 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
5502 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005503 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005504 const int bh = tx_size_high_unit[max_tx_size];
5505 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005506 int idx, idy;
5507
5508 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5509 xd->left_txfm_context =
5510 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5511
5512 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005513 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005514 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5515 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005516}
5517
5518static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5519 int blk_col) {
5520 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5521 const int tx_row = blk_row >> 1;
5522 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005523 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5524 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005525 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5526
Yaowu Xuc27fc142016-08-22 16:08:15 -07005527 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5528
5529 if (tx_size == plane_tx_size) {
5530 mbmi->tx_size = tx_size;
5531 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005532 xd->left_txfm_context + tx_row, tx_size, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005533
5534 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005535 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5536 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005537 int i;
5538
5539 if (tx_size == TX_8X8) {
5540 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5541 mbmi->tx_size = TX_4X4;
5542 txfm_partition_update(xd->above_txfm_context + tx_col,
Jingning Han581d1692017-01-05 16:03:54 -08005543 xd->left_txfm_context + tx_row, TX_4X4, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005544 return;
5545 }
5546
5547 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005548 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005549 int offsetr = (i >> 1) * bsl;
5550 int offsetc = (i & 0x01) * bsl;
5551 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005552 }
5553 }
5554}
5555
Urvang Joshi52648442016-10-13 17:27:51 -07005556static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5557 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5558 int mi_row, int mi_col) {
Jingning Han9ca05b72017-01-03 14:41:36 -08005559 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
5560 const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005561 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005562 const int bh = tx_size_high_unit[max_tx_size];
5563 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005564 int idx, idy;
5565
5566 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5567 xd->left_txfm_context =
5568 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5569
5570 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005571 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005572 set_txfm_context(xd, max_tx_size, idy, idx);
5573}
5574#endif
5575
Urvang Joshi52648442016-10-13 17:27:51 -07005576static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5577 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5578 int mi_col, BLOCK_SIZE bsize,
5579 PICK_MODE_CONTEXT *ctx, int *rate) {
5580 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005581 MACROBLOCK *const x = &td->mb;
5582 MACROBLOCKD *const xd = &x->e_mbd;
5583 MODE_INFO **mi_8x8 = xd->mi;
5584 MODE_INFO *mi = mi_8x8[0];
5585 MB_MODE_INFO *mbmi = &mi->mbmi;
5586 const int seg_skip =
5587 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5588 const int mis = cm->mi_stride;
Jingning Hanc709e1f2016-12-06 14:48:09 -08005589 const int mi_width = mi_size_wide[bsize];
5590 const int mi_height = mi_size_high[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005591 const int is_inter = is_inter_block(mbmi);
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005592#if CONFIG_CB4X4
5593 const int unify_bsize = 1;
5594 const BLOCK_SIZE block_size = bsize;
5595#else
5596 const int unify_bsize = 0;
5597 const BLOCK_SIZE block_size = AOMMAX(bsize, BLOCK_8X8);
5598#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599
Yushin Cho77bba8d2016-11-04 16:36:56 -07005600#if CONFIG_PVQ
5601 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005602 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005603#endif
5604
Jingning Han94ea1aa2016-11-08 12:10:46 -08005605 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005606 int plane;
5607 mbmi->skip = 1;
5608 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Jingning Han18c53c82017-02-17 14:49:57 -08005609 av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
5610 mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005611 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005612 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
Jingning Han36fe3202017-02-20 22:31:49 -08005613 frame_is_intra_only(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614
hui su5db97432016-10-14 16:10:14 -07005615 // TODO(huisu): move this into sum_intra_stats().
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005616 if (!dry_run && (bsize >= BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005617 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005618 (void)counts;
5619#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005620 if (mbmi->mode == DC_PRED
5621#if CONFIG_PALETTE
5622 && mbmi->palette_mode_info.palette_size[0] == 0
5623#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005624 ) {
5625 const int use_filter_intra_mode =
5626 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5627 ++counts->filter_intra[0][use_filter_intra_mode];
5628 }
Urvang Joshib100db72016-10-12 16:28:56 -07005629 if (mbmi->uv_mode == DC_PRED
5630#if CONFIG_PALETTE
5631 && mbmi->palette_mode_info.palette_size[1] == 0
5632#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005633 ) {
5634 const int use_filter_intra_mode =
5635 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5636 ++counts->filter_intra[1][use_filter_intra_mode];
5637 }
5638#endif // CONFIG_FILTER_INTRA
5639#if CONFIG_EXT_INTRA
hui sueda3d762016-12-06 16:58:23 -08005640#if CONFIG_INTRA_INTERP
hui su45dc5972016-12-08 17:42:50 -08005641 if (av1_is_directional_mode(mbmi->mode, bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005642 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005643 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
hui su45dc5972016-12-08 17:42:50 -08005644 p_angle = mode_to_angle_map[mbmi->mode] +
5645 mbmi->angle_delta[0] * av1_get_angle_step(mbmi->sb_type, 0);
Yaowu Xuf883b422016-08-30 14:01:10 -07005646 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005647 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5648 }
hui sueda3d762016-12-06 16:58:23 -08005649#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -07005650#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005651 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005652
Urvang Joshib100db72016-10-12 16:28:56 -07005653#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005654 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655 for (plane = 0; plane <= 1; ++plane) {
5656 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5657 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5658 xd->plane[plane].color_index_map[0];
5659 // TODO(huisu): this increases the use of token buffer. Needs stretch
5660 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005661 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005662 }
5663 }
5664 }
Urvang Joshib100db72016-10-12 16:28:56 -07005665#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005666#if CONFIG_VAR_TX
5667 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5668#endif
Jingning Han18c53c82017-02-17 14:49:57 -08005669 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005670 } else {
5671 int ref;
5672 const int is_compound = has_second_ref(mbmi);
5673
5674 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5675 for (ref = 0; ref < 1 + is_compound; ++ref) {
5676 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5677 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005678 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5679 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005680 }
Yue Chen69f18e12016-09-08 14:48:15 -07005681#if CONFIG_WARPED_MOTION
5682 if (mbmi->motion_mode == WARPED_CAUSAL) {
5683 int i;
5684#if CONFIG_AOM_HIGHBITDEPTH
5685 int use_hbd = xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH;
5686#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005687
Yue Chen69f18e12016-09-08 14:48:15 -07005688 for (i = 0; i < 3; ++i) {
5689 const struct macroblockd_plane *pd = &xd->plane[i];
5690
5691 av1_warp_plane(&mbmi->wm_params[0],
5692#if CONFIG_AOM_HIGHBITDEPTH
5693 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
5694#endif // CONFIG_AOM_HIGHBITDEPTH
5695 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
5696 pd->pre[0].stride, pd->dst.buf,
5697 ((mi_col * MI_SIZE) >> pd->subsampling_x),
5698 ((mi_row * MI_SIZE) >> pd->subsampling_y),
Jingning Hanff6ee6a2016-12-07 09:55:21 -08005699 xd->n8_w * (MI_SIZE >> pd->subsampling_x),
5700 xd->n8_h * (MI_SIZE >> pd->subsampling_y),
5701 pd->dst.stride, pd->subsampling_x, pd->subsampling_y, 16,
5702 16, 0);
Yue Chen69f18e12016-09-08 14:48:15 -07005703 }
5704 } else {
5705#endif // CONFIG_WARPED_MOTION
5706 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005707 av1_build_inter_predictors_sby(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005708
Jingning Hanbf9c6b72016-12-14 14:50:45 -08005709 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col, NULL, block_size);
Yue Chen69f18e12016-09-08 14:48:15 -07005710#if CONFIG_WARPED_MOTION
5711 }
5712#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07005713
Yue Chencb60b182016-10-13 15:18:22 -07005714#if CONFIG_MOTION_VAR
5715 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chenf27b1602017-01-13 11:11:43 -08005716#if CONFIG_NCOBMC
5717 if (dry_run == OUTPUT_ENABLED)
5718 av1_build_ncobmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
5719 else
5720#endif
5721 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005722 }
Yue Chencb60b182016-10-13 15:18:22 -07005723#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005724
Jingning Han18c53c82017-02-17 14:49:57 -08005725 av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005727 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Jingning Han9ca05b72017-01-03 14:41:36 -08005728 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col, block_size,
5729 rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005730#else
Jingning Han18c53c82017-02-17 14:49:57 -08005731 av1_tokenize_sb(cpi, td, t, dry_run, block_size, rate, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005732#endif
5733 }
5734
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005735 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005736#if CONFIG_VAR_TX
5737 TX_SIZE tx_size =
5738 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5739#else
5740 TX_SIZE tx_size = mbmi->tx_size;
5741#endif
Jingning Han581d1692017-01-05 16:03:54 -08005742 if (cm->tx_mode == TX_MODE_SELECT &&
Jingning Han3daa4fd2017-01-20 10:33:50 -08005743#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_RECT_TX)
Jingning Hancb512282017-02-10 14:21:35 -08005744#if CONFIG_RECT_TX
Jingning Han3daa4fd2017-01-20 10:33:50 -08005745 mbmi->sb_type > BLOCK_4X4 &&
Jingning Han581d1692017-01-05 16:03:54 -08005746#else
Jingning Hancb512282017-02-10 14:21:35 -08005747 (mbmi->sb_type >= BLOCK_8X8 ||
5748 (mbmi->sb_type > BLOCK_4X4 && is_inter)) &&
5749#endif
5750#else
Jingning Han581d1692017-01-05 16:03:54 -08005751 mbmi->sb_type >= BLOCK_8X8 &&
5752#endif
Jingning Han94ea1aa2016-11-08 12:10:46 -08005753 !(is_inter && (mbmi->skip || seg_skip))) {
Jingning Han581d1692017-01-05 16:03:54 -08005754#if CONFIG_VAR_TX
5755 if (is_inter) {
5756 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5757 } else {
5758 const int tx_size_ctx = get_tx_size_context(xd);
5759 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5760 : intra_tx_size_cat_lookup[bsize];
5761 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
5762 const int depth = tx_size_to_depth(coded_tx_size);
5763 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5764 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
5765 }
5766#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005767 const int tx_size_ctx = get_tx_size_context(xd);
5768 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5769 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005770 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005771 const int depth = tx_size_to_depth(coded_tx_size);
Jingning Han581d1692017-01-05 16:03:54 -08005772
5773 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
5774#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005775#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005776 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005777#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005778 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005779 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005780 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005781 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005782 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005783 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005784 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005785 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005786 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005787 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005788 } else {
Urvang Joshifeb925f2016-12-05 10:37:29 -08005789#if CONFIG_EXT_TX && CONFIG_RECT_TX
5790 intra_tx_size = tx_size;
5791#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005792 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Urvang Joshifeb925f2016-12-05 10:37:29 -08005793#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005794 }
Urvang Joshifeb925f2016-12-05 10:37:29 -08005795#if CONFIG_EXT_TX && CONFIG_RECT_TX
5796 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
5797 [txsize_sqr_up_map[tx_size]];
5798#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005799
Urvang Joshi454280d2016-10-14 16:51:44 -07005800 for (j = 0; j < mi_height; j++)
5801 for (i = 0; i < mi_width; i++)
5802 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005803 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005804
5805#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005806 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5807 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005808#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809 }
Jingning Han9777afc2016-10-20 15:17:43 -07005810
Jingning Hane67b38a2016-11-04 10:30:00 -07005811 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005812 ++td->counts
5813 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005814#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08005815 if (get_ext_tx_types(tx_size, bsize, is_inter, cm->reduced_tx_set_used) >
5816 1 &&
5817 cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005818 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Sarah Parkere68a3e42017-02-16 14:03:24 -08005819 const int eset =
5820 get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005822 if (is_inter) {
clang-format55ce9e02017-02-15 22:27:12 -08005823 ++td->counts
5824 ->inter_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005825 } else {
Urvang Joshifeb925f2016-12-05 10:37:29 -08005826 ++td->counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
5827 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005828 }
5829 }
5830 }
5831#else
Yaowu Xu7a08fe52017-02-13 18:49:29 -08005832 if (tx_size < TX_32X32 &&
5833 ((!cm->seg.enabled && cm->base_qindex > 0) ||
5834 (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
5835 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005837 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005838 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005839 } else {
clang-format55ce9e02017-02-15 22:27:12 -08005840 ++td->counts
5841 ->intra_ext_tx[tx_size][intra_mode_to_tx_type_context[mbmi->mode]]
5842 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005843 }
5844 }
5845#endif // CONFIG_EXT_TX
5846 }
5847
5848#if CONFIG_VAR_TX
Jingning Han581d1692017-01-05 16:03:54 -08005849 if (cm->tx_mode == TX_MODE_SELECT &&
5850#if CONFIG_CB4X4
Jingning Han3daa4fd2017-01-20 10:33:50 -08005851 mbmi->sb_type > BLOCK_4X4 &&
Jingning Han581d1692017-01-05 16:03:54 -08005852#else
5853 mbmi->sb_type >= BLOCK_8X8 &&
5854#endif
5855 is_inter && !(mbmi->skip || seg_skip)) {
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005856 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005857 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005858 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005859 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005860 if (is_inter)
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005861 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005862 else
Jingning Han3daa4fd2017-01-20 10:33:50 -08005863 tx_size = (bsize > BLOCK_4X4) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005864 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005865 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005866 }
Jingning Hanfe45b212016-11-22 10:30:23 -08005867#endif // CONFIG_VAR_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005868}
5869
5870#if CONFIG_SUPERTX
5871static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5872 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5873#if CONFIG_EXT_INTER
5874 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5875#endif // CONFIG_EXT_INTER
5876 return 0;
5877}
5878
Urvang Joshi52648442016-10-13 17:27:51 -07005879static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5880 int mi_row, int mi_col, BLOCK_SIZE bsize,
5881 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005882 const AV1_COMMON *const cm = &cpi->common;
Jingning Han1856e432016-12-21 14:58:39 -08005883 const int hbs = mi_size_wide[bsize] / 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005884 const PARTITION_TYPE partition = pc_tree->partitioning;
5885 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5886#if CONFIG_EXT_PARTITION_TYPES
5887 int i;
5888#endif
Jingning Hanfeb517c2016-12-21 16:02:07 -08005889#if CONFIG_CB4X4
5890 const int unify_bsize = 1;
5891#else
5892 const int unify_bsize = 0;
5893#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005894
Jingning Hanfeb517c2016-12-21 16:02:07 -08005895#if !CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07005896 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08005897#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005898
5899 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5900
5901 switch (partition) {
5902 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5903 case PARTITION_VERT:
5904 if (check_intra_b(&pc_tree->vertical[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005905 if (mi_col + hbs < cm->mi_cols && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005906 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5907 }
5908 break;
5909 case PARTITION_HORZ:
5910 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
Jingning Hanfeb517c2016-12-21 16:02:07 -08005911 if (mi_row + hbs < cm->mi_rows && (bsize > BLOCK_8X8 || unify_bsize)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005912 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5913 }
5914 break;
5915 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08005916 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005917 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5918 } else {
5919 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5920 pc_tree->split[0]))
5921 return 1;
5922 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5923 pc_tree->split[1]))
5924 return 1;
5925 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5926 pc_tree->split[2]))
5927 return 1;
5928 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5929 pc_tree->split[3]))
5930 return 1;
5931 }
5932 break;
5933#if CONFIG_EXT_PARTITION_TYPES
5934 case PARTITION_HORZ_A:
5935 for (i = 0; i < 3; i++) {
5936 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5937 }
5938 break;
5939 case PARTITION_HORZ_B:
5940 for (i = 0; i < 3; i++) {
5941 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5942 }
5943 break;
5944 case PARTITION_VERT_A:
5945 for (i = 0; i < 3; i++) {
5946 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5947 }
5948 break;
5949 case PARTITION_VERT_B:
5950 for (i = 0; i < 3; i++) {
5951 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5952 }
5953 break;
5954#endif // CONFIG_EXT_PARTITION_TYPES
5955 default: assert(0);
5956 }
5957 return 0;
5958}
5959
5960static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5961 return ctx->mic.mbmi.tx_size == supertx_size;
5962}
5963
5964static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5965 PC_TREE *pc_tree) {
5966 PARTITION_TYPE partition;
5967 BLOCK_SIZE subsize;
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;
5972#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005973
5974 partition = pc_tree->partitioning;
5975 subsize = get_subsize(bsize, partition);
5976 switch (partition) {
5977 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5978 case PARTITION_VERT:
5979 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5980 case PARTITION_HORZ:
5981 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5982 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08005983 if (bsize == BLOCK_8X8 && !unify_bsize)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005984 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5985 else
5986 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5987#if CONFIG_EXT_PARTITION_TYPES
5988 case PARTITION_HORZ_A:
5989 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5990 case PARTITION_HORZ_B:
5991 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5992 case PARTITION_VERT_A:
5993 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5994 case PARTITION_VERT_B:
5995 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5996#endif // CONFIG_EXT_PARTITION_TYPES
5997 default: assert(0); return 0;
5998 }
5999}
6000
Urvang Joshi52648442016-10-13 17:27:51 -07006001static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006002#if CONFIG_EXT_INTER
6003 int mi_row_ori, int mi_col_ori,
6004#endif // CONFIG_EXT_INTER
6005 int mi_row_pred, int mi_col_pred,
6006 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
6007 // Used in supertx
6008 // (mi_row_ori, mi_col_ori): location for mv
6009 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07006010 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006011 MACROBLOCK *const x = &td->mb;
6012 MACROBLOCKD *const xd = &x->e_mbd;
6013 MODE_INFO *mi_8x8 = xd->mi[0];
6014 MODE_INFO *mi = mi_8x8;
6015 MB_MODE_INFO *mbmi = &mi->mbmi;
6016 int ref;
6017 const int is_compound = has_second_ref(mbmi);
6018
6019 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
6020
6021 for (ref = 0; ref < 1 + is_compound; ++ref) {
6022 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07006023 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
6024 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006025 }
6026
6027 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07006028 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006029#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006030 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006031#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006032 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006033 else
Yaowu Xuf883b422016-08-30 14:01:10 -07006034 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006035#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006036 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006037#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07006038 mi_row_pred, mi_col_pred,
6039 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006040}
6041
Urvang Joshi52648442016-10-13 17:27:51 -07006042static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006043 const TileInfo *const tile, int block,
6044 int mi_row_ori, int mi_col_ori, int mi_row_pred,
6045 int mi_col_pred, int mi_row_top, int mi_col_top,
6046 uint8_t *dst_buf[3], int dst_stride[3],
6047 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006048 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049 // Used in supertx
6050 // (mi_row_ori, mi_col_ori): location for mv
6051 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
6052 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
6053 // block: sub location of sub8x8 blocks
6054 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
6055 // bextend: 1: region to predict is an extension of ori; 0: not
6056
6057 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07006058 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006059 MACROBLOCKD *const xd = &x->e_mbd;
6060 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
6061 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
Jingning Han1856e432016-12-21 14:58:39 -08006062 const int mi_width_top = mi_size_wide[bsize_top];
6063 const int mi_height_top = mi_size_high[bsize_top];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006064
6065 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
6066 mi_row_pred >= mi_row_top + mi_height_top ||
6067 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
6068 mi_col_pred >= cm->mi_cols)
6069 return;
6070
6071 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
6072 mi_col_ori, bsize_pred);
6073 xd->plane[0].dst.stride = dst_stride[0];
6074 xd->plane[1].dst.stride = dst_stride[1];
6075 xd->plane[2].dst.stride = dst_stride[2];
6076 xd->plane[0].dst.buf = dst_buf[0] +
6077 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
6078 (c >> xd->plane[0].subsampling_x);
6079 xd->plane[1].dst.buf = dst_buf[1] +
6080 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
6081 (c >> xd->plane[1].subsampling_x);
6082 xd->plane[2].dst.buf = dst_buf[2] +
6083 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
6084 (c >> xd->plane[2].subsampling_x);
6085
6086 predict_superblock(cpi, td,
6087#if CONFIG_EXT_INTER
6088 mi_row_ori, mi_col_ori,
6089#endif // CONFIG_EXT_INTER
6090 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
6091
Jingning Hanfc0476d2016-12-21 14:43:16 -08006092 if (!dry_run && !bextend)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07006093 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094}
6095
Urvang Joshi52648442016-10-13 17:27:51 -07006096static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006097 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6098 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006099 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006100 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
6101 // dir: 0-lower, 1-upper, 2-left, 3-right
6102 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
6103 MACROBLOCKD *xd = &td->mb.e_mbd;
Jingning Han1856e432016-12-21 14:58:39 -08006104 const int mi_width = mi_size_wide[bsize];
6105 const int mi_height = mi_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006106 int xss = xd->plane[1].subsampling_x;
6107 int yss = xd->plane[1].subsampling_y;
Jingning Hanfeb517c2016-12-21 16:02:07 -08006108#if CONFIG_CB4X4
6109 const int unify_bsize = 1;
6110#else
6111 const int unify_bsize = 0;
6112#endif
6113 int b_sub8x8 = (bsize < BLOCK_8X8) && !unify_bsize ? 1 : 0;
Jingning Han24f24a52016-12-27 10:13:28 -08006114 int wide_unit, high_unit;
6115 int i, j;
6116 int ext_offset = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117
6118 BLOCK_SIZE extend_bsize;
Jingning Han24f24a52016-12-27 10:13:28 -08006119 int mi_row_pred, mi_col_pred;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006120
6121 if (dir == 0 || dir == 1) { // lower and upper
Jingning Han1856e432016-12-21 14:58:39 -08006122 extend_bsize =
6123 (mi_width == mi_size_wide[BLOCK_8X8] || bsize < BLOCK_8X8 || xss < yss)
6124 ? BLOCK_8X8
6125 : BLOCK_16X8;
Jingning Han24f24a52016-12-27 10:13:28 -08006126
6127#if CONFIG_CB4X4
6128 if (bsize < BLOCK_8X8) {
6129 extend_bsize = BLOCK_4X4;
6130 ext_offset = mi_size_wide[BLOCK_8X8];
6131 }
6132#endif
6133 wide_unit = mi_size_wide[extend_bsize];
6134 high_unit = mi_size_high[extend_bsize];
6135
6136 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -(mi_height + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006137 mi_col_pred = mi_col;
6138
Jingning Han24f24a52016-12-27 10:13:28 -08006139 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6140 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6141 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6142 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006143 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6144 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 } else if (dir == 2 || dir == 3) { // left and right
Jingning Han1856e432016-12-21 14:58:39 -08006146 extend_bsize =
6147 (mi_height == mi_size_high[BLOCK_8X8] || bsize < BLOCK_8X8 || yss < xss)
6148 ? BLOCK_8X8
6149 : BLOCK_8X16;
Jingning Han24f24a52016-12-27 10:13:28 -08006150#if CONFIG_CB4X4
6151 if (bsize < BLOCK_8X8) {
6152 extend_bsize = BLOCK_4X4;
6153 ext_offset = mi_size_wide[BLOCK_8X8];
6154 }
6155#endif
6156 wide_unit = mi_size_wide[extend_bsize];
6157 high_unit = mi_size_high[extend_bsize];
6158
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159 mi_row_pred = mi_row;
Jingning Han24f24a52016-12-27 10:13:28 -08006160 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -(mi_width + ext_offset));
Yaowu Xuc27fc142016-08-22 16:08:15 -07006161
Jingning Han24f24a52016-12-27 10:13:28 -08006162 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6163 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6164 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6165 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006166 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6167 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 } else {
6169 extend_bsize = BLOCK_8X8;
Jingning Han24f24a52016-12-27 10:13:28 -08006170#if CONFIG_CB4X4
6171 if (bsize < BLOCK_8X8) {
6172 extend_bsize = BLOCK_4X4;
6173 ext_offset = mi_size_wide[BLOCK_8X8];
6174 }
6175#endif
6176 wide_unit = mi_size_wide[extend_bsize];
6177 high_unit = mi_size_high[extend_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07006178
Jingning Han24f24a52016-12-27 10:13:28 -08006179 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height
6180 : -(mi_height + ext_offset));
6181 mi_col_pred =
6182 mi_col + ((dir == 6 || dir == 7) ? mi_width : -(mi_width + ext_offset));
6183
6184 for (j = 0; j < mi_height + ext_offset; j += high_unit)
6185 for (i = 0; i < mi_width + ext_offset; i += wide_unit)
6186 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred + j,
6187 mi_col_pred + i, mi_row_top, mi_col_top, dst_buf,
6188 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
6189 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190 }
6191}
6192
Urvang Joshi52648442016-10-13 17:27:51 -07006193static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006194 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
6195 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006196 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006197 uint8_t *dst_buf[3], int dst_stride[3]) {
6198 assert(block >= 0 && block < 4);
6199 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006200 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006201 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006202 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006203 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006204 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006205 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006206 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006207 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006208 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006210 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006211 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006212 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006213 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006214 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006215}
6216
6217// This function generates prediction for multiple blocks, between which
6218// discontinuity around boundary is reduced by smoothing masks. The basic
6219// smoothing mask is a soft step function along horz/vert direction. In more
6220// complicated case when a block is split into 4 subblocks, the basic mask is
6221// first applied to neighboring subblocks (2 pairs) in horizontal direction and
6222// then applied to the 2 masked prediction mentioned above in vertical direction
6223// If the block is split into more than one level, at every stage, masked
6224// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07006225static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006226 const TileInfo *const tile, int mi_row,
6227 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006228 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006229 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
6230 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006231 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006232 MACROBLOCK *const x = &td->mb;
6233 MACROBLOCKD *const xd = &x->e_mbd;
Alex Converse55c6bde2017-01-12 15:55:31 -08006234 const int hbs = mi_size_wide[bsize] / 2;
Jingning Hanfeb517c2016-12-21 16:02:07 -08006235 const int is_partition_root = bsize >= BLOCK_8X8;
6236 const int ctx = is_partition_root
Alex Converse55c6bde2017-01-12 15:55:31 -08006237 ? partition_plane_context(xd, mi_row, mi_col,
6238#if CONFIG_UNPOISON_PARTITION_CTX
6239 mi_row + hbs < cm->mi_rows,
6240 mi_col + hbs < cm->mi_cols,
6241#endif
6242 bsize)
6243 : -1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006244 const PARTITION_TYPE partition = pc_tree->partitioning;
6245 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
6246#if CONFIG_EXT_PARTITION_TYPES
6247 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
6248#endif
6249
6250 int i;
6251 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
6252 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6253 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6254 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
6255 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6256 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
6257 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
Jingning Hanfeb517c2016-12-21 16:02:07 -08006258#if CONFIG_CB4X4
6259 const int unify_bsize = 1;
6260#else
6261 const int unify_bsize = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006262 assert(bsize >= BLOCK_8X8);
Jingning Hanfeb517c2016-12-21 16:02:07 -08006263#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264
6265 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
6266
Yaowu Xuf883b422016-08-30 14:01:10 -07006267#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006268 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
6269 int len = sizeof(uint16_t);
6270 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
6271 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
6272 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
6273 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
6274 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
6275 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
6276 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
6277 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
6278 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
6279 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07006280#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006281 dst_buf1[0] = tmp_buf1;
6282 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
6283 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
6284 dst_buf2[0] = tmp_buf2;
6285 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
6286 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
6287 dst_buf3[0] = tmp_buf3;
6288 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
6289 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07006290#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006291 }
Yaowu Xuf883b422016-08-30 14:01:10 -07006292#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07006293
Alex Converse55c6bde2017-01-12 15:55:31 -08006294 if (!dry_run && ctx >= 0 && bsize < top_bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -07006295 // Explicitly cast away const.
6296 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
6297 frame_counts->partition[ctx][partition]++;
6298 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07006299
6300 for (i = 0; i < MAX_MB_PLANE; i++) {
6301 xd->plane[i].dst.buf = dst_buf[i];
6302 xd->plane[i].dst.stride = dst_stride[i];
6303 }
6304
6305 switch (partition) {
6306 case PARTITION_NONE:
6307 assert(bsize < top_bsize);
6308 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6309 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006310 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006311 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006312 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006313 break;
6314 case PARTITION_HORZ:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006315 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006316 // Fisrt half
6317 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6318 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006319 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006320 if (bsize < top_bsize)
6321 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006322 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006323
6324 // Second half
6325 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6326 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006327 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006328 if (bsize < top_bsize)
6329 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006330 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006331
6332 // Smooth
6333 xd->plane[0].dst.buf = dst_buf[0];
6334 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006335 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006336 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6337 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6338 0);
6339 } else {
6340 // First half
6341 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6342 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006343 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006344 if (bsize < top_bsize)
6345 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006346 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006347 else
6348 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006349 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006350
6351 if (mi_row + hbs < cm->mi_rows) {
6352 // Second half
6353 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6354 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006355 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006356 if (bsize < top_bsize)
6357 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006358 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006359 dst_stride1);
6360 else
6361 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006362 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006363 dst_stride1, 1);
6364
6365 // Smooth
6366 for (i = 0; i < MAX_MB_PLANE; i++) {
6367 xd->plane[i].dst.buf = dst_buf[i];
6368 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006369 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006370 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6371 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6372 PARTITION_HORZ, i);
6373 }
6374 }
6375 }
6376 break;
6377 case PARTITION_VERT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006378 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006379 // First half
6380 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6381 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006382 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006383 if (bsize < top_bsize)
6384 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006385 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006386
6387 // Second half
6388 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6389 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006390 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006391 if (bsize < top_bsize)
6392 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006393 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006394
6395 // Smooth
6396 xd->plane[0].dst.buf = dst_buf[0];
6397 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07006398 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006399 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
6400 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6401 0);
6402 } else {
6403 // bsize: not important, not useful
6404 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6405 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006406 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006407 if (bsize < top_bsize)
6408 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006409 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006410 else
6411 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006412 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006413
6414 if (mi_col + hbs < cm->mi_cols) {
6415 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6416 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006417 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006418 if (bsize < top_bsize)
6419 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006420 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6421 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006422 else
6423 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006424 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6425 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006426
6427 for (i = 0; i < MAX_MB_PLANE; i++) {
6428 xd->plane[i].dst.buf = dst_buf[i];
6429 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006430 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006431 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6432 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6433 PARTITION_VERT, i);
6434 }
6435 }
6436 }
6437 break;
6438 case PARTITION_SPLIT:
Jingning Hanfeb517c2016-12-21 16:02:07 -08006439 if (bsize == BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07006440 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6441 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006442 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006443 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6444 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006445 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006446 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6447 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006448 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006449 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6450 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006451 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006452
6453 if (bsize < top_bsize) {
6454 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006455 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006456 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006457 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006458 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006459 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006460 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006461 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006462 }
6463 } else {
6464 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006465 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6466 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006467 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6468 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006469 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6470 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006471 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6472 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006473 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6474 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006475 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6476 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006477 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006478 top_bsize, dst_buf3, dst_stride3,
6479 pc_tree->split[3]);
6480 }
6481 for (i = 0; i < MAX_MB_PLANE; i++) {
Jingning Han9e0976a2016-12-27 17:52:42 -08006482#if !CONFIG_CB4X4
Jingning Han24f24a52016-12-27 10:13:28 -08006483 if (bsize == BLOCK_8X8 && i != 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07006484 continue; // Skip <4x4 chroma smoothing
Jingning Han9e0976a2016-12-27 17:52:42 -08006485#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07006486 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006487 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006488 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6489 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6490 PARTITION_VERT, i);
6491 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006492 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006493 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6494 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6495 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006496 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006497 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6498 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6499 PARTITION_HORZ, i);
6500 }
6501 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Jingning Han24f24a52016-12-27 10:13:28 -08006502 if (bsize == BLOCK_8X8 && i != 0)
6503 continue; // Skip <4x4 chroma smoothing
6504
Yaowu Xuf883b422016-08-30 14:01:10 -07006505 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006506 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6507 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6508 PARTITION_HORZ, i);
6509 }
6510 }
6511 break;
6512#if CONFIG_EXT_PARTITION_TYPES
6513 case PARTITION_HORZ_A:
6514 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6515 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006516 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006517 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006518 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006519
6520 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6521 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006522 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006523 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006524 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006525
6526 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6527 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006528 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006529 if (bsize < top_bsize)
6530 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006531 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006532 else
6533 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006534 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006535
6536 for (i = 0; i < MAX_MB_PLANE; i++) {
6537 xd->plane[i].dst.buf = dst_buf[i];
6538 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006539 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006540 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6541 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6542 i);
6543 }
6544 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006545 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006546 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6547 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6548 i);
6549 }
6550
6551 break;
6552 case PARTITION_VERT_A:
6553
6554 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6555 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006556 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006557 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006558 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006559
6560 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6561 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006562 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006563 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006564 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006565
6566 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6567 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006568 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006569 if (bsize < top_bsize)
6570 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006571 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006572 else
6573 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006574 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006575
6576 for (i = 0; i < MAX_MB_PLANE; i++) {
6577 xd->plane[i].dst.buf = dst_buf[i];
6578 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006579 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006580 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6581 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6582 i);
6583 }
6584 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006585 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006586 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6587 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6588 i);
6589 }
6590 break;
6591 case PARTITION_HORZ_B:
6592
6593 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6594 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006595 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006596 if (bsize < top_bsize)
6597 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006598 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006599 else
6600 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006601 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006602
6603 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6604 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006605 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006606 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006607 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006608
6609 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6610 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006611 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006612 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006613 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006614 dst_stride2);
6615
6616 for (i = 0; i < MAX_MB_PLANE; i++) {
6617 xd->plane[i].dst.buf = dst_buf1[i];
6618 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006619 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006620 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6621 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6622 PARTITION_VERT, i);
6623 }
6624 for (i = 0; i < MAX_MB_PLANE; i++) {
6625 xd->plane[i].dst.buf = dst_buf[i];
6626 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006627 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006628 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6629 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6630 i);
6631 }
6632 break;
6633 case PARTITION_VERT_B:
6634
6635 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6636 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006637 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006638 if (bsize < top_bsize)
6639 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006640 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006641 else
6642 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006643 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006644
6645 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6646 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006647 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006648 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006649 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006650
6651 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6652 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006653 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006654 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006655 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006656 dst_stride2);
6657
6658 for (i = 0; i < MAX_MB_PLANE; i++) {
6659 xd->plane[i].dst.buf = dst_buf1[i];
6660 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006661 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006662 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6663 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6664 PARTITION_HORZ, i);
6665 }
6666 for (i = 0; i < MAX_MB_PLANE; i++) {
6667 xd->plane[i].dst.buf = dst_buf[i];
6668 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006669 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006670 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6671 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6672 i);
6673 }
6674 break;
6675#endif // CONFIG_EXT_PARTITION_TYPES
6676 default: assert(0);
6677 }
6678
6679#if CONFIG_EXT_PARTITION_TYPES
6680 if (bsize < top_bsize)
6681 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6682#else
6683 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6684 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6685#endif // CONFIG_EXT_PARTITION_TYPES
6686}
6687
Urvang Joshi52648442016-10-13 17:27:51 -07006688static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006689 const TileInfo *const tile, int mi_row, int mi_col,
6690 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6691 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006692 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006693 MACROBLOCK *const x = &td->mb;
6694 MACROBLOCKD *const xd = &x->e_mbd;
6695 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6696 base_rate = *tmp_rate;
6697 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6698 uint8_t *dst_buf[3];
6699 int dst_stride[3];
6700 TX_SIZE tx_size;
6701 MB_MODE_INFO *mbmi;
6702 TX_TYPE tx_type, best_tx_nostx;
6703#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08006704 const int ext_tx_set;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006705#endif // CONFIG_EXT_TX
6706 int tmp_rate_tx = 0, skip_tx = 0;
6707 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6708
6709 set_skip_context(xd, mi_row, mi_col);
6710 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006711 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006712 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006713 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6714 dst_buf[plane] = xd->plane[plane].dst.buf;
6715 dst_stride[plane] = xd->plane[plane].dst.stride;
6716 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006717 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006718 bsize, dst_buf, dst_stride, pc_tree);
6719
6720 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6721 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6722
6723 mbmi = &xd->mi[0]->mbmi;
6724 best_tx_nostx = mbmi->tx_type;
6725
6726 *best_tx = DCT_DCT;
6727
6728 // chroma
6729 skippable_uv = 1;
6730 rate_uv = 0;
6731 dist_uv = 0;
6732 sse_uv = 0;
6733 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6734#if CONFIG_VAR_TX
6735 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6736 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6737 const struct macroblockd_plane *const pd = &xd->plane[plane];
6738 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006739 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006740 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006741
6742 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006743 tx_size =
6744 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006745 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006746 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6747
Yaowu Xuf883b422016-08-30 14:01:10 -07006748 av1_subtract_plane(x, bsize, plane);
6749 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006750 get_plane_block_size(bsize, pd), coeff_ctx,
6751 &this_rd_stats);
6752
6753 this_rate = this_rd_stats.rate;
6754 this_dist = this_rd_stats.dist;
6755 pnsse = this_rd_stats.sse;
6756 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006757#else
6758 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006759 tx_size =
6760 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006761 av1_subtract_plane(x, bsize, plane);
6762 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6763 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006764#endif // CONFIG_VAR_TX
6765
6766 rate_uv += this_rate;
6767 dist_uv += this_dist;
6768 sse_uv += pnsse;
6769 skippable_uv &= pnskip;
6770 }
6771
6772 // luma
6773 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006774 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006775#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08006776 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1, cm->reduced_tx_set_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006777#endif // CONFIG_EXT_TX
6778 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6779#if CONFIG_VAR_TX
6780 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6781 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6782 const struct macroblockd_plane *const pd = &xd->plane[0];
6783 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006784 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006785#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006786
Yaowu Xuc27fc142016-08-22 16:08:15 -07006787#if CONFIG_EXT_TX
6788 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6789#else
6790 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6791#endif // CONFIG_EXT_TX
6792 mbmi->tx_type = tx_type;
6793
6794#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006795 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006796
Yaowu Xuf883b422016-08-30 14:01:10 -07006797 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006798 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006799 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6800 &this_rd_stats);
6801
6802 this_rate = this_rd_stats.rate;
6803 this_dist = this_rd_stats.dist;
6804 pnsse = this_rd_stats.sse;
6805 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006806#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006807 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6808 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006809#endif // CONFIG_VAR_TX
6810
6811#if CONFIG_EXT_TX
Sarah Parkere68a3e42017-02-16 14:03:24 -08006812 if (get_ext_tx_types(tx_size, bsize, 1, cm->reduced_tx_set_used) > 1 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07006813 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6814 if (ext_tx_set > 0)
6815 this_rate +=
6816 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6817 }
6818#else
6819 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6820 this_rate != INT_MAX) {
6821 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6822 }
6823#endif // CONFIG_EXT_TX
6824 *tmp_rate = rate_uv + this_rate;
6825 *tmp_dist = dist_uv + this_dist;
6826 sse = sse_uv + pnsse;
6827 skippable = skippable_uv && pnskip;
6828 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006829 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006830 x->skip = 1;
6831 } else {
6832 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6833 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006834 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006835 x->skip = 0;
6836 } else {
6837 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006838 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006839 x->skip = 1;
6840 }
6841 }
6842 *tmp_rate += base_rate;
6843 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6844 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6845 *best_tx = tx_type;
6846 bestrd_tx = rd_tx;
6847 tmp_rate_tx = *tmp_rate;
6848 tmp_dist_tx = *tmp_dist;
6849 skip_tx = x->skip;
6850 }
6851 }
6852 *tmp_rate = tmp_rate_tx;
6853 *tmp_dist = tmp_dist_tx;
6854 x->skip = skip_tx;
6855#if CONFIG_VAR_TX
6856 for (plane = 0; plane < 1; ++plane)
6857 memset(x->blk_skip[plane], x->skip,
6858 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6859#endif // CONFIG_VAR_TX
6860 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6861}
6862#endif // CONFIG_SUPERTX