blob: 47d24c51fc2798427aa7c2e8581ded760986e42e [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
43#if CONFIG_GLOBAL_MOTION
Sarah Parkere5299862016-08-16 14:57:37 -070044#include "av1/common/warped_motion.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070045#include "av1/encoder/global_motion.h"
46#endif
47#include "av1/encoder/encodeframe.h"
48#include "av1/encoder/encodemb.h"
49#include "av1/encoder/encodemv.h"
50#include "av1/encoder/ethread.h"
51#include "av1/encoder/extend.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/rdopt.h"
54#include "av1/encoder/segmentation.h"
55#include "av1/encoder/tokenize.h"
56
Yaowu Xuf883b422016-08-30 14:01:10 -070057#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070058#define IF_HBD(...) __VA_ARGS__
59#else
60#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070061#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070062
Urvang Joshi52648442016-10-13 17:27:51 -070063static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
64 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
65 int mi_col, BLOCK_SIZE bsize,
66 PICK_MODE_CONTEXT *ctx, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070067
68#if CONFIG_SUPERTX
69static int check_intra_b(PICK_MODE_CONTEXT *ctx);
70
Urvang Joshi52648442016-10-13 17:27:51 -070071static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
72 int mi_row, int mi_col, BLOCK_SIZE bsize,
73 PC_TREE *pc_tree);
74static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070075#if CONFIG_EXT_INTER
76 int mi_row_ori, int mi_col_ori,
77#endif // CONFIG_EXT_INTER
78 int mi_row_pred, int mi_col_pred,
79 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
80static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
81 PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070082static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070083 const TileInfo *const tile, int mi_row,
84 int mi_col, int mi_row_ori, int mi_col_ori,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070085 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070086 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
87 int dst_stride[3], PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070088static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070089 const TileInfo *const tile, int mi_row,
90 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070091 RUN_TYPE dry_run, PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070092static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070093 const TileInfo *const tile, int mi_row, int mi_col,
94 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
95 TX_TYPE *best_tx, PC_TREE *pc_tree);
96#endif // CONFIG_SUPERTX
97
98// This is used as a reference when computing the source variance for the
99// purposes of activity masking.
100// Eventually this should be replaced by custom no-reference routines,
101// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700102static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
106 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
107 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
108#if CONFIG_EXT_PARTITION
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, 128,
113 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
114#endif // CONFIG_EXT_PARTITION
115};
116
Yaowu Xuf883b422016-08-30 14:01:10 -0700117#if CONFIG_AOM_HIGHBITDEPTH
118static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700119 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
120 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
121 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
122 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
123 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
124#if CONFIG_EXT_PARTITION
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, 128,
129 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
130#endif // CONFIG_EXT_PARTITION
131};
132
Yaowu Xuf883b422016-08-30 14:01:10 -0700133static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700134 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
135 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
136 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
137 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
138 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
139 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#if CONFIG_EXT_PARTITION
143 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
144 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
145 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
146 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
147 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
148 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
149 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#endif // CONFIG_EXT_PARTITION
152};
153
Yaowu Xuf883b422016-08-30 14:01:10 -0700154static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
156 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
157 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
158 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
159 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
160 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,
165#if CONFIG_EXT_PARTITION
166 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
167 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
168 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
169 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
170 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
171 128 * 16, 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
176#endif // CONFIG_EXT_PARTITION
177};
Yaowu Xuf883b422016-08-30 14:01:10 -0700178#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700179
Urvang Joshi52648442016-10-13 17:27:51 -0700180unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700181 const struct buf_2d *ref,
182 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183 unsigned int sse;
184 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700185 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
187}
188
Yaowu Xuf883b422016-08-30 14:01:10 -0700189#if CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700190unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700191 const struct buf_2d *ref,
192 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700193 unsigned int var, sse;
194 switch (bd) {
195 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700196 var =
197 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
198 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700199 break;
200 case 12:
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_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 break;
205 case 8:
206 default:
207 var =
208 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700209 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700210 break;
211 }
212 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
213}
Yaowu Xuf883b422016-08-30 14:01:10 -0700214#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700215
Urvang Joshi52648442016-10-13 17:27:51 -0700216static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700217 const struct buf_2d *ref,
218 int mi_row, int mi_col,
219 BLOCK_SIZE bs) {
220 unsigned int sse, var;
221 uint8_t *last_y;
222 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
223
224 assert(last != NULL);
225 last_y =
226 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
227 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
228 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
229}
230
Yaowu Xuf883b422016-08-30 14:01:10 -0700231static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
232 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233 unsigned int var = get_sby_perpixel_diff_variance(
234 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
235 if (var < 8)
236 return BLOCK_64X64;
237 else if (var < 128)
238 return BLOCK_32X32;
239 else if (var < 2048)
240 return BLOCK_16X16;
241 else
242 return BLOCK_8X8;
243}
244
245// Lighter version of set_offsets that only sets the mode info
246// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700247static void set_mode_info_offsets(const AV1_COMP *const cpi,
248 MACROBLOCK *const x, MACROBLOCKD *const xd,
249 int mi_row, int mi_col) {
250 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251 const int idx_str = xd->mi_stride * mi_row + mi_col;
252 xd->mi = cm->mi_grid_visible + idx_str;
253 xd->mi[0] = cm->mi + idx_str;
254 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
255}
256
Urvang Joshi52648442016-10-13 17:27:51 -0700257static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258 const TileInfo *const tile,
259 MACROBLOCK *const x, int mi_row,
260 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700261 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262 MACROBLOCKD *const xd = &x->e_mbd;
263 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
264 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Hana6923f72016-07-15 08:50:14 -0700265 const int bwl = b_width_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
266 const int bhl = b_height_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267
268 set_skip_context(xd, mi_row, mi_col);
269
270 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
271
272#if CONFIG_VAR_TX
273 xd->above_txfm_context = cm->above_txfm_context + mi_col;
274 xd->left_txfm_context =
275 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
276 xd->max_tx_size = max_txsize_lookup[bsize];
277#endif
278
279 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700280 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700281
282 // Set up limit values for MV components.
283 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700284 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
285 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
286 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
287 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700288
Jingning Hana6923f72016-07-15 08:50:14 -0700289 set_plane_n4(xd, mi_width, mi_height, bwl, bhl);
290
Yaowu Xuc27fc142016-08-22 16:08:15 -0700291 // Set up distance of MB to edge of frame in 1/8th pel units.
292 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
293 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
294 cm->mi_cols);
295
296 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700297 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298
299 // R/D setup.
300 x->rddiv = cpi->rd.RDDIV;
301 x->rdmult = cpi->rd.RDMULT;
302
Yaowu Xuf883b422016-08-30 14:01:10 -0700303 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700304 xd->tile = *tile;
305}
306
Urvang Joshi52648442016-10-13 17:27:51 -0700307static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700308 MACROBLOCK *const x, int mi_row, int mi_col,
309 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700310 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700311 MACROBLOCKD *const xd = &x->e_mbd;
312 MB_MODE_INFO *mbmi;
313 const struct segmentation *const seg = &cm->seg;
314
315 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
316
317 mbmi = &xd->mi[0]->mbmi;
318
319 // Setup segment ID.
320 if (seg->enabled) {
321 if (!cpi->vaq_refresh) {
322 const uint8_t *const map =
323 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
324 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
325 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700326 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700327 } else {
328 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700329 }
330
331#if CONFIG_SUPERTX
332 mbmi->segment_id_supertx = MAX_SEGMENTS;
333#endif // CONFIG_SUPERTX
334}
335
336#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700337static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700338 const TileInfo *const tile, int mi_row,
339 int mi_col, BLOCK_SIZE bsize) {
340 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700341 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700342 MACROBLOCKD *const xd = &x->e_mbd;
343 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
344 const int mi_height = num_8x8_blocks_high_lookup[bsize];
345
346 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
347
348 // Set up distance of MB to edge of frame in 1/8th pel units.
349 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
350 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
351 cm->mi_cols);
352}
353
Urvang Joshi52648442016-10-13 17:27:51 -0700354static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700355 const TileInfo *const tile, int mi_row_pred,
356 int mi_col_pred, int mi_row_ori, int mi_col_ori,
357 BLOCK_SIZE bsize_pred) {
358 // Used in supertx
359 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
360 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
361 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700362 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700363 MACROBLOCKD *const xd = &x->e_mbd;
364 const int mi_width = num_8x8_blocks_wide_lookup[bsize_pred];
365 const int mi_height = num_8x8_blocks_high_lookup[bsize_pred];
366
367 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
368
369 // Set up limit values for MV components.
370 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700371 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
372 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
373 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
374 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700375
376 // Set up distance of MB to edge of frame in 1/8th pel units.
377 assert(!(mi_col_pred & (mi_width - 1)) && !(mi_row_pred & (mi_height - 1)));
378 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
379 cm->mi_rows, cm->mi_cols);
380 xd->up_available = (mi_row_ori > tile->mi_row_start);
381 xd->left_available = (mi_col_ori > tile->mi_col_start);
382
383 // R/D setup.
384 x->rddiv = cpi->rd.RDDIV;
385 x->rdmult = cpi->rd.RDMULT;
386}
387
Yaowu Xuf883b422016-08-30 14:01:10 -0700388static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700389 MACROBLOCK *const x, const int mi_row,
390 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700391 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700392 const struct segmentation *seg = &cm->seg;
393 const int miw =
Yaowu Xuf883b422016-08-30 14:01:10 -0700394 AOMMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700395 const int mih =
Yaowu Xuf883b422016-08-30 14:01:10 -0700396 AOMMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 const int mi_offset = mi_row * cm->mi_stride + mi_col;
398 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
399 int r, c;
400 int seg_id_supertx = MAX_SEGMENTS;
401
402 if (!seg->enabled) {
403 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404 } else {
405 // Find the minimum segment_id
406 for (r = 0; r < mih; r++)
407 for (c = 0; c < miw; c++)
408 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700409 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700410 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
411
412 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700413 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700414 }
415
416 // Assign the the segment_id back to segment_id_supertx
417 for (r = 0; r < mih; r++)
418 for (c = 0; c < miw; c++)
419 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
420}
421#endif // CONFIG_SUPERTX
422
Yaowu Xuf883b422016-08-30 14:01:10 -0700423static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700424 MACROBLOCKD *const xd, int mi_row, int mi_col,
425 BLOCK_SIZE bsize) {
426 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
427 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
428 xd->mi[0]->mbmi.sb_type = bsize;
429 }
430}
431
Yaowu Xuf883b422016-08-30 14:01:10 -0700432static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700433 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
434 int mi_col, const int64_t *const threshold,
435 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700436 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437 const int hbw = num_8x8_blocks_wide_lookup[vt->bsize] / 2;
438 const int hbh = num_8x8_blocks_high_lookup[vt->bsize] / 2;
439 const int has_cols = mi_col + hbw < cm->mi_cols;
440 const int has_rows = mi_row + hbh < cm->mi_rows;
441
442 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
443
444 assert(vt->bsize >= BLOCK_8X8);
445
446 assert(hbh == hbw);
447
448 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
449 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
450 return;
451 }
452
453 if (vt->force_split || (!has_cols && !has_rows)) goto split;
454
455 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
456 // variance is below threshold, otherwise split will be selected.
457 // No check for vert/horiz split as too few samples for variance.
458 if (vt->bsize == bsize_min[0]) {
459 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
460 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
461 return;
462 } else {
463 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
464 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
465 if (vt->bsize > BLOCK_8X8) {
466 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
467 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
468 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
469 }
470 return;
471 }
472 } else if (vt->bsize > bsize_min[0]) {
473 // For key frame: take split for bsize above 32X32 or very high variance.
474 if (cm->frame_type == KEY_FRAME &&
475 (vt->bsize > BLOCK_32X32 ||
476 vt->variances.none.variance > (threshold[0] << 4))) {
477 goto split;
478 }
479 // If variance is low, take the bsize (no split).
480 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
481 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
482 return;
483 }
484
485 // Check vertical split.
486 if (has_rows) {
487 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
488 if (vt->variances.vert[0].variance < threshold[0] &&
489 vt->variances.vert[1].variance < threshold[0] &&
490 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
491 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
492 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
493 return;
494 }
495 }
496 // Check horizontal split.
497 if (has_cols) {
498 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
499 if (vt->variances.horz[0].variance < threshold[0] &&
500 vt->variances.horz[1].variance < threshold[0] &&
501 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
502 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
503 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
504 return;
505 }
506 }
507 }
508
509split : {
510 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
511 bsize_min + 1);
512 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
513 threshold + 1, bsize_min + 1);
514 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
515 threshold + 1, bsize_min + 1);
516 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
517 threshold + 1, bsize_min + 1);
518 return;
519}
520}
521
522// Set the variance split thresholds for following the block sizes:
523// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
524// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
525// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700526static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
527 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700528 const int is_key_frame = (cm->frame_type == KEY_FRAME);
529 const int threshold_multiplier = is_key_frame ? 20 : 1;
530 const int64_t threshold_base =
531 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
532 if (is_key_frame) {
533 thresholds[1] = threshold_base;
534 thresholds[2] = threshold_base >> 2;
535 thresholds[3] = threshold_base >> 2;
536 thresholds[4] = threshold_base << 2;
537 } else {
538 thresholds[2] = threshold_base;
539 if (cm->width <= 352 && cm->height <= 288) {
540 thresholds[1] = threshold_base >> 2;
541 thresholds[3] = threshold_base << 3;
542 } else {
543 thresholds[1] = threshold_base;
544 thresholds[2] = (5 * threshold_base) >> 2;
545 if (cm->width >= 1920 && cm->height >= 1080)
546 thresholds[2] = (7 * threshold_base) >> 2;
547 thresholds[3] = threshold_base << cpi->oxcf.speed;
548 }
549 }
550 thresholds[0] = INT64_MIN;
551}
552
Yaowu Xuf883b422016-08-30 14:01:10 -0700553void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
554 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700555 SPEED_FEATURES *const sf = &cpi->sf;
556 const int is_key_frame = (cm->frame_type == KEY_FRAME);
557 if (sf->partition_search_type != VAR_BASED_PARTITION &&
558 sf->partition_search_type != REFERENCE_PARTITION) {
559 return;
560 } else {
561 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
562 // The thresholds below are not changed locally.
563 if (is_key_frame) {
564 cpi->vbp_threshold_sad = 0;
565 cpi->vbp_bsize_min = BLOCK_8X8;
566 } else {
567 if (cm->width <= 352 && cm->height <= 288)
568 cpi->vbp_threshold_sad = 100;
569 else
570 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
571 ? (cpi->y_dequant[q][1] << 1)
572 : 1000;
573 cpi->vbp_bsize_min = BLOCK_16X16;
574 }
575 cpi->vbp_threshold_minmax = 15 + (q >> 3);
576 }
577}
578
579// Compute the minmax over the 8x8 subblocks.
580static int compute_minmax_8x8(const uint8_t *src, int src_stride,
581 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700582#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583 int highbd,
584#endif
585 int pixels_wide, int pixels_high) {
586 int k;
587 int minmax_max = 0;
588 int minmax_min = 255;
589 // Loop over the 4 8x8 subblocks.
590 for (k = 0; k < 4; k++) {
591 const int x8_idx = ((k & 1) << 3);
592 const int y8_idx = ((k >> 1) << 3);
593 int min = 0;
594 int max = 0;
595 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
596 const int src_offset = y8_idx * src_stride + x8_idx;
597 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700598#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700600 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700601 ref_stride, &min, &max);
602 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700603 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700604 ref_stride, &min, &max);
605 }
606#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700607 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608 &min, &max);
609#endif
610 if ((max - min) > minmax_max) minmax_max = (max - min);
611 if ((max - min) < minmax_min) minmax_min = (max - min);
612 }
613 }
614 return (minmax_max - minmax_min);
615}
616
Yaowu Xuf883b422016-08-30 14:01:10 -0700617#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618static INLINE int avg_4x4(const uint8_t *const src, const int stride,
619 const int highbd) {
620 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700621 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700622 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700623 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700624 }
625}
626#else
627static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700628 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700629}
630#endif
631
Yaowu Xuf883b422016-08-30 14:01:10 -0700632#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633static INLINE int avg_8x8(const uint8_t *const src, const int stride,
634 const int highbd) {
635 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700636 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700637 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 }
640}
641#else
642static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700643 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700644}
645#endif
646
647static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700648#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700649 const int highbd,
650#endif
651 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
652 const int width, const int height,
653 const uint8_t *const src, const int src_stride,
654 const uint8_t *const ref, const int ref_stride) {
655 assert(bsize >= leaf_size);
656
657 vt->bsize = bsize;
658
659 vt->force_split = 0;
660
661 vt->src = src;
662 vt->src_stride = src_stride;
663 vt->ref = ref;
664 vt->ref_stride = ref_stride;
665
666 vt->width = width;
667 vt->height = height;
668
Yaowu Xuf883b422016-08-30 14:01:10 -0700669#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700670 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700671#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672
673 if (bsize > leaf_size) {
674 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
675 const int px = num_4x4_blocks_wide_lookup[subsize] * 4;
676
677 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700678#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700679 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700680#endif // CONFIG_AOM_HIGHBITDEPTH
681 subsize, leaf_size, AOMMIN(px, width),
682 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700684#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700685 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700686#endif // CONFIG_AOM_HIGHBITDEPTH
687 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700688 src + px, src_stride, ref + px, ref_stride);
689 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700690#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700691 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700692#endif // CONFIG_AOM_HIGHBITDEPTH
693 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700694 src + px * src_stride, src_stride, ref + px * ref_stride,
695 ref_stride);
696 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700697#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700698 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700699#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 subsize, leaf_size, width - px, height - px,
701 src + px * src_stride + px, src_stride,
702 ref + px * ref_stride + px, ref_stride);
703 }
704}
705
706// Fill the variance tree based on averaging pixel values (sub-sampling), at
707// the leaf node size.
708static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
709 if (vt->bsize > leaf_size) {
710 fill_variance_tree(vt->split[0], leaf_size);
711 fill_variance_tree(vt->split[1], leaf_size);
712 fill_variance_tree(vt->split[2], leaf_size);
713 fill_variance_tree(vt->split[3], leaf_size);
714 fill_variance_node(vt);
715 } else if (vt->width <= 0 || vt->height <= 0) {
716 fill_variance(0, 0, 0, &vt->variances.none);
717 } else {
718 unsigned int sse = 0;
719 int sum = 0;
720 int src_avg;
721 int ref_avg;
722 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
723 if (leaf_size == BLOCK_4X4) {
724 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
725 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
726 } else {
727 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
728 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
729 }
730 sum = src_avg - ref_avg;
731 sse = sum * sum;
732 fill_variance(sse, sum, 0, &vt->variances.none);
733 }
734}
735
736static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
737 if (vt->bsize >= BLOCK_8X8) {
738 if (vt->bsize == BLOCK_16X16) {
739 if (vt->variances.none.variance <= threshold)
740 return;
741 else
742 vt->force_split = 0;
743 }
744
745 refine_variance_tree(vt->split[0], threshold);
746 refine_variance_tree(vt->split[1], threshold);
747 refine_variance_tree(vt->split[2], threshold);
748 refine_variance_tree(vt->split[3], threshold);
749
750 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
751 } else if (vt->width <= 0 || vt->height <= 0) {
752 fill_variance(0, 0, 0, &vt->variances.none);
753 } else {
754 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
755 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
756 const int sum = src_avg - ref_avg;
757 const unsigned int sse = sum * sum;
758 assert(vt->bsize == BLOCK_4X4);
759 fill_variance(sse, sum, 0, &vt->variances.none);
760 }
761}
762
763static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
764 if (vt->bsize == BLOCK_32X32) {
765 vt->force_split = vt->variances.none.variance > threshold;
766 } else {
767 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
768 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
769 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
770 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
771 }
772 return vt->force_split;
773}
774
Yaowu Xuf883b422016-08-30 14:01:10 -0700775static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 const int segment_id, const int64_t *const thresholds) {
777 if (vt->bsize == BLOCK_16X16) {
778 vt->force_split = vt->variances.none.variance > thresholds[0];
779 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
780 !cyclic_refresh_segment_id_boosted(segment_id)) {
781 // We have some nominal amount of 16x16 variance (based on average),
782 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
783 // force split to 8x8 block for this 16x16 block.
784 int minmax =
785 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700786#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700787 vt->highbd,
788#endif
789 vt->width, vt->height);
790 vt->force_split = minmax > cpi->vbp_threshold_minmax;
791 }
792 } else {
793 vt->force_split |=
794 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
795 vt->force_split |=
796 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
797 vt->force_split |=
798 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
799 vt->force_split |=
800 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
801
802 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
803 vt->force_split = vt->variances.none.variance > thresholds[0];
804 }
805 }
806
807 return vt->force_split;
808}
809
810// This function chooses partitioning based on the variance between source and
811// reconstructed last (or golden), where variance is computed for down-sampled
812// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700813static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700814 const TileInfo *const tile, MACROBLOCK *const x,
815 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700816 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700817 MACROBLOCKD *const xd = &x->e_mbd;
818 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700819#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700820 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700821#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822 const uint8_t *src;
823 const uint8_t *ref;
824 int src_stride;
825 int ref_stride;
826 int pixels_wide = 8 * num_8x8_blocks_wide_lookup[cm->sb_size];
827 int pixels_high = 8 * num_8x8_blocks_high_lookup[cm->sb_size];
828 int64_t thresholds[5] = {
829 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
830 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
831 };
832 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
833 cpi->vbp_bsize_min, BLOCK_8X8 };
834 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
835 const int64_t *const thre = thresholds + start_level;
836 const BLOCK_SIZE *const bmin = bsize_min + start_level;
837
838 const int is_key_frame = (cm->frame_type == KEY_FRAME);
839 const int low_res = (cm->width <= 352 && cm->height <= 288);
840
841 int segment_id = CR_SEGMENT_ID_BASE;
842
843 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
844 const uint8_t *const map =
845 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
846 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
847
848 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700849 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 set_vbp_thresholds(cpi, thresholds, q);
851 }
852 }
853
854 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
855
856 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
857 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
858
859 src = x->plane[0].src.buf;
860 src_stride = x->plane[0].src.stride;
861
862 if (!is_key_frame) {
863 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700864 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
865 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
866 unsigned int y_sad, y_sad_g;
867
868 const int hbs = cm->mib_size / 2;
869 const int split_vert = mi_col + hbs >= cm->mi_cols;
870 const int split_horz = mi_row + hbs >= cm->mi_rows;
871 BLOCK_SIZE bsize;
872
873 if (split_vert && split_horz)
874 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
875 else if (split_vert)
876 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
877 else if (split_horz)
878 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
879 else
880 bsize = cm->sb_size;
881
882 assert(yv12 != NULL);
883
884 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700885 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
886 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700887 y_sad_g = cpi->fn_ptr[bsize].sdf(
888 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
889 xd->plane[0].pre[0].stride);
890 } else {
891 y_sad_g = UINT_MAX;
892 }
893
Yaowu Xuf883b422016-08-30 14:01:10 -0700894 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
895 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700896 mbmi->ref_frame[0] = LAST_FRAME;
897 mbmi->ref_frame[1] = NONE;
898 mbmi->sb_type = cm->sb_size;
899 mbmi->mv[0].as_int = 0;
900#if CONFIG_DUAL_FILTER
901 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
902#else
903 mbmi->interp_filter = BILINEAR;
904#endif
905
Yaowu Xuf883b422016-08-30 14:01:10 -0700906 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907
908 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700909 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
910 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911 mbmi->ref_frame[0] = GOLDEN_FRAME;
912 mbmi->mv[0].as_int = 0;
913 y_sad = y_sad_g;
914 } else {
915 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
916 }
917
Yaowu Xuf883b422016-08-30 14:01:10 -0700918 av1_build_inter_predictors_sb(xd, mi_row, mi_col, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700919
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920 ref = xd->plane[0].dst.buf;
921 ref_stride = xd->plane[0].dst.stride;
922
923 // If the y_sad is very small, take the largest partition and exit.
924 // Don't check on boosted segment for now, as largest is suppressed there.
925 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
926 if (!split_vert && !split_horz) {
927 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
928 return;
929 }
930 }
931 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700932 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700933 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700934#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
936 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700937 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
938 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700940 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941 }
942 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700943#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700944 }
945
946 init_variance_tree(
947 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700948#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700949 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700950#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
952 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
953
954 // Fill in the entire tree of variances and compute splits.
955 if (is_key_frame) {
956 fill_variance_tree(vt, BLOCK_4X4);
957 check_split_key_frame(vt, thre[1]);
958 } else {
959 fill_variance_tree(vt, BLOCK_8X8);
960 check_split(cpi, vt, segment_id, thre);
961 if (low_res) {
962 refine_variance_tree(vt, thre[1] << 1);
963 }
964 }
965
966 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
967 mi_row + cm->mib_size > cm->mi_rows;
968
969 // Now go through the entire structure, splitting every block size until
970 // we get to one that's got a variance lower than our threshold.
971 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
972}
973
974#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700975static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700976 MB_MODE_INFO *mbmi) {
977 int dir;
978 for (dir = 0; dir < 2; ++dir) {
979 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
980 (mbmi->ref_frame[1] == NONE ||
981 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
982 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
983 ? EIGHTTAP_REGULAR
984 : cm->interp_filter;
985 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
986 }
987}
988
989static void update_filter_type_count(FRAME_COUNTS *counts,
990 const MACROBLOCKD *xd,
991 const MB_MODE_INFO *mbmi) {
992 int dir;
993 for (dir = 0; dir < 2; ++dir) {
994 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
995 (mbmi->ref_frame[1] > INTRA_FRAME &&
996 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700997 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700998 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
999 }
1000 }
1001}
1002#endif
1003#if CONFIG_GLOBAL_MOTION
1004static void update_global_motion_used(PREDICTION_MODE mode,
Yaowu Xuf883b422016-08-30 14:01:10 -07001005 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001006 if (mode == ZEROMV) {
1007 ++cpi->global_motion_used[mbmi->ref_frame[0]];
1008 if (has_second_ref(mbmi)) ++cpi->global_motion_used[mbmi->ref_frame[1]];
1009 }
1010}
1011#endif // CONFIG_GLOBAL_MOTION
1012
Urvang Joshi52648442016-10-13 17:27:51 -07001013static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1014 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1015 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001017 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018 RD_COUNTS *const rdc = &td->rd_counts;
1019 MACROBLOCK *const x = &td->mb;
1020 MACROBLOCKD *const xd = &x->e_mbd;
1021 struct macroblock_plane *const p = x->plane;
1022 struct macroblockd_plane *const pd = xd->plane;
1023 MODE_INFO *mi = &ctx->mic;
1024 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1025 MODE_INFO *mi_addr = xd->mi[0];
1026 const struct segmentation *const seg = &cm->seg;
1027 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
1028 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001029 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1030 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001031 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1032 int w, h;
1033
1034 const int mis = cm->mi_stride;
1035 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1036 const int mi_height = num_8x8_blocks_high_lookup[bsize];
1037 int max_plane;
1038
1039#if CONFIG_REF_MV
1040 int8_t rf_type;
1041#endif
1042
1043#if !CONFIG_SUPERTX
1044 assert(mi->mbmi.sb_type == bsize);
1045#endif
1046
1047 *mi_addr = *mi;
1048 *x->mbmi_ext = ctx->mbmi_ext;
1049
1050#if CONFIG_DUAL_FILTER
1051 reset_intmv_filter_type(cm, xd, mbmi);
1052#endif
1053
1054#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001055 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1057 mbmi->mode == NEWMV) {
1058 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1059 int_mv this_mv =
1060 (i == 0)
1061 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1062 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1063 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1064 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1065 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001066 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001067 }
1068 }
1069#endif
1070
1071 // If segmentation in use
1072 if (seg->enabled) {
1073 // For in frame complexity AQ copy the segment id from the segment map.
1074 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1075 const uint8_t *const map =
1076 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1077 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1078 }
1079 // Else for cyclic refresh mode update the segment map, set the segment id
1080 // and then update the quantizer.
1081 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001082 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1083 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001084 }
1085 }
1086
1087 max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
1088 for (i = 0; i < max_plane; ++i) {
1089 p[i].coeff = ctx->coeff[i][1];
1090 p[i].qcoeff = ctx->qcoeff[i][1];
1091 pd[i].dqcoeff = ctx->dqcoeff[i][1];
1092 p[i].eobs = ctx->eobs[i][1];
1093 }
1094
1095 for (i = max_plane; i < MAX_MB_PLANE; ++i) {
1096 p[i].coeff = ctx->coeff[i][2];
1097 p[i].qcoeff = ctx->qcoeff[i][2];
1098 pd[i].dqcoeff = ctx->dqcoeff[i][2];
1099 p[i].eobs = ctx->eobs[i][2];
1100 }
1101
Urvang Joshib100db72016-10-12 16:28:56 -07001102#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001103 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001104#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001105
1106 // Restore the coding context of the MB to that that was in place
1107 // when the mode was picked for it
1108 for (y = 0; y < mi_height; y++)
1109 for (x_idx = 0; x_idx < mi_width; x_idx++)
1110 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1111 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1112 xd->mi[x_idx + y * mis] = mi_addr;
1113 }
1114
Arild Fuldseth07441162016-08-15 15:07:52 +02001115#if CONFIG_DELTA_Q
1116 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001117 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001118#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001120 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001121#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001122
1123 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1124 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1125 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1126 }
1127
1128 x->skip = ctx->skip;
1129
1130#if CONFIG_VAR_TX
1131 for (i = 0; i < 1; ++i)
1132 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1133 sizeof(uint8_t) * ctx->num_4x4_blk);
1134#endif
1135
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001136 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001137
1138#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001139 {
1140 unsigned int *const mode_chosen_counts =
1141 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1142 if (frame_is_intra_only(cm)) {
1143 static const int kf_mode_index[] = {
1144 THR_DC /*DC_PRED*/, THR_V_PRED /*V_PRED*/,
1145 THR_H_PRED /*H_PRED*/, THR_D45_PRED /*D45_PRED*/,
1146 THR_D135_PRED /*D135_PRED*/, THR_D117_PRED /*D117_PRED*/,
1147 THR_D153_PRED /*D153_PRED*/, THR_D207_PRED /*D207_PRED*/,
1148 THR_D63_PRED /*D63_PRED*/, THR_TM /*TM_PRED*/,
1149 };
1150 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1151 } else {
1152 // Note how often each mode chosen as best
1153 ++mode_chosen_counts[ctx->best_mode_index];
1154 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001155 }
1156#endif
1157 if (!frame_is_intra_only(cm)) {
1158 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001159 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160#if CONFIG_GLOBAL_MOTION
1161 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001162 // TODO(sarahparker): global motion stats need to be handled per-tile
1163 // to be compatible with tile-based threading.
1164 update_global_motion_used(mbmi->mode, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001165 } else {
1166 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1167 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1168 int idx, idy;
1169 for (idy = 0; idy < 2; idy += num_4x4_h) {
1170 for (idx = 0; idx < 2; idx += num_4x4_w) {
1171 const int j = idy * 2 + idx;
James Zernaf322e12016-10-22 12:43:15 -07001172 update_global_motion_used(mi->bmi[j].as_mode, mbmi,
1173 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001174 }
1175 }
1176 }
1177#endif // CONFIG_GLOBAL_MOTION
1178 if (cm->interp_filter == SWITCHABLE
1179#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001180 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001181#endif
1182 ) {
1183#if CONFIG_DUAL_FILTER
1184 update_filter_type_count(td->counts, xd, mbmi);
1185#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001186 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1187 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188#endif
1189 }
1190 }
1191
1192 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1193 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1194 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1195 }
1196
1197 for (h = 0; h < y_mis; ++h) {
1198 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1199 for (w = 0; w < x_mis; ++w) {
1200 MV_REF *const mv = frame_mv + w;
1201 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1202 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1203 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1204 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1205 }
1206 }
1207}
1208
1209#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001210static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001211 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001212 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213 int y, x_idx;
1214#if CONFIG_VAR_TX || CONFIG_REF_MV
1215 int i;
1216#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001217 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001218 RD_COUNTS *const rdc = &td->rd_counts;
1219 MACROBLOCK *const x = &td->mb;
1220 MACROBLOCKD *const xd = &x->e_mbd;
1221 MODE_INFO *mi = &ctx->mic;
1222 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1223 MODE_INFO *mi_addr = xd->mi[0];
1224 const struct segmentation *const seg = &cm->seg;
1225 const int mis = cm->mi_stride;
1226 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1227 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001228 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1229 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001230 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1231 int w, h;
1232
1233#if CONFIG_REF_MV
1234 int8_t rf_type;
1235#endif
1236
1237 *mi_addr = *mi;
1238 *x->mbmi_ext = ctx->mbmi_ext;
1239 assert(is_inter_block(mbmi));
1240 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1241
1242#if CONFIG_DUAL_FILTER
1243 reset_intmv_filter_type(cm, xd, mbmi);
1244#endif
1245
1246#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001247 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1249 mbmi->mode == NEWMV) {
1250 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1251 int_mv this_mv =
1252 (i == 0)
1253 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1254 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1255 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1256 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1257 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1258 mbmi->pred_mv[i] = this_mv;
1259 }
1260 }
1261#endif
1262
1263 // If segmentation in use
1264 if (seg->enabled) {
1265 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001266 const int energy =
1267 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1268 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001269 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1270 // For cyclic refresh mode, now update the segment map
1271 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001272 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1273 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001274 } else {
1275 // Otherwise just set the segment id based on the current segment map
1276 const uint8_t *const map =
1277 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1278 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1279 }
1280 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1281 }
1282
1283 // Restore the coding context of the MB to that that was in place
1284 // when the mode was picked for it
1285 for (y = 0; y < mi_height; y++)
1286 for (x_idx = 0; x_idx < mi_width; x_idx++)
1287 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1288 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1289 xd->mi[x_idx + y * mis] = mi_addr;
1290 }
1291
1292 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1293 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1294 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1295 }
1296
1297 x->skip = ctx->skip;
1298
1299#if CONFIG_VAR_TX
1300 for (i = 0; i < 1; ++i)
1301 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1302 sizeof(uint8_t) * ctx->num_4x4_blk);
1303#endif // CONFIG_VAR_TX
1304
1305#if CONFIG_VAR_TX
1306 {
1307 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001308 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1309 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001310 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001311 mbmi->inter_tx_size[0][0] = mtx;
1312 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1313 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1314 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001315 }
1316#endif // CONFIG_VAR_TX
1317 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001318 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001320 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001321
1322 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001323 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001324
1325 if (cm->interp_filter == SWITCHABLE
1326#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001327 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001328#endif
1329 ) {
1330#if CONFIG_DUAL_FILTER
1331 update_filter_type_count(td->counts, xd, mbmi);
1332#else
James Zern9ca190c2016-10-22 12:42:43 -07001333 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1334 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001335#endif
1336 }
1337
1338 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1339 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1340 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1341 }
1342
1343 for (h = 0; h < y_mis; ++h) {
1344 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1345 for (w = 0; w < x_mis; ++w) {
1346 MV_REF *const mv = frame_mv + w;
1347 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1348 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1349 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1350 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1351 }
1352 }
1353}
1354
Urvang Joshi52648442016-10-13 17:27:51 -07001355static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356 const TileInfo *const tile, int mi_row,
1357 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001358 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001359 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360 MACROBLOCK *const x = &td->mb;
1361 MACROBLOCKD *const xd = &x->e_mbd;
1362 struct macroblock_plane *const p = x->plane;
1363 struct macroblockd_plane *const pd = xd->plane;
1364 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1365 PARTITION_TYPE partition = pc_tree->partitioning;
1366 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1367 int i;
1368#if CONFIG_EXT_PARTITION_TYPES
1369 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1370#endif
1371 PICK_MODE_CONTEXT *pmc = NULL;
1372
1373 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1374
1375 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001376 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001377
1378 switch (partition) {
1379 case PARTITION_NONE:
1380 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1381 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001382 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383 break;
1384 case PARTITION_VERT:
1385 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1386 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001387 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1389 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1390 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001391 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001392 }
1393 pmc = &pc_tree->vertical_supertx;
1394 break;
1395 case PARTITION_HORZ:
1396 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1397 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001398 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001399 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1400 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1401 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001402 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001403 }
1404 pmc = &pc_tree->horizontal_supertx;
1405 break;
1406 case PARTITION_SPLIT:
1407 if (bsize == BLOCK_8X8) {
1408 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1409 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001410 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001411 } else {
1412 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001413 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1414 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1416 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001417 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001418 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1419 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001420 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001421 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1422 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001423 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001424 }
1425 pmc = &pc_tree->split_supertx;
1426 break;
1427#if CONFIG_EXT_PARTITION_TYPES
1428 case PARTITION_HORZ_A:
1429 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1430 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001431 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1433 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001434 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1436 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001437 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001438 pmc = &pc_tree->horizontala_supertx;
1439 break;
1440 case PARTITION_HORZ_B:
1441 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1442 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001443 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001444 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1445 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001446 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001447 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1448 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001449 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001450 pmc = &pc_tree->horizontalb_supertx;
1451 break;
1452 case PARTITION_VERT_A:
1453 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1454 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001455 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001456 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1457 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001458 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001459 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1460 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001461 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462 pmc = &pc_tree->verticala_supertx;
1463 break;
1464 case PARTITION_VERT_B:
1465 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1466 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001467 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001468 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1469 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001470 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001471 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1472 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001473 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474 pmc = &pc_tree->verticalb_supertx;
1475 break;
1476#endif // CONFIG_EXT_PARTITION_TYPES
1477 default: assert(0);
1478 }
1479
1480 for (i = 0; i < MAX_MB_PLANE; ++i) {
1481 if (pmc != NULL) {
1482 p[i].coeff = pmc->coeff[i][1];
1483 p[i].qcoeff = pmc->qcoeff[i][1];
1484 pd[i].dqcoeff = pmc->dqcoeff[i][1];
1485 p[i].eobs = pmc->eobs[i][1];
1486 } else {
1487 // These should never be used
1488 p[i].coeff = NULL;
1489 p[i].qcoeff = NULL;
1490 pd[i].dqcoeff = NULL;
1491 p[i].eobs = NULL;
1492 }
1493 }
1494}
1495
1496static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1497 int best_tx, TX_SIZE supertx_size) {
1498 MACROBLOCK *const x = &td->mb;
1499#if CONFIG_VAR_TX
1500 int i;
1501
1502 for (i = 0; i < 1; ++i)
1503 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1504 sizeof(uint8_t) * ctx->num_4x4_blk);
1505#endif // CONFIG_VAR_TX
1506 ctx->mic.mbmi.tx_size = supertx_size;
1507 ctx->skip = x->skip;
1508 ctx->mic.mbmi.tx_type = best_tx;
1509}
1510
Urvang Joshi52648442016-10-13 17:27:51 -07001511static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1512 int mi_row, int mi_col, BLOCK_SIZE bsize,
1513 int best_tx, TX_SIZE supertx_size,
1514 PC_TREE *pc_tree) {
1515 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001516 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1517 PARTITION_TYPE partition = pc_tree->partitioning;
1518 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1519#if CONFIG_EXT_PARTITION_TYPES
1520 int i;
1521#endif
1522
1523 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1524
1525 switch (partition) {
1526 case PARTITION_NONE:
1527 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1528 break;
1529 case PARTITION_VERT:
1530 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
1531 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8)
1532 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1533 break;
1534 case PARTITION_HORZ:
1535 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
1536 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8)
1537 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1538 supertx_size);
1539 break;
1540 case PARTITION_SPLIT:
1541 if (bsize == BLOCK_8X8) {
1542 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1543 } else {
1544 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1545 supertx_size, pc_tree->split[0]);
1546 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1547 supertx_size, pc_tree->split[1]);
1548 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1549 supertx_size, pc_tree->split[2]);
1550 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1551 best_tx, supertx_size, pc_tree->split[3]);
1552 }
1553 break;
1554#if CONFIG_EXT_PARTITION_TYPES
1555 case PARTITION_HORZ_A:
1556 for (i = 0; i < 3; i++)
1557 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1558 supertx_size);
1559 break;
1560 case PARTITION_HORZ_B:
1561 for (i = 0; i < 3; i++)
1562 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1563 supertx_size);
1564 break;
1565 case PARTITION_VERT_A:
1566 for (i = 0; i < 3; i++)
1567 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1568 break;
1569 case PARTITION_VERT_B:
1570 for (i = 0; i < 3; i++)
1571 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1572 break;
1573#endif // CONFIG_EXT_PARTITION_TYPES
1574 default: assert(0);
1575 }
1576}
1577#endif // CONFIG_SUPERTX
1578
Yaowu Xuf883b422016-08-30 14:01:10 -07001579void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1580 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001581 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1582 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1583 src->uv_crop_width };
1584 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1585 src->uv_crop_height };
1586 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1587 int i;
1588
1589 // Set current frame pointer.
1590 x->e_mbd.cur_buf = src;
1591
1592 for (i = 0; i < MAX_MB_PLANE; i++)
1593 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1594 strides[i], mi_row, mi_col, NULL,
1595 x->e_mbd.plane[i].subsampling_x,
1596 x->e_mbd.plane[i].subsampling_y);
1597}
1598
Urvang Joshi52648442016-10-13 17:27:51 -07001599static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001600 int8_t segment_id) {
1601 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001602 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001603 av1_init_plane_quantizers(cpi, x, segment_id);
1604 aom_clear_system_state();
1605 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1606 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001607}
1608
Urvang Joshi52648442016-10-13 17:27:51 -07001609static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001610 MACROBLOCK *const x, int mi_row, int mi_col,
1611 RD_COST *rd_cost,
1612#if CONFIG_SUPERTX
1613 int *totalrate_nocoef,
1614#endif
1615#if CONFIG_EXT_PARTITION_TYPES
1616 PARTITION_TYPE partition,
1617#endif
1618 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1619 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001620 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001621 TileInfo *const tile_info = &tile_data->tile_info;
1622 MACROBLOCKD *const xd = &x->e_mbd;
1623 MB_MODE_INFO *mbmi;
1624 struct macroblock_plane *const p = x->plane;
1625 struct macroblockd_plane *const pd = xd->plane;
1626 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1627 int i, orig_rdmult;
1628
Yaowu Xuf883b422016-08-30 14:01:10 -07001629 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001630
1631 // Use the lower precision, but faster, 32x32 fdct for mode selection.
1632 x->use_lp32x32fdct = 1;
1633
1634 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1635 mbmi = &xd->mi[0]->mbmi;
1636 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001637#if CONFIG_RD_DEBUG
1638 mbmi->mi_row = mi_row;
1639 mbmi->mi_col = mi_col;
1640#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001641#if CONFIG_SUPERTX
1642 // We set tx_size here as skip blocks would otherwise not set it.
1643 // tx_size needs to be set at this point as supertx_enable in
1644 // write_modes_sb is computed based on this, and if the garbage in memory
1645 // just happens to be the supertx_size, then the packer will code this
1646 // block as a supertx block, even if rdopt did not pick it as such.
1647 mbmi->tx_size = max_txsize_lookup[bsize];
1648#endif
1649#if CONFIG_EXT_PARTITION_TYPES
1650 mbmi->partition = partition;
1651#endif
1652
1653 for (i = 0; i < MAX_MB_PLANE; ++i) {
1654 p[i].coeff = ctx->coeff[i][0];
1655 p[i].qcoeff = ctx->qcoeff[i][0];
1656 pd[i].dqcoeff = ctx->dqcoeff[i][0];
1657 p[i].eobs = ctx->eobs[i][0];
1658 }
1659
Urvang Joshib100db72016-10-12 16:28:56 -07001660#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001661 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001662#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001663
Yaowu Xuc27fc142016-08-22 16:08:15 -07001664 ctx->skippable = 0;
1665 ctx->pred_pixel_ready = 0;
1666
1667 // Set to zero to make sure we do not use the previous encoded frame stats
1668 mbmi->skip = 0;
1669
Yaowu Xuf883b422016-08-30 14:01:10 -07001670#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001671 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001672 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001673 cpi, &x->plane[0].src, bsize, xd->bd);
1674 } else {
1675 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001676 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001677 }
1678#else
1679 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001680 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1681#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001682
1683 // Save rdmult before it might be changed, so it can be restored later.
1684 orig_rdmult = x->rdmult;
1685
1686 if (aq_mode == VARIANCE_AQ) {
1687 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001688 const int energy =
1689 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1690 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001691 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001692 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001693 }
1694 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1695 } else if (aq_mode == COMPLEXITY_AQ) {
1696 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1697 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1698 // If segment is boosted, use rdmult for that segment.
1699 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001700 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001701 }
1702
1703 // Find best coding mode & reconstruct the MB so it is available
1704 // as a predictor for MBs that follow in the SB
1705 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001706 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001707#if CONFIG_SUPERTX
1708 *totalrate_nocoef = 0;
1709#endif // CONFIG_SUPERTX
1710 } else {
1711 if (bsize >= BLOCK_8X8) {
1712 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001713 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1714 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715#if CONFIG_SUPERTX
1716 *totalrate_nocoef = rd_cost->rate;
1717#endif // CONFIG_SUPERTX
1718 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001719 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001720#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001721 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001722#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001723 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001724#if CONFIG_SUPERTX
1725 assert(*totalrate_nocoef >= 0);
1726#endif // CONFIG_SUPERTX
1727 }
1728 } else {
1729 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1730 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1731 rd_cost->rate = INT_MAX;
1732 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001733 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1734 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001735#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001736 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001737#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001738 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001739#if CONFIG_SUPERTX
1740 assert(*totalrate_nocoef >= 0);
1741#endif // CONFIG_SUPERTX
1742 }
1743 }
1744 }
1745
1746 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1747 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1748 (bsize >= BLOCK_16X16) &&
1749 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1750 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001751 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001752 }
1753
1754 x->rdmult = orig_rdmult;
1755
1756 // TODO(jingning) The rate-distortion optimization flow needs to be
1757 // refactored to provide proper exit/return handle.
1758 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1759
1760 ctx->rate = rd_cost->rate;
1761 ctx->dist = rd_cost->dist;
1762}
1763
1764#if CONFIG_REF_MV
1765static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1766#if CONFIG_EXT_INTER
1767 int is_compound,
1768#endif // CONFIG_EXT_INTER
1769 int16_t mode_context) {
1770 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1771#if CONFIG_EXT_INTER
1772 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1773 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1774#else
1775 if (mode == NEWMV) {
1776#endif // CONFIG_EXT_INTER
1777 ++counts->newmv_mode[mode_ctx][0];
1778 return;
1779 } else {
1780 ++counts->newmv_mode[mode_ctx][1];
1781
1782 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1783 return;
1784 }
1785
1786 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1787 if (mode == ZEROMV) {
1788 ++counts->zeromv_mode[mode_ctx][0];
1789 return;
1790 } else {
1791 ++counts->zeromv_mode[mode_ctx][1];
1792 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1793
1794 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1795 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1796 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1797
1798 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1799 }
1800 }
1801}
1802#endif
1803
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001804static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1805 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806#if CONFIG_SUPERTX
1807 ,
1808 int supertx_enabled
1809#endif
1810 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01001811#if CONFIG_DELTA_Q
1812 MACROBLOCK *x = &td->mb;
1813 MACROBLOCKD *const xd = &x->e_mbd;
1814#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001815 const MACROBLOCK *x = &td->mb;
1816 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01001817#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001818 const MODE_INFO *const mi = xd->mi[0];
1819 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1820 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1821 const BLOCK_SIZE bsize = mbmi->sb_type;
1822
Thomas Daviesf6936102016-09-05 16:51:31 +01001823#if CONFIG_DELTA_Q
1824 // delta quant applies to both intra and inter
1825 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
1826
1827 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
1828 super_block_upper_left) {
1829 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1830 const int absdq = abs(dq);
1831 int i;
1832 for (i = 0; i < absdq; ++i) {
1833 td->counts->delta_q[i][1]++;
1834 }
1835 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1836 xd->prev_qindex = mbmi->current_q_index;
1837 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001838#else
1839 (void)mi_row;
1840 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01001841#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842 if (!frame_is_intra_only(cm)) {
1843 FRAME_COUNTS *const counts = td->counts;
1844 const int inter_block = is_inter_block(mbmi);
1845 const int seg_ref_active =
1846 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1847 if (!seg_ref_active) {
1848#if CONFIG_SUPERTX
1849 if (!supertx_enabled)
1850#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001851 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001852 // If the segment reference feature is enabled we have only a single
1853 // reference frame allowed for the segment so exclude it from
1854 // the reference frame counts used to work out probabilities.
1855 if (inter_block) {
1856 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1857#if CONFIG_EXT_REFS
1858 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1859#endif // CONFIG_EXT_REFS
1860
1861 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07001862 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1863 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001864
1865 if (has_second_ref(mbmi)) {
1866#if CONFIG_EXT_REFS
1867 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1868
Yaowu Xuf883b422016-08-30 14:01:10 -07001869 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001870 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07001871 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1872 [ref0 == LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873 } else {
clang-format67948d32016-09-07 22:40:40 -07001874 counts->comp_ref[av1_get_pred_context_comp_ref_p2(cm, xd)][2]
1875 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001876 }
1877
clang-format67948d32016-09-07 22:40:40 -07001878 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1879 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880#else
clang-format67948d32016-09-07 22:40:40 -07001881 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1882 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883#endif // CONFIG_EXT_REFS
1884 } else {
1885#if CONFIG_EXT_REFS
1886 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
1887
Yaowu Xuf883b422016-08-30 14:01:10 -07001888 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07001890 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1891 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001892 } else {
1893 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001894 counts->single_ref[av1_get_pred_context_single_ref_p3(xd)][2]
1895 [bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001896 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001897 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1898 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899 } else {
clang-format67948d32016-09-07 22:40:40 -07001900 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1901 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902 }
1903 }
1904#else
clang-format67948d32016-09-07 22:40:40 -07001905 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1906 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001907 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07001908 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1909 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001910 }
1911#endif // CONFIG_EXT_REFS
1912 }
1913
1914#if CONFIG_EXT_INTER
1915 if (cm->reference_mode != COMPOUND_REFERENCE &&
1916#if CONFIG_SUPERTX
1917 !supertx_enabled &&
1918#endif
1919 is_interintra_allowed(mbmi)) {
1920 const int bsize_group = size_group_lookup[bsize];
1921 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1922 counts->interintra[bsize_group][1]++;
1923 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1924 if (is_interintra_wedge_used(bsize))
1925 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1926 } else {
1927 counts->interintra[bsize_group][0]++;
1928 }
1929 }
1930#endif // CONFIG_EXT_INTER
1931
Yue Chencb60b182016-10-13 15:18:22 -07001932#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001933#if CONFIG_SUPERTX
1934 if (!supertx_enabled)
1935#endif // CONFIG_SUPERTX
1936#if CONFIG_EXT_INTER
1937 if (mbmi->ref_frame[1] != INTRA_FRAME)
1938#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001939 if (is_motion_variation_allowed(mbmi))
1940 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1941#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001942
1943#if CONFIG_EXT_INTER
1944 if (cm->reference_mode != SINGLE_REFERENCE &&
1945 is_inter_compound_mode(mbmi->mode) &&
Yue Chencb60b182016-10-13 15:18:22 -07001946#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1947 !(is_motion_variation_allowed(mbmi) &&
1948 mbmi->motion_mode != SIMPLE_TRANSLATION) &&
1949#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001950 is_interinter_wedge_used(bsize)) {
1951 counts->wedge_interinter[bsize][mbmi->use_wedge_interinter]++;
1952 }
1953#endif // CONFIG_EXT_INTER
1954 }
1955 }
1956
1957 if (inter_block &&
1958 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1959 int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
1960 if (bsize >= BLOCK_8X8) {
1961 const PREDICTION_MODE mode = mbmi->mode;
1962#if CONFIG_REF_MV
1963#if CONFIG_EXT_INTER
1964 if (has_second_ref(mbmi)) {
1965 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1966 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
1967 } else {
1968#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001969 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
1970 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001971 update_inter_mode_stats(counts, mode,
1972#if CONFIG_EXT_INTER
1973 has_second_ref(mbmi),
1974#endif // CONFIG_EXT_INTER
1975 mode_ctx);
1976
1977 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001978 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001979 int idx;
1980
1981 for (idx = 0; idx < 2; ++idx) {
1982 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1983 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07001984 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001985 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
1986
1987 if (mbmi->ref_mv_idx == idx) break;
1988 }
1989 }
1990 }
1991
1992 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001993 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001994 int idx;
1995
1996 for (idx = 1; idx < 3; ++idx) {
1997 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1998 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07001999 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002000 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2001
2002 if (mbmi->ref_mv_idx == idx - 1) break;
2003 }
2004 }
2005 }
2006#if CONFIG_EXT_INTER
2007 }
2008#endif // CONFIG_EXT_INTER
2009#else
2010#if CONFIG_EXT_INTER
2011 if (is_inter_compound_mode(mode))
2012 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2013 else
2014#endif // CONFIG_EXT_INTER
2015 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2016#endif
2017 } else {
2018 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2019 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2020 int idx, idy;
2021 for (idy = 0; idy < 2; idy += num_4x4_h) {
2022 for (idx = 0; idx < 2; idx += num_4x4_w) {
2023 const int j = idy * 2 + idx;
2024 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2025#if CONFIG_REF_MV
2026#if CONFIG_EXT_INTER
2027 if (has_second_ref(mbmi)) {
2028 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002029 ++counts->inter_compound_mode[mode_ctx]
2030 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002031 } else {
2032#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002033 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2034 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002035 update_inter_mode_stats(counts, b_mode,
2036#if CONFIG_EXT_INTER
2037 has_second_ref(mbmi),
2038#endif // CONFIG_EXT_INTER
2039 mode_ctx);
2040#if CONFIG_EXT_INTER
2041 }
2042#endif // CONFIG_EXT_INTER
2043#else
2044#if CONFIG_EXT_INTER
2045 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002046 ++counts->inter_compound_mode[mode_ctx]
2047 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002048 else
2049#endif // CONFIG_EXT_INTER
2050 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2051#endif
2052 }
2053 }
2054 }
2055 }
2056 }
2057}
2058
2059typedef struct {
2060 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2061 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2062 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2063 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2064#if CONFIG_VAR_TX
2065 TXFM_CONTEXT *p_ta;
2066 TXFM_CONTEXT *p_tl;
2067 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2068 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2069#endif
2070} RD_SEARCH_MACROBLOCK_CONTEXT;
2071
2072static void restore_context(MACROBLOCK *x,
2073 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
2074 int mi_col, BLOCK_SIZE bsize) {
2075 MACROBLOCKD *xd = &x->e_mbd;
2076 int p;
2077 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2078 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2079 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2080 int mi_height = num_8x8_blocks_high_lookup[bsize];
2081 for (p = 0; p < MAX_MB_PLANE; p++) {
2082 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2083 ctx->a + num_4x4_blocks_wide * p,
2084 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2085 xd->plane[p].subsampling_x);
2086 memcpy(xd->left_context[p] +
2087 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2088 ctx->l + num_4x4_blocks_high * p,
2089 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2090 xd->plane[p].subsampling_y);
2091 }
2092 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2093 sizeof(*xd->above_seg_context) * mi_width);
2094 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2095 sizeof(xd->left_seg_context[0]) * mi_height);
2096#if CONFIG_VAR_TX
2097 xd->above_txfm_context = ctx->p_ta;
2098 xd->left_txfm_context = ctx->p_tl;
2099 memcpy(xd->above_txfm_context, ctx->ta,
2100 sizeof(*xd->above_txfm_context) * mi_width);
2101 memcpy(xd->left_txfm_context, ctx->tl,
2102 sizeof(*xd->left_txfm_context) * mi_height);
2103#endif
2104}
2105
2106static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
2107 int mi_row, int mi_col, BLOCK_SIZE bsize) {
2108 const MACROBLOCKD *xd = &x->e_mbd;
2109 int p;
2110 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2111 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2112 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2113 int mi_height = num_8x8_blocks_high_lookup[bsize];
2114
2115 // buffer the above/left context information of the block in search.
2116 for (p = 0; p < MAX_MB_PLANE; ++p) {
2117 memcpy(ctx->a + num_4x4_blocks_wide * p,
2118 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2119 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2120 xd->plane[p].subsampling_x);
2121 memcpy(ctx->l + num_4x4_blocks_high * p,
2122 xd->left_context[p] +
2123 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2124 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2125 xd->plane[p].subsampling_y);
2126 }
2127 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2128 sizeof(*xd->above_seg_context) * mi_width);
2129 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2130 sizeof(xd->left_seg_context[0]) * mi_height);
2131#if CONFIG_VAR_TX
2132 memcpy(ctx->ta, xd->above_txfm_context,
2133 sizeof(*xd->above_txfm_context) * mi_width);
2134 memcpy(ctx->tl, xd->left_txfm_context,
2135 sizeof(*xd->left_txfm_context) * mi_height);
2136 ctx->p_ta = xd->above_txfm_context;
2137 ctx->p_tl = xd->left_txfm_context;
2138#endif
2139}
2140
Urvang Joshi52648442016-10-13 17:27:51 -07002141static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2142 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2143 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002144#if CONFIG_EXT_PARTITION_TYPES
2145 PARTITION_TYPE partition,
2146#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002147 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002148 MACROBLOCK *const x = &td->mb;
2149 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2150#if CONFIG_EXT_PARTITION_TYPES
2151 x->e_mbd.mi[0]->mbmi.partition = partition;
2152#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002153 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2154 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002155
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002156 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002157#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002158 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002159#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002160 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002161#endif
2162 }
2163}
2164
Urvang Joshi52648442016-10-13 17:27:51 -07002165static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2166 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2167 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2168 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002169 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002170 MACROBLOCK *const x = &td->mb;
2171 MACROBLOCKD *const xd = &x->e_mbd;
2172
2173 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
2174 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
2175 const PARTITION_TYPE partition = pc_tree->partitioning;
2176 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2177#if CONFIG_EXT_PARTITION_TYPES
2178 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2179#endif
2180
2181 assert(bsize >= BLOCK_8X8);
2182
2183 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2184
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002185 if (!dry_run) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002186
2187#if CONFIG_SUPERTX
2188 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2189 partition != PARTITION_NONE && !xd->lossless[0]) {
2190 int supertx_enabled;
2191 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2192 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2193 if (supertx_enabled) {
2194 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2195 const int mi_height = num_8x8_blocks_high_lookup[bsize];
2196 int x_idx, y_idx, i;
2197 uint8_t *dst_buf[3];
2198 int dst_stride[3];
2199 set_skip_context(xd, mi_row, mi_col);
2200 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002201 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2202 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002203
Yaowu Xuf883b422016-08-30 14:01:10 -07002204 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002205 for (i = 0; i < MAX_MB_PLANE; i++) {
2206 dst_buf[i] = xd->plane[i].dst.buf;
2207 dst_stride[i] = xd->plane[i].dst.stride;
2208 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002209 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2210 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002211
2212 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2213 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2214
2215 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002216 int this_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002217 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2218
Angie Chiangff6d8902016-10-21 11:02:09 -07002219 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002220 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2221 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002222 } else {
2223 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002224 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002225 reset_skip_context(xd, bsize);
2226 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002227 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002228 for (y_idx = 0; y_idx < mi_height; y_idx++)
2229 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2230 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2231 x_idx &&
2232 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2233 y_idx) {
2234 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2235 xd->mi[0]->mbmi.skip;
2236 }
2237 }
2238 td->counts->supertx[partition_supertx_context_lookup[partition]]
2239 [supertx_size][1]++;
2240 td->counts->supertx_size[supertx_size]++;
2241#if CONFIG_EXT_TX
2242 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2243 !xd->mi[0]->mbmi.skip) {
2244 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2245 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002246 ++td->counts->inter_ext_tx[eset][supertx_size]
2247 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002248 }
2249 }
2250#else
2251 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2252 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2253 }
2254#endif // CONFIG_EXT_TX
2255 }
2256#if CONFIG_EXT_PARTITION_TYPES
2257 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2258 partition);
2259#else
2260 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2261 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2262#endif
2263#if CONFIG_VAR_TX
2264 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd);
2265#endif // CONFIG_VAR_TX
2266 return;
2267 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002268 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002269 td->counts->supertx[partition_supertx_context_lookup[partition]]
2270 [supertx_size][0]++;
2271 }
2272 }
2273 }
2274#endif // CONFIG_SUPERTX
2275
2276 switch (partition) {
2277 case PARTITION_NONE:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002278 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002279#if CONFIG_EXT_PARTITION_TYPES
2280 partition,
2281#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002282 &pc_tree->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002283 break;
2284 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002285 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002286#if CONFIG_EXT_PARTITION_TYPES
2287 partition,
2288#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002289 &pc_tree->vertical[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002290 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002291 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292#if CONFIG_EXT_PARTITION_TYPES
2293 partition,
2294#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002295 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002296 }
2297 break;
2298 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002299 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002300#if CONFIG_EXT_PARTITION_TYPES
2301 partition,
2302#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002303 &pc_tree->horizontal[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002305 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002306#if CONFIG_EXT_PARTITION_TYPES
2307 partition,
2308#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002309 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002310 }
2311 break;
2312 case PARTITION_SPLIT:
2313 if (bsize == BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002314 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315#if CONFIG_EXT_PARTITION_TYPES
2316 partition,
2317#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002318 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002319 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002320 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2321 pc_tree->split[0], rate);
2322 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2323 pc_tree->split[1], rate);
2324 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2325 pc_tree->split[2], rate);
2326 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2327 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002328 }
2329 break;
2330#if CONFIG_EXT_PARTITION_TYPES
2331 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002332 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2333 &pc_tree->horizontala[0], rate);
2334 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2335 partition, &pc_tree->horizontala[1], rate);
2336 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2337 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002338 break;
2339 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002340 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2341 &pc_tree->horizontalb[0], rate);
2342 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2343 partition, &pc_tree->horizontalb[1], rate);
2344 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2345 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002346 break;
2347 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002348 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2349 &pc_tree->verticala[0], rate);
2350 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2351 partition, &pc_tree->verticala[1], rate);
2352 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2353 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002354
2355 break;
2356 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002357 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2358 &pc_tree->verticalb[0], rate);
2359 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2360 partition, &pc_tree->verticalb[1], rate);
2361 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2362 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002363 break;
2364#endif // CONFIG_EXT_PARTITION_TYPES
2365 default: assert(0 && "Invalid partition type."); break;
2366 }
2367
2368#if CONFIG_EXT_PARTITION_TYPES
2369 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2370#else
2371 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2372 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2373#endif // CONFIG_EXT_PARTITION_TYPES
2374}
2375
2376// Check to see if the given partition size is allowed for a specified number
2377// of mi block rows and columns remaining in the image.
2378// If not then return the largest allowed partition size
2379static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2380 int cols_left, int *bh, int *bw) {
2381 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002382 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383 } else {
2384 for (; bsize > 0; bsize -= 3) {
2385 *bh = num_8x8_blocks_high_lookup[bsize];
2386 *bw = num_8x8_blocks_wide_lookup[bsize];
2387 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2388 break;
2389 }
2390 }
2391 }
2392 return bsize;
2393}
2394
Yaowu Xuf883b422016-08-30 14:01:10 -07002395static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002396 int bh_in, int bw_in,
2397 int mi_rows_remaining,
2398 int mi_cols_remaining, BLOCK_SIZE bsize,
2399 MODE_INFO **mib) {
2400 int bh = bh_in;
2401 int r, c;
2402 for (r = 0; r < cm->mib_size; r += bh) {
2403 int bw = bw_in;
2404 for (c = 0; c < cm->mib_size; c += bw) {
2405 const int index = r * cm->mi_stride + c;
2406 mib[index] = mi + index;
2407 mib[index]->mbmi.sb_type = find_partition_size(
2408 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2409 }
2410 }
2411}
2412
2413// This function attempts to set all mode info entries in a given superblock
2414// to the same block partition size.
2415// However, at the bottom and right borders of the image the requested size
2416// may not be allowed in which case this code attempts to choose the largest
2417// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002418static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002419 MODE_INFO **mib, int mi_row, int mi_col,
2420 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002421 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002422 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2423 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2424 int block_row, block_col;
2425 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2426 int bh = num_8x8_blocks_high_lookup[bsize];
2427 int bw = num_8x8_blocks_wide_lookup[bsize];
2428
2429 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2430
2431 // Apply the requested partition size to the SB if it is all "in image"
2432 if ((mi_cols_remaining >= cm->mib_size) &&
2433 (mi_rows_remaining >= cm->mib_size)) {
2434 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2435 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2436 int index = block_row * cm->mi_stride + block_col;
2437 mib[index] = mi_upper_left + index;
2438 mib[index]->mbmi.sb_type = bsize;
2439 }
2440 }
2441 } else {
2442 // Else this is a partial SB.
2443 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2444 mi_cols_remaining, bsize, mib);
2445 }
2446}
2447
Yaowu Xuf883b422016-08-30 14:01:10 -07002448static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002449 TileDataEnc *tile_data, MODE_INFO **mib,
2450 TOKENEXTRA **tp, int mi_row, int mi_col,
2451 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2452#if CONFIG_SUPERTX
2453 int *rate_nocoef,
2454#endif
2455 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002456 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457 TileInfo *const tile_info = &tile_data->tile_info;
2458 MACROBLOCK *const x = &td->mb;
2459 MACROBLOCKD *const xd = &x->e_mbd;
2460 const int bs = num_8x8_blocks_wide_lookup[bsize];
2461 const int hbs = bs / 2;
2462 int i;
2463 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2464 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2465 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2466 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2467 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2468 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2469 int splits_below = 0;
2470 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2471 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002472 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002473#if CONFIG_SUPERTX
2474 int last_part_rate_nocoef = INT_MAX;
2475 int none_rate_nocoef = INT_MAX;
2476 int chosen_rate_nocoef = INT_MAX;
2477#endif
2478
2479 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2480
2481 assert(num_4x4_blocks_wide_lookup[bsize] ==
2482 num_4x4_blocks_high_lookup[bsize]);
2483
Yaowu Xuf883b422016-08-30 14:01:10 -07002484 av1_rd_cost_reset(&last_part_rdc);
2485 av1_rd_cost_reset(&none_rdc);
2486 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002487
2488 pc_tree->partitioning = partition;
2489
2490#if CONFIG_VAR_TX
2491 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2492 xd->left_txfm_context =
2493 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2494#endif
2495
2496 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2497
2498 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2499 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002500 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002501 }
2502
2503 if (do_partition_search &&
2504 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2505 cpi->sf.adjust_partitioning_from_last_frame) {
2506 // Check if any of the sub blocks are further split.
2507 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2508 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2509 splits_below = 1;
2510 for (i = 0; i < 4; i++) {
2511 int jj = i >> 1, ii = i & 0x01;
2512 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2513 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2514 splits_below = 0;
2515 }
2516 }
2517 }
2518
2519 // If partition is not none try none unless each of the 4 splits are split
2520 // even further..
2521 if (partition != PARTITION_NONE && !splits_below &&
2522 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2523 pc_tree->partitioning = PARTITION_NONE;
2524 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2525#if CONFIG_SUPERTX
2526 &none_rate_nocoef,
2527#endif
2528#if CONFIG_EXT_PARTITION_TYPES
2529 PARTITION_NONE,
2530#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002531 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002532
2533 if (none_rdc.rate < INT_MAX) {
2534 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2535 none_rdc.rdcost =
2536 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2537#if CONFIG_SUPERTX
2538 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2539#endif
2540 }
2541
2542 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2543
2544 mib[0]->mbmi.sb_type = bs_type;
2545 pc_tree->partitioning = partition;
2546 }
2547 }
2548
2549 switch (partition) {
2550 case PARTITION_NONE:
2551 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2552#if CONFIG_SUPERTX
2553 &last_part_rate_nocoef,
2554#endif
2555#if CONFIG_EXT_PARTITION_TYPES
2556 PARTITION_NONE,
2557#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002558 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002559 break;
2560 case PARTITION_HORZ:
2561 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2562#if CONFIG_SUPERTX
2563 &last_part_rate_nocoef,
2564#endif
2565#if CONFIG_EXT_PARTITION_TYPES
2566 PARTITION_HORZ,
2567#endif
2568 subsize, &pc_tree->horizontal[0], INT64_MAX);
2569 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2570 mi_row + hbs < cm->mi_rows) {
2571 RD_COST tmp_rdc;
2572#if CONFIG_SUPERTX
2573 int rt_nocoef = 0;
2574#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002575 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002576 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002577 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002578 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002579 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002580 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2581#if CONFIG_SUPERTX
2582 &rt_nocoef,
2583#endif
2584#if CONFIG_EXT_PARTITION_TYPES
2585 PARTITION_HORZ,
2586#endif
2587 subsize, &pc_tree->horizontal[1], INT64_MAX);
2588 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002589 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590#if CONFIG_SUPERTX
2591 last_part_rate_nocoef = INT_MAX;
2592#endif
2593 break;
2594 }
2595 last_part_rdc.rate += tmp_rdc.rate;
2596 last_part_rdc.dist += tmp_rdc.dist;
2597 last_part_rdc.rdcost += tmp_rdc.rdcost;
2598#if CONFIG_SUPERTX
2599 last_part_rate_nocoef += rt_nocoef;
2600#endif
2601 }
2602 break;
2603 case PARTITION_VERT:
2604 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2605#if CONFIG_SUPERTX
2606 &last_part_rate_nocoef,
2607#endif
2608#if CONFIG_EXT_PARTITION_TYPES
2609 PARTITION_VERT,
2610#endif
2611 subsize, &pc_tree->vertical[0], INT64_MAX);
2612 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2613 mi_col + hbs < cm->mi_cols) {
2614 RD_COST tmp_rdc;
2615#if CONFIG_SUPERTX
2616 int rt_nocoef = 0;
2617#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002618 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002619 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002620 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002621 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002622 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002623 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2624#if CONFIG_SUPERTX
2625 &rt_nocoef,
2626#endif
2627#if CONFIG_EXT_PARTITION_TYPES
2628 PARTITION_VERT,
2629#endif
2630 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2631 INT64_MAX);
2632 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002633 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002634#if CONFIG_SUPERTX
2635 last_part_rate_nocoef = INT_MAX;
2636#endif
2637 break;
2638 }
2639 last_part_rdc.rate += tmp_rdc.rate;
2640 last_part_rdc.dist += tmp_rdc.dist;
2641 last_part_rdc.rdcost += tmp_rdc.rdcost;
2642#if CONFIG_SUPERTX
2643 last_part_rate_nocoef += rt_nocoef;
2644#endif
2645 }
2646 break;
2647 case PARTITION_SPLIT:
2648 if (bsize == BLOCK_8X8) {
2649 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2650#if CONFIG_SUPERTX
2651 &last_part_rate_nocoef,
2652#endif
2653#if CONFIG_EXT_PARTITION_TYPES
2654 PARTITION_SPLIT,
2655#endif
2656 subsize, pc_tree->leaf_split[0], INT64_MAX);
2657 break;
2658 }
2659 last_part_rdc.rate = 0;
2660 last_part_rdc.dist = 0;
2661 last_part_rdc.rdcost = 0;
2662#if CONFIG_SUPERTX
2663 last_part_rate_nocoef = 0;
2664#endif
2665 for (i = 0; i < 4; i++) {
2666 int x_idx = (i & 1) * hbs;
2667 int y_idx = (i >> 1) * hbs;
2668 int jj = i >> 1, ii = i & 0x01;
2669 RD_COST tmp_rdc;
2670#if CONFIG_SUPERTX
2671 int rt_nocoef;
2672#endif
2673 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2674 continue;
2675
Yaowu Xuf883b422016-08-30 14:01:10 -07002676 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002677 rd_use_partition(cpi, td, tile_data,
2678 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2679 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2680 &tmp_rdc.dist,
2681#if CONFIG_SUPERTX
2682 &rt_nocoef,
2683#endif
2684 i != 3, pc_tree->split[i]);
2685 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002686 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002687#if CONFIG_SUPERTX
2688 last_part_rate_nocoef = INT_MAX;
2689#endif
2690 break;
2691 }
2692 last_part_rdc.rate += tmp_rdc.rate;
2693 last_part_rdc.dist += tmp_rdc.dist;
2694#if CONFIG_SUPERTX
2695 last_part_rate_nocoef += rt_nocoef;
2696#endif
2697 }
2698 break;
2699#if CONFIG_EXT_PARTITION_TYPES
2700 case PARTITION_VERT_A:
2701 case PARTITION_VERT_B:
2702 case PARTITION_HORZ_A:
2703 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2704#endif // CONFIG_EXT_PARTITION_TYPES
2705 default: assert(0); break;
2706 }
2707
2708 if (last_part_rdc.rate < INT_MAX) {
2709 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2710 last_part_rdc.rdcost =
2711 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2712#if CONFIG_SUPERTX
2713 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2714#endif
2715 }
2716
2717 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2718 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2719 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2720 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2721 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2722 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2723 chosen_rdc.rate = 0;
2724 chosen_rdc.dist = 0;
2725#if CONFIG_SUPERTX
2726 chosen_rate_nocoef = 0;
2727#endif
2728
2729 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2730
2731 pc_tree->partitioning = PARTITION_SPLIT;
2732
2733 // Split partition.
2734 for (i = 0; i < 4; i++) {
2735 int x_idx = (i & 1) * hbs;
2736 int y_idx = (i >> 1) * hbs;
2737 RD_COST tmp_rdc;
2738#if CONFIG_SUPERTX
2739 int rt_nocoef = 0;
2740#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002741 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2742 continue;
2743
2744 save_context(x, &x_ctx, mi_row, mi_col, bsize);
2745 pc_tree->split[i]->partitioning = PARTITION_NONE;
2746 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2747 &tmp_rdc,
2748#if CONFIG_SUPERTX
2749 &rt_nocoef,
2750#endif
2751#if CONFIG_EXT_PARTITION_TYPES
2752 PARTITION_SPLIT,
2753#endif
2754 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2755
2756 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2757
2758 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002759 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760#if CONFIG_SUPERTX
2761 chosen_rate_nocoef = INT_MAX;
2762#endif
2763 break;
2764 }
2765
2766 chosen_rdc.rate += tmp_rdc.rate;
2767 chosen_rdc.dist += tmp_rdc.dist;
2768#if CONFIG_SUPERTX
2769 chosen_rate_nocoef += rt_nocoef;
2770#endif
2771
2772 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002773 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2774 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002775
2776 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2777#if CONFIG_SUPERTX
2778 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2779#endif
2780 }
2781 if (chosen_rdc.rate < INT_MAX) {
2782 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2783 chosen_rdc.rdcost =
2784 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2785#if CONFIG_SUPERTX
2786 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2787#endif
2788 }
2789 }
2790
2791 // If last_part is better set the partitioning to that.
2792 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2793 mib[0]->mbmi.sb_type = bsize;
2794 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2795 chosen_rdc = last_part_rdc;
2796#if CONFIG_SUPERTX
2797 chosen_rate_nocoef = last_part_rate_nocoef;
2798#endif
2799 }
2800 // If none was better set the partitioning to that.
2801 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2802 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2803 chosen_rdc = none_rdc;
2804#if CONFIG_SUPERTX
2805 chosen_rate_nocoef = none_rate_nocoef;
2806#endif
2807 }
2808
2809 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
2810
2811 // We must have chosen a partitioning and encoding or we'll fail later on.
2812 // No other opportunities for success.
2813 if (bsize == cm->sb_size)
2814 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2815
2816 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002817 if (bsize == cm->sb_size) {
2818 // NOTE: To get estimate for rate due to the tokens, use:
2819 // int rate_coeffs = 0;
2820 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2821 // bsize, pc_tree, &rate_coeffs);
2822 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2823 pc_tree, NULL);
2824 } else {
2825 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2826 pc_tree, NULL);
2827 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002828 }
2829
2830 *rate = chosen_rdc.rate;
2831 *dist = chosen_rdc.dist;
2832#if CONFIG_SUPERTX
2833 *rate_nocoef = chosen_rate_nocoef;
2834#endif
2835}
2836
2837/* clang-format off */
2838static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2839 BLOCK_4X4, // 4x4
2840 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2841 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2842 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2843 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2844#if CONFIG_EXT_PARTITION
2845 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2846#endif // CONFIG_EXT_PARTITION
2847};
2848
2849static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2850 BLOCK_8X8, // 4x4
2851 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2852 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2853 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2854 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2855#if CONFIG_EXT_PARTITION
2856 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2857#endif // CONFIG_EXT_PARTITION
2858};
2859
2860// Next square block size less or equal than current block size.
2861static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2862 BLOCK_4X4, // 4x4
2863 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2864 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2865 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2866 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2867#if CONFIG_EXT_PARTITION
2868 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
2869#endif // CONFIG_EXT_PARTITION
2870};
2871/* clang-format on */
2872
2873// Look at all the mode_info entries for blocks that are part of this
2874// partition and find the min and max values for sb_type.
2875// At the moment this is designed to work on a superblock but could be
2876// adjusted to use a size parameter.
2877//
2878// The min and max are assumed to have been initialized prior to calling this
2879// function so repeat calls can accumulate a min and max of more than one
2880// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002881static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882 MACROBLOCKD *xd, MODE_INFO **mib,
2883 BLOCK_SIZE *min_block_size,
2884 BLOCK_SIZE *max_block_size) {
2885 int i, j;
2886 int index = 0;
2887
2888 // Check the sb_type for each block that belongs to this region.
2889 for (i = 0; i < cm->mib_size; ++i) {
2890 for (j = 0; j < cm->mib_size; ++j) {
2891 MODE_INFO *mi = mib[index + j];
2892 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002893 *min_block_size = AOMMIN(*min_block_size, sb_type);
2894 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002895 }
2896 index += xd->mi_stride;
2897 }
2898}
2899
2900// Look at neighboring blocks and set a min and max partition size based on
2901// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002902static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002903 MACROBLOCKD *const xd, int mi_row,
2904 int mi_col, BLOCK_SIZE *min_block_size,
2905 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002906 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002907 MODE_INFO **mi = xd->mi;
2908 const int left_in_image = xd->left_available && mi[-1];
2909 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
2910 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2911 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2912 int bh, bw;
2913 BLOCK_SIZE min_size = BLOCK_4X4;
2914 BLOCK_SIZE max_size = BLOCK_LARGEST;
2915
2916 // Trap case where we do not have a prediction.
2917 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2918 // Default "min to max" and "max to min"
2919 min_size = BLOCK_LARGEST;
2920 max_size = BLOCK_4X4;
2921
2922 // NOTE: each call to get_sb_partition_size_range() uses the previous
2923 // passed in values for min and max as a starting point.
2924 // Find the min and max partition used in previous frame at this location
2925 if (cm->frame_type != KEY_FRAME) {
2926 MODE_INFO **prev_mi =
2927 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
2928 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
2929 }
2930 // Find the min and max partition sizes used in the left superblock
2931 if (left_in_image) {
2932 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
2933 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
2934 }
2935 // Find the min and max partition sizes used in the above suprblock.
2936 if (above_in_image) {
2937 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
2938 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
2939 }
2940
2941 // Adjust observed min and max for "relaxed" auto partition case.
2942 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2943 min_size = min_partition_size[min_size];
2944 max_size = max_partition_size[max_size];
2945 }
2946 }
2947
2948 // Check border cases where max and min from neighbors may not be legal.
2949 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
2950 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07002951 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952
2953 // Test for blocks at the edge of the active image.
2954 // This may be the actual edge of the image or where there are formatting
2955 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07002956 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002957 min_size = BLOCK_4X4;
2958 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002959 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002960 }
2961
2962 // When use_square_partition_only is true, make sure at least one square
2963 // partition is allowed by selecting the next smaller square size as
2964 // *min_block_size.
2965 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002966 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002967 }
2968
Yaowu Xuf883b422016-08-30 14:01:10 -07002969 *min_block_size = AOMMIN(min_size, cm->sb_size);
2970 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002971}
2972
2973// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07002974static void set_partition_range(const AV1_COMMON *const cm,
2975 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07002977 BLOCK_SIZE *const min_bs,
2978 BLOCK_SIZE *const max_bs) {
2979 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2980 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002981 int idx, idy;
2982
Yaowu Xuc27fc142016-08-22 16:08:15 -07002983 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07002984 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
2985 BLOCK_SIZE min_size = BLOCK_64X64; // default values
2986 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002987
2988 if (prev_mi) {
2989 for (idy = 0; idy < mi_height; ++idy) {
2990 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07002991 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
2992 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07002993 min_size = AOMMIN(min_size, bs);
2994 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002995 }
2996 }
2997 }
2998
2999 if (xd->left_available) {
3000 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003001 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3002 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003003 min_size = AOMMIN(min_size, bs);
3004 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003005 }
3006 }
3007
3008 if (xd->up_available) {
3009 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003010 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3011 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003012 min_size = AOMMIN(min_size, bs);
3013 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003014 }
3015 }
3016
3017 if (min_size == max_size) {
3018 min_size = min_partition_size[min_size];
3019 max_size = max_partition_size[max_size];
3020 }
3021
Yaowu Xuf883b422016-08-30 14:01:10 -07003022 *min_bs = AOMMIN(min_size, cm->sb_size);
3023 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003024}
3025
3026static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3027 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3028}
3029
3030static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3031 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3032}
3033
3034#if CONFIG_FP_MB_STATS
3035const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3036 0,
3037 10,
3038 10,
3039 30,
3040 40,
3041 40,
3042 60,
3043 80,
3044 80,
3045 90,
3046 100,
3047 100,
3048 120,
3049#if CONFIG_EXT_PARTITION
3050 // TODO(debargha): What are the correct numbers here?
3051 130,
3052 130,
3053 150
3054#endif // CONFIG_EXT_PARTITION
3055};
3056const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3057 0,
3058 3,
3059 3,
3060 7,
3061 15,
3062 15,
3063 30,
3064 40,
3065 40,
3066 60,
3067 80,
3068 80,
3069 120,
3070#if CONFIG_EXT_PARTITION
3071 // TODO(debargha): What are the correct numbers here?
3072 160,
3073 160,
3074 240
3075#endif // CONFIG_EXT_PARTITION
3076};
3077const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3078 1,
3079 1,
3080 1,
3081 1,
3082 1,
3083 1,
3084 1,
3085 1,
3086 1,
3087 1,
3088 4,
3089 4,
3090 6
3091#if CONFIG_EXT_PARTITION
3092 // TODO(debargha): What are the correct numbers here?
3093 8,
3094 8,
3095 10
3096#endif // CONFIG_EXT_PARTITION
3097};
3098
3099typedef enum {
3100 MV_ZERO = 0,
3101 MV_LEFT = 1,
3102 MV_UP = 2,
3103 MV_RIGHT = 3,
3104 MV_DOWN = 4,
3105 MV_INVALID
3106} MOTION_DIRECTION;
3107
3108static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3109 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3110 return MV_ZERO;
3111 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3112 return MV_LEFT;
3113 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3114 return MV_RIGHT;
3115 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3116 return MV_UP;
3117 } else {
3118 return MV_DOWN;
3119 }
3120}
3121
3122static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3123 MOTION_DIRECTION that_mv) {
3124 if (this_mv == that_mv) {
3125 return 0;
3126 } else {
3127 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3128 }
3129}
3130#endif
3131
3132#if CONFIG_EXT_PARTITION_TYPES
3133static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003134 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3135 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3136 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3137 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003138#if CONFIG_SUPERTX
3139 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3140#endif
3141 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3142 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3143 MACROBLOCK *const x = &td->mb;
3144 MACROBLOCKD *const xd = &x->e_mbd;
3145 RD_COST this_rdc, sum_rdc;
3146#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003147 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 TileInfo *const tile_info = &tile_data->tile_info;
3149 int this_rate_nocoef, sum_rate_nocoef;
3150 int abort_flag;
3151 const int supertx_allowed = !frame_is_intra_only(cm) &&
3152 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3153 !xd->lossless[0];
3154#endif
3155 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3156
3157 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3158#if CONFIG_SUPERTX
3159 &sum_rate_nocoef,
3160#endif
3161#if CONFIG_EXT_PARTITION_TYPES
3162 partition,
3163#endif
3164 subsize0, &ctxs[0], best_rdc->rdcost);
3165#if CONFIG_SUPERTX
3166 abort_flag = sum_rdc.rdcost >= best_rd;
3167#endif
3168
3169#if CONFIG_SUPERTX
3170 if (sum_rdc.rdcost < INT64_MAX) {
3171#else
3172 if (sum_rdc.rdcost < best_rdc->rdcost) {
3173#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003174 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3175 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003176 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003177 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003178
Urvang Joshi368fbc92016-10-17 16:31:34 -07003179 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180
3181#if CONFIG_SUPERTX
3182 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3183 &this_rate_nocoef,
3184#if CONFIG_EXT_PARTITION_TYPES
3185 partition,
3186#endif
3187 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3188#else
3189 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3190#if CONFIG_EXT_PARTITION_TYPES
3191 partition,
3192#endif
3193 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3194#endif // CONFIG_SUPERTX
3195
3196 if (this_rdc.rate == INT_MAX) {
3197 sum_rdc.rdcost = INT64_MAX;
3198#if CONFIG_SUPERTX
3199 sum_rate_nocoef = INT_MAX;
3200#endif
3201 } else {
3202 sum_rdc.rate += this_rdc.rate;
3203 sum_rdc.dist += this_rdc.dist;
3204 sum_rdc.rdcost += this_rdc.rdcost;
3205#if CONFIG_SUPERTX
3206 sum_rate_nocoef += this_rate_nocoef;
3207#endif
3208 }
3209
3210#if CONFIG_SUPERTX
3211 if (sum_rdc.rdcost < INT64_MAX) {
3212#else
3213 if (sum_rdc.rdcost < best_rdc->rdcost) {
3214#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003215 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3216 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003217 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003218 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003219
Urvang Joshi368fbc92016-10-17 16:31:34 -07003220 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221
3222#if CONFIG_SUPERTX
3223 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3224 &this_rate_nocoef,
3225#if CONFIG_EXT_PARTITION_TYPES
3226 partition,
3227#endif
3228 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3229#else
3230 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3231#if CONFIG_EXT_PARTITION_TYPES
3232 partition,
3233#endif
3234 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3235#endif // CONFIG_SUPERTX
3236
3237 if (this_rdc.rate == INT_MAX) {
3238 sum_rdc.rdcost = INT64_MAX;
3239#if CONFIG_SUPERTX
3240 sum_rate_nocoef = INT_MAX;
3241#endif
3242 } else {
3243 sum_rdc.rate += this_rdc.rate;
3244 sum_rdc.dist += this_rdc.dist;
3245 sum_rdc.rdcost += this_rdc.rdcost;
3246#if CONFIG_SUPERTX
3247 sum_rate_nocoef += this_rate_nocoef;
3248#endif
3249 }
3250
3251#if CONFIG_SUPERTX
3252 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3253 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3254 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3255 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003256 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003257 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3258 [supertx_size],
3259 0);
3260 sum_rdc.rdcost =
3261 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3262
3263 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3264 TX_TYPE best_tx = DCT_DCT;
3265 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3266
3267 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3268
3269 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3270 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3271
Yaowu Xuf883b422016-08-30 14:01:10 -07003272 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003273 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3274 [supertx_size],
3275 1);
3276 tmp_rdc.rdcost =
3277 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3278 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3279 sum_rdc = tmp_rdc;
3280 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3281 supertx_size, pc_tree);
3282 }
3283 }
3284
3285 pc_tree->partitioning = best_partition;
3286 }
3287#endif // CONFIG_SUPERTX
3288
3289 if (sum_rdc.rdcost < best_rdc->rdcost) {
3290 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3291 sum_rdc.rate += cpi->partition_cost[pl][partition];
3292 sum_rdc.rdcost =
3293 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3294#if CONFIG_SUPERTX
3295 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3296#endif
3297 if (sum_rdc.rdcost < best_rdc->rdcost) {
3298#if CONFIG_SUPERTX
3299 *best_rate_nocoef = sum_rate_nocoef;
3300 assert(*best_rate_nocoef >= 0);
3301#endif
3302 *best_rdc = sum_rdc;
3303 pc_tree->partitioning = partition;
3304 }
3305 }
3306 }
3307 }
3308}
3309#endif // CONFIG_EXT_PARTITION_TYPES
3310
3311// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3312// unlikely to be selected depending on previous rate-distortion optimization
3313// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003314static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003315 TileDataEnc *tile_data, TOKENEXTRA **tp,
3316 int mi_row, int mi_col, BLOCK_SIZE bsize,
3317 RD_COST *rd_cost,
3318#if CONFIG_SUPERTX
3319 int *rate_nocoef,
3320#endif
3321 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003322 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003323 TileInfo *const tile_info = &tile_data->tile_info;
3324 MACROBLOCK *const x = &td->mb;
3325 MACROBLOCKD *const xd = &x->e_mbd;
3326 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
3327 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003328 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003329 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003330 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
Urvang Joshi52648442016-10-13 17:27:51 -07003331 const int *partition_cost = cpi->partition_cost[pl];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003332 int tmp_partition_cost[PARTITION_TYPES];
3333 BLOCK_SIZE subsize;
3334 RD_COST this_rdc, sum_rdc, best_rdc;
3335#if CONFIG_SUPERTX
3336 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3337 int abort_flag;
3338 const int supertx_allowed = !frame_is_intra_only(cm) &&
3339 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3340 !xd->lossless[0];
3341#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003342 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3343 int do_square_split = bsize_at_least_8x8;
3344 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003345#if CONFIG_EXT_PARTITION_TYPES
3346 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3347#endif
3348
3349 // Override skipping rectangular partition operations for edge blocks
3350 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3351 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3352 const int xss = x->e_mbd.plane[1].subsampling_x;
3353 const int yss = x->e_mbd.plane[1].subsampling_y;
3354
3355 BLOCK_SIZE min_size = x->min_partition_size;
3356 BLOCK_SIZE max_size = x->max_partition_size;
3357
3358#if CONFIG_FP_MB_STATS
3359 unsigned int src_diff_var = UINT_MAX;
3360 int none_complexity = 0;
3361#endif
3362
3363 int partition_none_allowed = !force_horz_split && !force_vert_split;
3364 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003365 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003366 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003367 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003368 (void)*tp_orig;
3369
3370 if (force_horz_split || force_vert_split) {
3371 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3372
3373 if (!force_vert_split) { // force_horz_split only
3374 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3375 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003376 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003377 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003378 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003379 } else if (!force_horz_split) { // force_vert_split only
3380 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3381 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003382 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003383 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003384 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003385 } else { // force_ horz_split && force_vert_split horz_split
3386 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3387 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3388 tmp_partition_cost[PARTITION_SPLIT] = 0;
3389 }
3390
3391 partition_cost = tmp_partition_cost;
3392 }
3393
3394#if CONFIG_VAR_TX
3395#ifndef NDEBUG
3396 // Nothing should rely on the default value of this array (which is just
3397 // leftover from encoding the previous block. Setting it to magic number
3398 // when debugging.
3399 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3400#endif // NDEBUG
3401#endif // CONFIG_VAR_TX
3402
3403 assert(num_8x8_blocks_wide_lookup[bsize] ==
3404 num_8x8_blocks_high_lookup[bsize]);
3405
Yaowu Xuf883b422016-08-30 14:01:10 -07003406 av1_rd_cost_init(&this_rdc);
3407 av1_rd_cost_init(&sum_rdc);
3408 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003409 best_rdc.rdcost = best_rd;
3410
3411 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3412
3413 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003414 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003415
3416 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003417 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003418 ((pc_tree->index == 0 || pc_tree->index == 3) +
3419 get_chessboard_index(cm->current_video_frame)) &
3420 0x1;
3421
3422 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3423 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3424 }
3425
3426 // Determine partition types in search according to the speed features.
3427 // The threshold set here has to be of square block size.
3428 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003429 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3430 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3431 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3432 partition_none_allowed &= no_partition_allowed;
3433 partition_horz_allowed &= partition_allowed || force_horz_split;
3434 partition_vert_allowed &= partition_allowed || force_vert_split;
3435 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003436 }
3437 if (cpi->sf.use_square_partition_only) {
3438 partition_horz_allowed &= force_horz_split;
3439 partition_vert_allowed &= force_vert_split;
3440 }
3441
3442#if CONFIG_VAR_TX
3443 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3444 xd->left_txfm_context =
3445 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3446#endif
3447
3448 save_context(x, &x_ctx, mi_row, mi_col, bsize);
3449
3450#if CONFIG_FP_MB_STATS
3451 if (cpi->use_fp_mb_stats) {
3452 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3453 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3454 mi_col, bsize);
3455 }
3456#endif
3457
3458#if CONFIG_FP_MB_STATS
3459 // Decide whether we shall split directly and skip searching NONE by using
3460 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003461 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003462 partition_none_allowed && src_diff_var > 4 &&
3463 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3464 int mb_row = mi_row >> 1;
3465 int mb_col = mi_col >> 1;
3466 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003467 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003469 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003470 int r, c;
3471
3472 // compute a complexity measure, basically measure inconsistency of motion
3473 // vectors obtained from the first pass in the current block
3474 for (r = mb_row; r < mb_row_end; r++) {
3475 for (c = mb_col; c < mb_col_end; c++) {
3476 const int mb_index = r * cm->mb_cols + c;
3477
3478 MOTION_DIRECTION this_mv;
3479 MOTION_DIRECTION right_mv;
3480 MOTION_DIRECTION bottom_mv;
3481
3482 this_mv =
3483 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3484
3485 // to its right
3486 if (c != mb_col_end - 1) {
3487 right_mv = get_motion_direction_fp(
3488 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3489 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3490 }
3491
3492 // to its bottom
3493 if (r != mb_row_end - 1) {
3494 bottom_mv = get_motion_direction_fp(
3495 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3496 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3497 }
3498
3499 // do not count its left and top neighbors to avoid double counting
3500 }
3501 }
3502
3503 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3504 partition_none_allowed = 0;
3505 }
3506 }
3507#endif
3508
3509 // PARTITION_NONE
3510 if (partition_none_allowed) {
3511 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3512#if CONFIG_SUPERTX
3513 &this_rate_nocoef,
3514#endif
3515#if CONFIG_EXT_PARTITION_TYPES
3516 PARTITION_NONE,
3517#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003518 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003519 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003520 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003521 this_rdc.rate += partition_cost[PARTITION_NONE];
3522 this_rdc.rdcost =
3523 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3524#if CONFIG_SUPERTX
3525 this_rate_nocoef += partition_cost[PARTITION_NONE];
3526#endif
3527 }
3528
3529 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003530 // Adjust dist breakout threshold according to the partition size.
3531 const int64_t dist_breakout_thr =
3532 cpi->sf.partition_search_breakout_dist_thr >>
3533 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3534 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3535 const int rate_breakout_thr =
3536 cpi->sf.partition_search_breakout_rate_thr *
3537 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003538
3539 best_rdc = this_rdc;
3540#if CONFIG_SUPERTX
3541 best_rate_nocoef = this_rate_nocoef;
3542 assert(best_rate_nocoef >= 0);
3543#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003544 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545
3546 // If all y, u, v transform blocks in this partition are skippable, and
3547 // the dist & rate are within the thresholds, the partition search is
3548 // terminated for current branch of the partition search tree.
3549 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3550 // early termination at that speed.
3551 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003552 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003553 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003554 do_square_split = 0;
3555 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003556 }
3557
3558#if CONFIG_FP_MB_STATS
3559 // Check if every 16x16 first pass block statistics has zero
3560 // motion and the corresponding first pass residue is small enough.
3561 // If that is the case, check the difference variance between the
3562 // current frame and the last frame. If the variance is small enough,
3563 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003564 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3566 int mb_row = mi_row >> 1;
3567 int mb_col = mi_col >> 1;
3568 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003569 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003571 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003572 int r, c;
3573
3574 int skip = 1;
3575 for (r = mb_row; r < mb_row_end; r++) {
3576 for (c = mb_col; c < mb_col_end; c++) {
3577 const int mb_index = r * cm->mb_cols + c;
3578 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3579 FPMB_MOTION_ZERO_MASK) ||
3580 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3581 FPMB_ERROR_SMALL_MASK)) {
3582 skip = 0;
3583 break;
3584 }
3585 }
3586 if (skip == 0) {
3587 break;
3588 }
3589 }
3590 if (skip) {
3591 if (src_diff_var == UINT_MAX) {
3592 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3593 src_diff_var = get_sby_perpixel_diff_variance(
3594 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3595 }
3596 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003597 do_square_split = 0;
3598 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003599 }
3600 }
3601 }
3602#endif
3603 }
3604 }
3605
3606 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3607 }
3608
3609 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003610 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003611
3612 // PARTITION_SPLIT
3613 // TODO(jingning): use the motion vectors given by the above search as
3614 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003615 if (do_square_split) {
3616 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003617 subsize = get_subsize(bsize, PARTITION_SPLIT);
3618 if (bsize == BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003619#if CONFIG_DUAL_FILTER
3620 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3621 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003622 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003623#else
3624 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3625 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003626 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003627#endif
3628#if CONFIG_SUPERTX
3629 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3630 &sum_rate_nocoef,
3631#if CONFIG_EXT_PARTITION_TYPES
3632 PARTITION_SPLIT,
3633#endif
3634 subsize, pc_tree->leaf_split[0], INT64_MAX);
3635#else
3636 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3637#if CONFIG_EXT_PARTITION_TYPES
3638 PARTITION_SPLIT,
3639#endif
3640 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3641#endif // CONFIG_SUPERTX
3642 if (sum_rdc.rate == INT_MAX) {
3643 sum_rdc.rdcost = INT64_MAX;
3644#if CONFIG_SUPERTX
3645 sum_rate_nocoef = INT_MAX;
3646#endif
3647 }
3648#if CONFIG_SUPERTX
3649 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3650 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3651 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3652
3653 pc_tree->partitioning = PARTITION_SPLIT;
3654
clang-format67948d32016-09-07 22:40:40 -07003655 sum_rdc.rate +=
3656 av1_cost_bit(cm->fc->supertx_prob
3657 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3658 [supertx_size],
3659 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003660 sum_rdc.rdcost =
3661 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3662
3663 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3664 TX_TYPE best_tx = DCT_DCT;
3665 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3666
3667 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3668
3669 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3670 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3671
Yaowu Xuf883b422016-08-30 14:01:10 -07003672 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003673 cm->fc->supertx_prob
3674 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3675 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003676 1);
3677 tmp_rdc.rdcost =
3678 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3679 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3680 sum_rdc = tmp_rdc;
3681 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3682 supertx_size, pc_tree);
3683 }
3684 }
3685
3686 pc_tree->partitioning = best_partition;
3687 }
3688#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003689 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003690 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07003691 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003692#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003693 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003694#else
Urvang Joshi52648442016-10-13 17:27:51 -07003695 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003696#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003697 const int x_idx = (idx & 1) * mi_step;
3698 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699
3700 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3701 continue;
3702
Urvang Joshi454280d2016-10-14 16:51:44 -07003703 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003704
Urvang Joshi52648442016-10-13 17:27:51 -07003705 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003706#if CONFIG_SUPERTX
3707 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3708 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07003709 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003710#else
Urvang Joshi52648442016-10-13 17:27:51 -07003711 rd_pick_partition(
3712 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
3713 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003714#endif // CONFIG_SUPERTX
3715
3716 if (this_rdc.rate == INT_MAX) {
3717 sum_rdc.rdcost = INT64_MAX;
3718#if CONFIG_SUPERTX
3719 sum_rate_nocoef = INT_MAX;
3720#endif // CONFIG_SUPERTX
3721 break;
3722 } else {
3723 sum_rdc.rate += this_rdc.rate;
3724 sum_rdc.dist += this_rdc.dist;
3725 sum_rdc.rdcost += this_rdc.rdcost;
3726#if CONFIG_SUPERTX
3727 sum_rate_nocoef += this_rate_nocoef;
3728#endif // CONFIG_SUPERTX
3729 }
3730 }
Urvang Joshi52648442016-10-13 17:27:51 -07003731 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003733 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3735 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3736
3737 pc_tree->partitioning = PARTITION_SPLIT;
3738
clang-format67948d32016-09-07 22:40:40 -07003739 sum_rdc.rate +=
3740 av1_cost_bit(cm->fc->supertx_prob
3741 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3742 [supertx_size],
3743 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003744 sum_rdc.rdcost =
3745 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3746
3747 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3748 TX_TYPE best_tx = DCT_DCT;
3749 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3750
3751 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3752
3753 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3754 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3755
Yaowu Xuf883b422016-08-30 14:01:10 -07003756 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003757 cm->fc->supertx_prob
3758 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3759 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003760 1);
3761 tmp_rdc.rdcost =
3762 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3763 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3764 sum_rdc = tmp_rdc;
3765 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3766 supertx_size, pc_tree);
3767 }
3768 }
3769
3770 pc_tree->partitioning = best_partition;
3771 }
3772#endif // CONFIG_SUPERTX
3773 }
3774
Urvang Joshi52648442016-10-13 17:27:51 -07003775 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003776 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3777 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3778#if CONFIG_SUPERTX
3779 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3780#endif // CONFIG_SUPERTX
3781
3782 if (sum_rdc.rdcost < best_rdc.rdcost) {
3783 best_rdc = sum_rdc;
3784#if CONFIG_SUPERTX
3785 best_rate_nocoef = sum_rate_nocoef;
3786 assert(best_rate_nocoef >= 0);
3787#endif // CONFIG_SUPERTX
3788 pc_tree->partitioning = PARTITION_SPLIT;
3789 }
Urvang Joshi52648442016-10-13 17:27:51 -07003790 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003791 // skip rectangular partition test when larger block size
3792 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07003793 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003794 }
3795
3796 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3797 } // if (do_split)
3798
3799 // PARTITION_HORZ
3800 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003801 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003802 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07003803 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003804#if CONFIG_DUAL_FILTER
3805 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3806 partition_none_allowed)
3807 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003808 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003809#else
3810 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3811 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003812 pc_tree->horizontal[0].pred_interp_filter =
3813 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003814#endif
3815 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3816#if CONFIG_SUPERTX
3817 &sum_rate_nocoef,
3818#endif // CONFIG_SUPERTX
3819#if CONFIG_EXT_PARTITION_TYPES
3820 PARTITION_HORZ,
3821#endif
3822 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3823
3824#if CONFIG_SUPERTX
3825 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3826 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3827 if (sum_rdc.rdcost < INT64_MAX &&
3828#else
3829 if (sum_rdc.rdcost < best_rdc.rdcost &&
3830#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003831 !force_horz_split && bsize > BLOCK_8X8) {
Urvang Joshi454280d2016-10-14 16:51:44 -07003832 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
3833 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003834 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07003835 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003836
Urvang Joshi454280d2016-10-14 16:51:44 -07003837 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003838
3839#if CONFIG_DUAL_FILTER
3840 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3841 partition_none_allowed)
3842 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003843 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003844#else
3845 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3846 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003847 pc_tree->horizontal[1].pred_interp_filter =
3848 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003849#endif
3850#if CONFIG_SUPERTX
3851 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3852 &this_rate_nocoef,
3853#if CONFIG_EXT_PARTITION_TYPES
3854 PARTITION_HORZ,
3855#endif
3856 subsize, &pc_tree->horizontal[1], INT64_MAX);
3857#else
3858 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3859#if CONFIG_EXT_PARTITION_TYPES
3860 PARTITION_HORZ,
3861#endif
3862 subsize, &pc_tree->horizontal[1],
3863 best_rdc.rdcost - sum_rdc.rdcost);
3864#endif // CONFIG_SUPERTX
3865 if (this_rdc.rate == INT_MAX) {
3866 sum_rdc.rdcost = INT64_MAX;
3867#if CONFIG_SUPERTX
3868 sum_rate_nocoef = INT_MAX;
3869#endif // CONFIG_SUPERTX
3870 } else {
3871 sum_rdc.rate += this_rdc.rate;
3872 sum_rdc.dist += this_rdc.dist;
3873 sum_rdc.rdcost += this_rdc.rdcost;
3874#if CONFIG_SUPERTX
3875 sum_rate_nocoef += this_rate_nocoef;
3876#endif // CONFIG_SUPERTX
3877 }
3878 }
3879
3880#if CONFIG_SUPERTX
3881 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3882 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3883 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3884
3885 pc_tree->partitioning = PARTITION_HORZ;
3886
Yaowu Xuf883b422016-08-30 14:01:10 -07003887 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003888 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3889 [supertx_size],
3890 0);
3891 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3892
3893 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3894 TX_TYPE best_tx = DCT_DCT;
3895 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3896
3897 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3898
3899 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
3900 &tmp_rdc.dist, &best_tx, pc_tree);
3901
Yaowu Xuf883b422016-08-30 14:01:10 -07003902 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903 cm->fc
3904 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3905 [supertx_size],
3906 1);
3907 tmp_rdc.rdcost =
3908 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3909 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3910 sum_rdc = tmp_rdc;
3911 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3912 supertx_size, pc_tree);
3913 }
3914 }
3915
3916 pc_tree->partitioning = best_partition;
3917 }
3918#endif // CONFIG_SUPERTX
3919
3920 if (sum_rdc.rdcost < best_rdc.rdcost) {
3921 sum_rdc.rate += partition_cost[PARTITION_HORZ];
3922 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3923#if CONFIG_SUPERTX
3924 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
3925#endif // CONFIG_SUPERTX
3926 if (sum_rdc.rdcost < best_rdc.rdcost) {
3927 best_rdc = sum_rdc;
3928#if CONFIG_SUPERTX
3929 best_rate_nocoef = sum_rate_nocoef;
3930 assert(best_rate_nocoef >= 0);
3931#endif // CONFIG_SUPERTX
3932 pc_tree->partitioning = PARTITION_HORZ;
3933 }
3934 }
3935
3936 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3937 }
3938
3939 // PARTITION_VERT
3940 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003941 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 subsize = get_subsize(bsize, PARTITION_VERT);
3943
Urvang Joshi454280d2016-10-14 16:51:44 -07003944 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003945
3946#if CONFIG_DUAL_FILTER
3947 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3948 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003949 pc_tree->vertical[0].pred_interp_filter =
3950 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951#else
3952 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3953 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003954 pc_tree->vertical[0].pred_interp_filter =
3955 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003956#endif
3957 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3958#if CONFIG_SUPERTX
3959 &sum_rate_nocoef,
3960#endif // CONFIG_SUPERTX
3961#if CONFIG_EXT_PARTITION_TYPES
3962 PARTITION_VERT,
3963#endif
3964 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
3965#if CONFIG_SUPERTX
3966 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3967 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3968 if (sum_rdc.rdcost < INT64_MAX &&
3969#else
3970 if (sum_rdc.rdcost < best_rdc.rdcost &&
3971#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003972 !force_vert_split && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003973 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
3974 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
3975 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003976
Urvang Joshi454280d2016-10-14 16:51:44 -07003977 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978
3979#if CONFIG_DUAL_FILTER
3980 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3981 partition_none_allowed)
3982 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003983 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003984#else
3985 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3986 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003987 pc_tree->vertical[1].pred_interp_filter =
3988 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003989#endif
3990#if CONFIG_SUPERTX
3991 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
3992 &this_rate_nocoef,
3993#if CONFIG_EXT_PARTITION_TYPES
3994 PARTITION_VERT,
3995#endif
3996 subsize, &pc_tree->vertical[1],
3997 INT64_MAX - sum_rdc.rdcost);
3998#else
3999 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4000#if CONFIG_EXT_PARTITION_TYPES
4001 PARTITION_VERT,
4002#endif
4003 subsize, &pc_tree->vertical[1],
4004 best_rdc.rdcost - sum_rdc.rdcost);
4005#endif // CONFIG_SUPERTX
4006 if (this_rdc.rate == INT_MAX) {
4007 sum_rdc.rdcost = INT64_MAX;
4008#if CONFIG_SUPERTX
4009 sum_rate_nocoef = INT_MAX;
4010#endif // CONFIG_SUPERTX
4011 } else {
4012 sum_rdc.rate += this_rdc.rate;
4013 sum_rdc.dist += this_rdc.dist;
4014 sum_rdc.rdcost += this_rdc.rdcost;
4015#if CONFIG_SUPERTX
4016 sum_rate_nocoef += this_rate_nocoef;
4017#endif // CONFIG_SUPERTX
4018 }
4019 }
4020#if CONFIG_SUPERTX
4021 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4022 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4023 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4024
4025 pc_tree->partitioning = PARTITION_VERT;
4026
Yaowu Xuf883b422016-08-30 14:01:10 -07004027 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004028 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4029 [supertx_size],
4030 0);
4031 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4032
4033 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4034 TX_TYPE best_tx = DCT_DCT;
4035 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4036
4037 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4038
4039 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4040 &tmp_rdc.dist, &best_tx, pc_tree);
4041
Yaowu Xuf883b422016-08-30 14:01:10 -07004042 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004043 cm->fc
4044 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4045 [supertx_size],
4046 1);
4047 tmp_rdc.rdcost =
4048 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4049 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4050 sum_rdc = tmp_rdc;
4051 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4052 supertx_size, pc_tree);
4053 }
4054 }
4055
4056 pc_tree->partitioning = best_partition;
4057 }
4058#endif // CONFIG_SUPERTX
4059
4060 if (sum_rdc.rdcost < best_rdc.rdcost) {
4061 sum_rdc.rate += partition_cost[PARTITION_VERT];
4062 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4063#if CONFIG_SUPERTX
4064 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4065#endif // CONFIG_SUPERTX
4066 if (sum_rdc.rdcost < best_rdc.rdcost) {
4067 best_rdc = sum_rdc;
4068#if CONFIG_SUPERTX
4069 best_rate_nocoef = sum_rate_nocoef;
4070 assert(best_rate_nocoef >= 0);
4071#endif // CONFIG_SUPERTX
4072 pc_tree->partitioning = PARTITION_VERT;
4073 }
4074 }
4075 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4076 }
4077
4078#if CONFIG_EXT_PARTITION_TYPES
4079 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004080 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004081 partition_none_allowed) {
4082 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4083 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004084 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004085 PARTITION_HORZ_A,
4086#if CONFIG_SUPERTX
4087 best_rd, &best_rate_nocoef, &x_ctx,
4088#endif
4089 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4090 mi_row + mi_step, mi_col, subsize);
4091 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4092 }
4093 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004094 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004095 partition_none_allowed) {
4096 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4097 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004098 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004099 PARTITION_HORZ_B,
4100#if CONFIG_SUPERTX
4101 best_rd, &best_rate_nocoef, &x_ctx,
4102#endif
4103 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4104 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4105 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4106 }
4107 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004108 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004109 partition_none_allowed) {
4110 subsize = get_subsize(bsize, PARTITION_VERT_A);
4111 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004112 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004113 PARTITION_VERT_A,
4114#if CONFIG_SUPERTX
4115 best_rd, &best_rate_nocoef, &x_ctx,
4116#endif
4117 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4118 mi_row, mi_col + mi_step, subsize);
4119 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4120 }
4121 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004122 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004123 partition_none_allowed) {
4124 subsize = get_subsize(bsize, PARTITION_VERT_B);
4125 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004126 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004127 PARTITION_VERT_B,
4128#if CONFIG_SUPERTX
4129 best_rd, &best_rate_nocoef, &x_ctx,
4130#endif
4131 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4132 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4133 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4134 }
4135#endif // CONFIG_EXT_PARTITION_TYPES
4136
4137 // TODO(jbb): This code added so that we avoid static analysis
4138 // warning related to the fact that best_rd isn't used after this
4139 // point. This code should be refactored so that the duplicate
4140 // checks occur in some sub function and thus are used...
4141 (void)best_rd;
4142 *rd_cost = best_rdc;
4143#if CONFIG_SUPERTX
4144 *rate_nocoef = best_rate_nocoef;
4145#endif // CONFIG_SUPERTX
4146
4147 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4148 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004149 if (bsize == cm->sb_size) {
4150 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4151 pc_tree, NULL);
4152 } else {
4153 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4154 pc_tree, NULL);
4155 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004156 }
4157
4158 if (bsize == cm->sb_size) {
4159 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
4160 assert(best_rdc.rate < INT_MAX);
4161 assert(best_rdc.dist < INT64_MAX);
4162 } else {
4163 assert(tp_orig == *tp);
4164 }
4165}
4166
Yaowu Xuf883b422016-08-30 14:01:10 -07004167static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004168 TileDataEnc *tile_data, int mi_row,
4169 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004170 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004171 const TileInfo *const tile_info = &tile_data->tile_info;
4172 MACROBLOCK *const x = &td->mb;
4173 MACROBLOCKD *const xd = &x->e_mbd;
4174 SPEED_FEATURES *const sf = &cpi->sf;
4175 int mi_col;
4176#if CONFIG_EXT_PARTITION
4177 const int leaf_nodes = 256;
4178#else
4179 const int leaf_nodes = 64;
4180#endif // CONFIG_EXT_PARTITION
4181
4182 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004183 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004184
Thomas Daviesf6936102016-09-05 16:51:31 +01004185#if CONFIG_DELTA_Q
4186 // Reset delta for every tile
4187 if (cm->delta_q_present_flag)
4188 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4189#endif
4190
Yaowu Xuc27fc142016-08-22 16:08:15 -07004191 // Code each SB in the row
4192 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4193 mi_col += cm->mib_size) {
4194 const struct segmentation *const seg = &cm->seg;
4195 int dummy_rate;
4196 int64_t dummy_dist;
4197 RD_COST dummy_rdc;
4198#if CONFIG_SUPERTX
4199 int dummy_rate_nocoef;
4200#endif // CONFIG_SUPERTX
4201 int i;
4202 int seg_skip = 0;
4203
4204 const int idx_str = cm->mi_stride * mi_row + mi_col;
4205 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4206 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4207
4208 if (sf->adaptive_pred_interp_filter) {
4209 for (i = 0; i < leaf_nodes; ++i)
4210 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4211
4212 for (i = 0; i < leaf_nodes; ++i) {
4213 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4214 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4215 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4216 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4217 }
4218 }
4219
Yaowu Xuf883b422016-08-30 14:01:10 -07004220 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004221 pc_root->index = 0;
4222
4223 if (seg->enabled) {
4224 const uint8_t *const map =
4225 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4226 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4227 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4228 }
4229
Arild Fuldseth07441162016-08-15 15:07:52 +02004230#if CONFIG_DELTA_Q
4231 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004232 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004233 int sb_row = mi_row >> 3;
4234 int sb_col = mi_col >> 3;
4235 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4236 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004237
4238 // Ensure divisibility of delta_qindex by delta_q_res
4239 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4240 int qmask = ~(cm->delta_q_res - 1);
4241 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4242 cm->delta_q_res, 256 - cm->delta_q_res);
4243 current_qindex =
4244 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4245 cm->base_qindex;
4246
Arild Fuldseth07441162016-08-15 15:07:52 +02004247 xd->delta_qindex = current_qindex - cm->base_qindex;
4248 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4249 xd->mi[0]->mbmi.current_q_index = current_qindex;
4250 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004251 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004252 }
4253#endif
4254
Yaowu Xuc27fc142016-08-22 16:08:15 -07004255 x->source_variance = UINT_MAX;
4256 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4257 BLOCK_SIZE bsize;
4258 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4259 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4260 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4261 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4262 &dummy_rate, &dummy_dist,
4263#if CONFIG_SUPERTX
4264 &dummy_rate_nocoef,
4265#endif // CONFIG_SUPERTX
4266 1, pc_root);
4267 } else if (cpi->partition_search_skippable_frame) {
4268 BLOCK_SIZE bsize;
4269 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4270 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4271 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4272 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4273 &dummy_rate, &dummy_dist,
4274#if CONFIG_SUPERTX
4275 &dummy_rate_nocoef,
4276#endif // CONFIG_SUPERTX
4277 1, pc_root);
4278 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4279 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4280 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4281 &dummy_rate, &dummy_dist,
4282#if CONFIG_SUPERTX
4283 &dummy_rate_nocoef,
4284#endif // CONFIG_SUPERTX
4285 1, pc_root);
4286 } else {
4287 // If required set upper and lower partition size limits
4288 if (sf->auto_min_max_partition_size) {
4289 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4290 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4291 &x->min_partition_size, &x->max_partition_size);
4292 }
4293 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4294 &dummy_rdc,
4295#if CONFIG_SUPERTX
4296 &dummy_rate_nocoef,
4297#endif // CONFIG_SUPERTX
4298 INT64_MAX, pc_root);
4299 }
4300 }
4301#if CONFIG_ENTROPY
4302 if (cm->do_subframe_update &&
4303 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4304 if ((mi_row + MI_SIZE) %
4305 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004306 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004307 0 &&
4308 mi_row + MI_SIZE < cm->mi_rows &&
4309 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4310 TX_SIZE t;
4311 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4312
4313 for (t = TX_4X4; t <= TX_32X32; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004314 av1_full_to_model_counts(cpi->td.counts->coef[t],
4315 cpi->td.rd_counts.coef_counts[t]);
4316 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004317 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004318 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4319 cm->fc->coef_probs);
4320 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4321 cpi->td.rd_counts.coef_counts);
4322 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4323 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004324 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004325 }
4326 }
4327#endif // CONFIG_ENTROPY
4328}
4329
Yaowu Xuf883b422016-08-30 14:01:10 -07004330static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004331 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004332 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004333 MACROBLOCKD *const xd = &x->e_mbd;
4334
4335 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004336 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004337
Yaowu Xuf883b422016-08-30 14:01:10 -07004338 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004339}
4340
Yaowu Xuf883b422016-08-30 14:01:10 -07004341static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004342 const int ref_flags = cpi->ref_frame_flags;
4343
4344 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4345 return 0;
4346 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004347 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004349 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4350 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004351#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004352 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004353 }
4354}
4355
4356#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004357static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004358 int mi_row, mi_col;
4359 const int mis = cm->mi_stride;
4360 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4361
4362 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4363 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4364 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4365 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4366 }
4367 }
4368}
4369#endif
4370
Yaowu Xuf883b422016-08-30 14:01:10 -07004371static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004372 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4373#if CONFIG_EXT_REFS
4374 // We will not update the golden frame with an internal overlay frame
4375 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4376 cpi->rc.is_src_frame_ext_arf)
4377#else
4378 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4379#endif
4380 return ALTREF_FRAME;
4381 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4382 return GOLDEN_FRAME;
4383 else
4384 // TODO(zoeliu): To investigate whether a frame_type other than
4385 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4386 return LAST_FRAME;
4387}
4388
Yaowu Xuf883b422016-08-30 14:01:10 -07004389static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004390 if (xd->lossless[0]) return ONLY_4X4;
4391 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
4392 return ALLOW_32X32;
4393 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4394 cpi->sf.tx_size_search_method == USE_TX_8X8)
4395 return TX_MODE_SELECT;
4396 else
4397 return cpi->common.tx_mode;
4398}
4399
Yaowu Xuf883b422016-08-30 14:01:10 -07004400void av1_init_tile_data(AV1_COMP *cpi) {
4401 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004402 const int tile_cols = cm->tile_cols;
4403 const int tile_rows = cm->tile_rows;
4404 int tile_col, tile_row;
4405 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4406 unsigned int tile_tok = 0;
4407
4408 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004409 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4410 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004411 sizeof(*cpi->tile_data)));
4412 cpi->allocated_tiles = tile_cols * tile_rows;
4413
4414 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4415 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4416 TileDataEnc *const tile_data =
4417 &cpi->tile_data[tile_row * tile_cols + tile_col];
4418 int i, j;
4419 for (i = 0; i < BLOCK_SIZES; ++i) {
4420 for (j = 0; j < MAX_MODES; ++j) {
4421 tile_data->thresh_freq_fact[i][j] = 32;
4422 tile_data->mode_map[i][j] = j;
4423 }
4424 }
4425 }
4426 }
4427
4428 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4429 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4430 TileInfo *const tile_info =
4431 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004432 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004433
4434 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4435 pre_tok = cpi->tile_tok[tile_row][tile_col];
4436 tile_tok = allocated_tokens(*tile_info);
4437 }
4438 }
4439}
4440
Yaowu Xuf883b422016-08-30 14:01:10 -07004441void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4442 int tile_col) {
4443 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004444 TileDataEnc *const this_tile =
4445 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4446 const TileInfo *const tile_info = &this_tile->tile_info;
4447 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4448 int mi_row;
4449
Yaowu Xuf883b422016-08-30 14:01:10 -07004450 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004451
4452 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004453 this_tile->m_search_count = 0; // Count of motion search hits.
4454 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4455 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4456 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004457
4458 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4459 mi_row += cm->mib_size) {
4460 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4461 }
4462
4463 cpi->tok_count[tile_row][tile_col] =
4464 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4465 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
4466}
4467
Yaowu Xuf883b422016-08-30 14:01:10 -07004468static void encode_tiles(AV1_COMP *cpi) {
4469 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004470 int tile_col, tile_row;
4471
Yaowu Xuf883b422016-08-30 14:01:10 -07004472 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004473
4474 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4475 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004476 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004477}
4478
4479#if CONFIG_FP_MB_STATS
4480static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004481 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004482 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4483 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4484
4485 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4486
4487 *this_frame_mb_stats = mb_stats_in;
4488
4489 return 1;
4490}
4491#endif
4492
4493#if CONFIG_GLOBAL_MOTION
4494#define MIN_TRANS_THRESH 8
4495#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004496#define GLOBAL_MOTION_MODEL ROTZOOM
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004497
4498// Adds some offset to a global motion parameter and handles
4499// all of the necessary precision shifts, clamping, and
4500// zero-centering.
4501static int16_t add_param_offset(int param_index, int16_t param_value,
4502 int16_t offset) {
Sarah Parkerb3dab492016-10-26 11:45:50 -07004503 const int scale_vals[2] = { GM_ALPHA_PREC_DIFF, GM_TRANS_PREC_DIFF };
4504 const int clamp_vals[2] = { GM_ALPHA_MAX, GM_TRANS_MAX };
4505 const int is_trans_param = param_index < 2;
4506 const int is_one_centered = (!is_trans_param) && (param_index & 1);
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004507
4508 // Make parameter zero-centered and offset the shift that was done to make
4509 // it compatible with the warped model
4510 param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
4511 scale_vals[is_trans_param];
4512 // Add desired offset to the rescaled/zero-centered parameter
4513 param_value += offset;
4514 // Clamp the parameter so it does not overflow the number of bits allotted
4515 // to it in the bitstream
4516 param_value = (int16_t)clamp(param_value, -clamp_vals[is_trans_param],
4517 clamp_vals[is_trans_param]);
Sarah Parkerb3dab492016-10-26 11:45:50 -07004518 // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004519 // with the warped motion library
4520 param_value *= (1 << scale_vals[is_trans_param]);
4521
Sarah Parkerb3dab492016-10-26 11:45:50 -07004522 // Undo the zero-centering step if necessary
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004523 return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
4524}
4525
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004526static void refine_integerized_param(WarpedMotionParams *wm,
4527#if CONFIG_AOM_HIGHBITDEPTH
4528 int use_hbd, int bd,
4529#endif // CONFIG_AOM_HIGHBITDEPTH
4530 uint8_t *ref, int r_width, int r_height,
4531 int r_stride, uint8_t *dst, int d_width,
4532 int d_height, int d_stride,
4533 int n_refinements) {
4534 int i = 0, p;
4535 int n_params = n_trans_model_params[wm->wmtype];
4536 int16_t *param_mat = (int16_t *)wm->wmmat;
4537 double step_error;
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004538 int16_t step;
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004539 int16_t *param;
4540 int16_t curr_param;
4541 int16_t best_param;
4542
4543 double best_error =
4544 av1_warp_erroradv(wm,
4545#if CONFIG_AOM_HIGHBITDEPTH
4546 use_hbd, bd,
4547#endif // CONFIG_AOM_HIGHBITDEPTH
4548 ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
4549 d_height, d_stride, 0, 0, 16, 16);
4550 for (p = 0; p < n_params; ++p) {
4551 param = param_mat + p;
4552 step = 1 << (n_refinements + 1);
4553 curr_param = *param;
4554 best_param = curr_param;
4555 for (i = 0; i < n_refinements; i++) {
4556 // look to the left
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004557 *param = add_param_offset(p, curr_param, -step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004558 step_error =
4559 av1_warp_erroradv(wm,
4560#if CONFIG_AOM_HIGHBITDEPTH
4561 use_hbd, bd,
4562#endif // CONFIG_AOM_HIGHBITDEPTH
4563 ref, r_width, r_height, r_stride, dst, 0, 0,
4564 d_width, d_height, d_stride, 0, 0, 16, 16);
4565 if (step_error < best_error) {
4566 step >>= 1;
4567 best_error = step_error;
4568 best_param = *param;
4569 curr_param = best_param;
4570 continue;
4571 }
4572
4573 // look to the right
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004574 *param = add_param_offset(p, curr_param, step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004575 step_error =
4576 av1_warp_erroradv(wm,
4577#if CONFIG_AOM_HIGHBITDEPTH
4578 use_hbd, bd,
4579#endif // CONFIG_AOM_HIGHBITDEPTH
4580 ref, r_width, r_height, r_stride, dst, 0, 0,
4581 d_width, d_height, d_stride, 0, 0, 16, 16);
4582 if (step_error < best_error) {
4583 step >>= 1;
4584 best_error = step_error;
4585 best_param = *param;
4586 curr_param = best_param;
4587 continue;
4588 }
4589
4590 // no improvement found-> means we're either already at a minimum or
4591 // step is too wide
4592 step >>= 1;
4593 }
4594
4595 *param = best_param;
4596 }
4597}
4598
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004599static void convert_to_params(const double *params, TransformationType type,
Sarah Parkere5299862016-08-16 14:57:37 -07004600 int16_t *model) {
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004601 int i, diag_value;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004602 int alpha_present = 0;
4603 int n_params = n_trans_model_params[type];
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004604 model[0] = (int16_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4605 model[1] = (int16_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
Sarah Parkere5299862016-08-16 14:57:37 -07004606 model[0] = (int16_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
4607 GM_TRANS_DECODE_FACTOR;
4608 model[1] = (int16_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
4609 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004610
4611 for (i = 2; i < n_params; ++i) {
Sarah Parkerea16b682016-10-20 12:00:16 -07004612 diag_value = ((i & 1) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004613 model[i] = (int16_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004614 model[i] =
4615 (int16_t)(clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX) +
4616 diag_value) *
4617 GM_ALPHA_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004618 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004619 }
4620
4621 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004622 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4623 model[0] = 0;
4624 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004625 }
4626 }
4627}
4628
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004629static void convert_model_to_params(const double *params,
4630 TransformationType type,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004631 Global_Motion_Params *model) {
4632 // TODO(sarahparker) implement for homography
Sarah Parkere5299862016-08-16 14:57:37 -07004633 if (type > HOMOGRAPHY)
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004634 convert_to_params(params, type, (int16_t *)model->motion_params.wmmat);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635 model->gmtype = get_gmtype(model);
4636 model->motion_params.wmtype = gm_to_trans_type(model->gmtype);
4637}
4638#endif // CONFIG_GLOBAL_MOTION
4639
Yaowu Xuf883b422016-08-30 14:01:10 -07004640static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004641 ThreadData *const td = &cpi->td;
4642 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004643 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644 MACROBLOCKD *const xd = &x->e_mbd;
4645 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4646 int i;
4647
Yaowu Xuf883b422016-08-30 14:01:10 -07004648 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4649 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Dengca8d24d2016-10-17 14:06:35 +08004650#if CONFIG_SIMP_MV_PRED
4651 cm->setup_mi(cm);
4652#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004653
4654 xd->mi = cm->mi_grid_visible;
4655 xd->mi[0] = cm->mi;
4656
Yaowu Xuf883b422016-08-30 14:01:10 -07004657 av1_zero(*td->counts);
4658 av1_zero(rdc->coef_counts);
4659 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004660
4661#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004662 aom_clear_system_state();
4663 av1_zero(cpi->global_motion_used);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004664 if (cpi->common.frame_type == INTER_FRAME && cpi->Source) {
4665 YV12_BUFFER_CONFIG *ref_buf;
4666 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004667 double erroradvantage = 0;
4668 double params[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004669 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4670 ref_buf = get_ref_frame_buffer(cpi, frame);
4671 if (ref_buf) {
4672 if (compute_global_motion_feature_based(GLOBAL_MOTION_MODEL,
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004673 cpi->Source, ref_buf, params)) {
4674 convert_model_to_params(params, GLOBAL_MOTION_MODEL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004675 &cm->global_motion[frame]);
4676 if (get_gmtype(&cm->global_motion[frame]) > GLOBAL_ZERO) {
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004677 refine_integerized_param(
4678 &cm->global_motion[frame].motion_params,
4679#if CONFIG_AOM_HIGHBITDEPTH
4680 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4681#endif // CONFIG_AOM_HIGHBITDEPTH
4682 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4683 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4684 cpi->Source->y_height, cpi->Source->y_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004685 // compute the advantage of using gm parameters over 0 motion
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004686 erroradvantage = av1_warp_erroradv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687 &cm->global_motion[frame].motion_params,
Yaowu Xuf883b422016-08-30 14:01:10 -07004688#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004689 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Yaowu Xuf883b422016-08-30 14:01:10 -07004690#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004691 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4692 ref_buf->y_stride, cpi->Source->y_buffer, 0, 0,
4693 cpi->Source->y_width, cpi->Source->y_height,
4694 cpi->Source->y_stride, 0, 0, 16, 16);
4695 if (erroradvantage > GLOBAL_MOTION_ADVANTAGE_THRESH)
4696 // Not enough advantage in using a global model. Make 0.
4697 memset(&cm->global_motion[frame], 0,
4698 sizeof(cm->global_motion[frame]));
4699 }
4700 }
4701 }
4702 }
4703 }
4704#endif // CONFIG_GLOBAL_MOTION
4705
4706 for (i = 0; i < MAX_SEGMENTS; ++i) {
4707 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004708 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004709 : cm->base_qindex;
4710 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4711 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4712 }
4713
4714 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4715
4716 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004717 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004718
Yaowu Xuf883b422016-08-30 14:01:10 -07004719 av1_initialize_rd_consts(cpi);
4720 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004721 init_encode_frame_mb_context(cpi);
4722
4723 cm->use_prev_frame_mvs =
4724 !cm->error_resilient_mode && cm->width == cm->last_width &&
4725 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004726
4727#if CONFIG_DELTA_Q
4728 // Fix delta q resolution for the moment
4729 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4730#endif
4731
Yaowu Xuc27fc142016-08-22 16:08:15 -07004732#if CONFIG_EXT_REFS
4733 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4734 // show_exisiting_frame=1, nor can it take a frame not used as
4735 // a reference, it is probable that by the time it is being
4736 // referred to, the frame buffer it originally points to may
4737 // already get expired and have been reassigned to the current
4738 // newly coded frame. Hence, we need to check whether this is
4739 // the case, and if yes, we have 2 choices:
4740 // (1) Simply disable the use of previous frame mvs; or
4741 // (2) Have cm->prev_frame point to one reference frame buffer,
4742 // e.g. LAST_FRAME.
4743 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4744 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4745 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4746 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4747 }
4748#endif // CONFIG_EXT_REFS
4749
4750 // Special case: set prev_mi to NULL when the previous mode info
4751 // context cannot be used.
4752 cm->prev_mi =
4753 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4754
4755#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004756 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004757#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004758 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004759#endif
4760#endif
4761
4762 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4763 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004764 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004765
4766 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004767 struct aom_usec_timer emr_timer;
4768 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004769
4770#if CONFIG_FP_MB_STATS
4771 if (cpi->use_fp_mb_stats) {
4772 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4773 &cpi->twopass.this_frame_mb_stats);
4774 }
4775#endif
4776
4777 // If allowed, encoding tiles in parallel with one thread handling one tile.
4778 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4779 // 1 tile rows, as it uses the single above_context et al arrays from
4780 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004781 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4782 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004783 else
4784 encode_tiles(cpi);
4785
Yaowu Xuf883b422016-08-30 14:01:10 -07004786 aom_usec_timer_mark(&emr_timer);
4787 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004788 }
4789
4790#if 0
4791 // Keep record of the total distortion this time around for future use
4792 cpi->last_frame_distortion = cpi->frame_distortion;
4793#endif
4794}
4795
Yaowu Xuf883b422016-08-30 14:01:10 -07004796void av1_encode_frame(AV1_COMP *cpi) {
4797 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004798
4799 // In the longer term the encoder should be generalized to match the
4800 // decoder such that we allow compound where one of the 3 buffers has a
4801 // different sign bias and that buffer is then the fixed ref. However, this
4802 // requires further work in the rd loop. For now the only supported encoder
4803 // side behavior is where the ALT ref buffer has opposite sign bias to
4804 // the other two.
4805 if (!frame_is_intra_only(cm)) {
4806 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4807 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4808 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4809 cm->ref_frame_sign_bias[LAST_FRAME])) {
4810 cpi->allow_comp_inter_inter = 0;
4811 } else {
4812 cpi->allow_comp_inter_inter = 1;
4813
4814#if CONFIG_EXT_REFS
4815 cm->comp_fwd_ref[0] = LAST_FRAME;
4816 cm->comp_fwd_ref[1] = LAST2_FRAME;
4817 cm->comp_fwd_ref[2] = LAST3_FRAME;
4818 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4819 cm->comp_bwd_ref[0] = BWDREF_FRAME;
4820 cm->comp_bwd_ref[1] = ALTREF_FRAME;
4821#else
4822 cm->comp_fixed_ref = ALTREF_FRAME;
4823 cm->comp_var_ref[0] = LAST_FRAME;
4824 cm->comp_var_ref[1] = GOLDEN_FRAME;
4825#endif // CONFIG_EXT_REFS
4826 }
4827 } else {
4828 cpi->allow_comp_inter_inter = 0;
4829 }
4830
4831 if (cpi->sf.frame_parameter_update) {
4832 int i;
4833 RD_OPT *const rd_opt = &cpi->rd;
4834 FRAME_COUNTS *counts = cpi->td.counts;
4835 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4836
4837 // This code does a single RD pass over the whole frame assuming
4838 // either compound, single or hybrid prediction as per whatever has
4839 // worked best for that type of frame in the past.
4840 // It also predicts whether another coding mode would have worked
4841 // better than this coding mode. If that is the case, it remembers
4842 // that for subsequent frames.
4843 // It does the same analysis for transform size selection also.
4844 //
4845 // TODO(zoeliu): To investigate whether a frame_type other than
4846 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4847 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4848 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4849 const int is_alt_ref = frame_type == ALTREF_FRAME;
4850
4851 /* prediction (compound, single or hybrid) mode selection */
4852 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4853 cm->reference_mode = SINGLE_REFERENCE;
4854 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4855 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4856 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4857 cm->reference_mode = COMPOUND_REFERENCE;
4858 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4859 cm->reference_mode = SINGLE_REFERENCE;
4860 else
4861 cm->reference_mode = REFERENCE_MODE_SELECT;
4862
4863#if CONFIG_DUAL_FILTER
4864 cm->interp_filter = SWITCHABLE;
4865#endif
4866
4867 encode_frame_internal(cpi);
4868
4869 for (i = 0; i < REFERENCE_MODES; ++i)
4870 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4871
4872 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4873 int single_count_zero = 0;
4874 int comp_count_zero = 0;
4875
4876 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
4877 single_count_zero += counts->comp_inter[i][0];
4878 comp_count_zero += counts->comp_inter[i][1];
4879 }
4880
4881 if (comp_count_zero == 0) {
4882 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004883 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004884 } else if (single_count_zero == 0) {
4885 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07004886 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004887 }
4888 }
4889
Jingning Han9777afc2016-10-20 15:17:43 -07004890#if CONFIG_VAR_TX
4891 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
4892 cm->tx_mode = ALLOW_32X32;
4893#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004894 if (cm->tx_mode == TX_MODE_SELECT) {
4895 int count4x4 = 0;
4896 int count8x8_lp = 0, count8x8_8x8p = 0;
4897 int count16x16_16x16p = 0, count16x16_lp = 0;
4898 int count32x32 = 0;
4899 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07004900 // counts->tx_size[max_depth][context_idx][this_depth_level]
4901 count4x4 += counts->tx_size[0][i][0];
4902 count4x4 += counts->tx_size[1][i][0];
4903 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004904
Jingning Han2adcfb12016-10-27 11:19:53 -07004905 count8x8_lp += counts->tx_size[1][i][1];
4906 count8x8_lp += counts->tx_size[2][i][1];
4907 count8x8_8x8p += counts->tx_size[0][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004908
Jingning Han2adcfb12016-10-27 11:19:53 -07004909 count16x16_16x16p += counts->tx_size[1][i][2];
4910 count16x16_lp += counts->tx_size[2][i][2];
4911 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004912 }
4913#if CONFIG_EXT_TX && CONFIG_RECT_TX
4914 count4x4 += counts->tx_size_implied[0][TX_4X4];
4915 count4x4 += counts->tx_size_implied[1][TX_4X4];
4916 count4x4 += counts->tx_size_implied[2][TX_4X4];
4917 count4x4 += counts->tx_size_implied[3][TX_4X4];
4918 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
4919 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
4920 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
4921 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
4922 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
4923 count32x32 += counts->tx_size_implied[3][TX_32X32];
4924#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
4925 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
4926#if CONFIG_SUPERTX
4927 cm->counts.supertx_size[TX_16X16] == 0 &&
4928 cm->counts.supertx_size[TX_32X32] == 0 &&
4929#endif // CONFIG_SUPERTX
4930 count32x32 == 0) {
4931 cm->tx_mode = ALLOW_8X8;
4932 reset_skip_tx_size(cm, TX_8X8);
4933 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
4934 count8x8_lp == 0 && count16x16_lp == 0 &&
4935#if CONFIG_SUPERTX
4936 cm->counts.supertx_size[TX_8X8] == 0 &&
4937 cm->counts.supertx_size[TX_16X16] == 0 &&
4938 cm->counts.supertx_size[TX_32X32] == 0 &&
4939#endif // CONFIG_SUPERTX
4940 count32x32 == 0) {
4941 cm->tx_mode = ONLY_4X4;
4942 reset_skip_tx_size(cm, TX_4X4);
4943 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
4944 cm->tx_mode = ALLOW_32X32;
4945 } else if (count32x32 == 0 && count8x8_lp == 0 &&
4946#if CONFIG_SUPERTX
4947 cm->counts.supertx_size[TX_32X32] == 0 &&
4948#endif // CONFIG_SUPERTX
4949 count4x4 == 0) {
4950 cm->tx_mode = ALLOW_16X16;
4951 reset_skip_tx_size(cm, TX_16X16);
4952 }
4953 }
4954#endif
4955 } else {
4956 encode_frame_internal(cpi);
4957 }
4958}
4959
4960static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
4961 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
4962 const int intraonly) {
4963 const PREDICTION_MODE y_mode = mi->mbmi.mode;
4964 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
4965 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
4966
4967 if (bsize < BLOCK_8X8) {
4968 int idx, idy;
4969 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
4970 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
4971 for (idy = 0; idy < 2; idy += num_4x4_h)
4972 for (idx = 0; idx < 2; idx += num_4x4_w) {
4973 const int bidx = idy * 2 + idx;
4974 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
4975 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004976 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
4977 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004978 ++counts->kf_y_mode[a][l][bmode];
4979 } else {
4980 ++counts->y_mode[0][bmode];
4981 }
4982 }
4983 } else {
4984 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004985 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
4986 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004987 ++counts->kf_y_mode[above][left][y_mode];
4988 } else {
4989 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
4990 }
4991 }
4992
4993 ++counts->uv_mode[y_mode][uv_mode];
4994}
4995
4996#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004997static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07004998 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07004999 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005000 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5001 const int tx_row = blk_row >> 1;
5002 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005003 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5004 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005005 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005006 xd->left_txfm_context + tx_row,
5007 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005008 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5009
Yaowu Xuc27fc142016-08-22 16:08:15 -07005010 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5011
5012 if (tx_size == plane_tx_size) {
5013 ++counts->txfm_partition[ctx][0];
5014 mbmi->tx_size = tx_size;
5015 txfm_partition_update(xd->above_txfm_context + tx_col,
5016 xd->left_txfm_context + tx_row, tx_size);
5017 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005018 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5019 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005021
Yaowu Xuc27fc142016-08-22 16:08:15 -07005022 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005023 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005024
5025 if (tx_size == TX_8X8) {
5026 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5027 mbmi->tx_size = TX_4X4;
5028 txfm_partition_update(xd->above_txfm_context + tx_col,
5029 xd->left_txfm_context + tx_row, TX_4X4);
5030 return;
5031 }
5032
5033 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005034 int offsetr = (i >> 1) * bs;
5035 int offsetc = (i & 0x01) * bs;
5036 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5037 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005038 }
5039 }
5040}
5041
Jingning Han9777afc2016-10-20 15:17:43 -07005042static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5043 BLOCK_SIZE plane_bsize, int mi_row,
5044 int mi_col, FRAME_COUNTS *td_counts) {
5045 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005046 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5047 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
5048 TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005049 const int bh = tx_size_high_unit[max_tx_size];
5050 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005051 int idx, idy;
5052
5053 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5054 xd->left_txfm_context =
5055 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5056
5057 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005058 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005059 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5060 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005061}
5062
5063static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5064 int blk_col) {
5065 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5066 const int tx_row = blk_row >> 1;
5067 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005068 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5069 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005070 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5071
Yaowu Xuc27fc142016-08-22 16:08:15 -07005072 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5073
5074 if (tx_size == plane_tx_size) {
5075 mbmi->tx_size = tx_size;
5076 txfm_partition_update(xd->above_txfm_context + tx_col,
5077 xd->left_txfm_context + tx_row, tx_size);
5078
5079 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005080 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5081 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005082 int i;
5083
5084 if (tx_size == TX_8X8) {
5085 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5086 mbmi->tx_size = TX_4X4;
5087 txfm_partition_update(xd->above_txfm_context + tx_col,
5088 xd->left_txfm_context + tx_row, TX_4X4);
5089 return;
5090 }
5091
5092 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005093 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005094 int offsetr = (i >> 1) * bsl;
5095 int offsetc = (i & 0x01) * bsl;
5096 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005097 }
5098 }
5099}
5100
Urvang Joshi52648442016-10-13 17:27:51 -07005101static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5102 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5103 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005104 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5105 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
5106 TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005107 const int bh = tx_size_high_unit[max_tx_size];
5108 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005109 int idx, idy;
5110
5111 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5112 xd->left_txfm_context =
5113 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5114
5115 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005116 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005117 set_txfm_context(xd, max_tx_size, idy, idx);
5118}
5119#endif
5120
Urvang Joshi52648442016-10-13 17:27:51 -07005121static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5122 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5123 int mi_col, BLOCK_SIZE bsize,
5124 PICK_MODE_CONTEXT *ctx, int *rate) {
5125 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 MACROBLOCK *const x = &td->mb;
5127 MACROBLOCKD *const xd = &x->e_mbd;
5128 MODE_INFO **mi_8x8 = xd->mi;
5129 MODE_INFO *mi = mi_8x8[0];
5130 MB_MODE_INFO *mbmi = &mi->mbmi;
5131 const int seg_skip =
5132 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5133 const int mis = cm->mi_stride;
5134 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5135 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5136
Yaowu Xuc27fc142016-08-22 16:08:15 -07005137 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5138
5139 if (!is_inter_block(mbmi)) {
5140 int plane;
5141 mbmi->skip = 1;
5142 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Angie Chiangff6d8902016-10-21 11:02:09 -07005143 av1_encode_intra_block_plane((AV1_COMMON *)cm, x,
5144 AOMMAX(bsize, BLOCK_8X8), plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005145 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5147 frame_is_intra_only(cm));
5148
hui su5db97432016-10-14 16:10:14 -07005149 // TODO(huisu): move this into sum_intra_stats().
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005150 if (!dry_run && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005151 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005152 (void)counts;
5153#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005154 if (mbmi->mode == DC_PRED
5155#if CONFIG_PALETTE
5156 && mbmi->palette_mode_info.palette_size[0] == 0
5157#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005158 ) {
5159 const int use_filter_intra_mode =
5160 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5161 ++counts->filter_intra[0][use_filter_intra_mode];
5162 }
Urvang Joshib100db72016-10-12 16:28:56 -07005163 if (mbmi->uv_mode == DC_PRED
5164#if CONFIG_PALETTE
5165 && mbmi->palette_mode_info.palette_size[1] == 0
5166#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005167 ) {
5168 const int use_filter_intra_mode =
5169 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5170 ++counts->filter_intra[1][use_filter_intra_mode];
5171 }
5172#endif // CONFIG_FILTER_INTRA
5173#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005174 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5175 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005176 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005177 p_angle =
5178 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005179 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005180 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5181 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005182#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005183 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005184
Urvang Joshib100db72016-10-12 16:28:56 -07005185#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005186 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187 for (plane = 0; plane <= 1; ++plane) {
5188 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5189 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5190 xd->plane[plane].color_index_map[0];
5191 // TODO(huisu): this increases the use of token buffer. Needs stretch
5192 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005193 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005194 }
5195 }
5196 }
Urvang Joshib100db72016-10-12 16:28:56 -07005197#endif // CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005198 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005199 } else {
5200 int ref;
5201 const int is_compound = has_second_ref(mbmi);
5202
5203 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5204 for (ref = 0; ref < 1 + is_compound; ++ref) {
5205 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5206 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005207 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5208 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005209 }
5210 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Yaowu Xuf883b422016-08-30 14:01:10 -07005211 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5212 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005213
Yaowu Xuf883b422016-08-30 14:01:10 -07005214 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5215 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005216
Yue Chencb60b182016-10-13 15:18:22 -07005217#if CONFIG_MOTION_VAR
5218 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005219 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005220 }
Yue Chencb60b182016-10-13 15:18:22 -07005221#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005222
Angie Chiangff6d8902016-10-21 11:02:09 -07005223 av1_encode_sb((AV1_COMMON *)cm, x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005224#if CONFIG_VAR_TX
5225#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005226 if (is_rect_tx(mbmi->tx_size))
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005227 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005228 else
5229#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005230 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5231 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232#else
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005233 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005234#endif
5235 }
5236
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005237 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005238 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
5239 !(is_inter_block(mbmi) && (mbmi->skip || seg_skip))) {
5240 const int is_inter = is_inter_block(mbmi);
5241 const int tx_size_ctx = get_tx_size_context(xd);
5242 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5243 : intra_tx_size_cat_lookup[bsize];
5244 const TX_SIZE coded_tx_size = txsize_sqr_up_map[mbmi->tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005245 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005246#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005247 assert(IMPLIES(is_rect_tx(mbmi->tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005248#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5249#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005250#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005251 if (is_rect_tx_allowed(xd, mbmi)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005252 td->counts->rect_tx[tx_size_cat][is_rect_tx(mbmi->tx_size)]++;
5253 }
Yue Chen49587a72016-09-28 17:09:47 -07005254 if (!is_rect_tx_allowed(xd, mbmi) || !is_rect_tx(mbmi->tx_size)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005255#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005256 if (is_inter) {
5257 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5258 } else {
Jingning Han4e1737a2016-10-25 16:05:02 -07005259 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Han9777afc2016-10-20 15:17:43 -07005260 if (mbmi->tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
5261 }
Yue Chena1e48dc2016-08-29 17:29:33 -07005262#if CONFIG_EXT_TX && CONFIG_RECT_TX
5263 }
5264#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005265#endif
Jingning Handc9ad312016-10-20 12:00:15 -07005266#if !CONFIG_VAR_TX
Jingning Han4e1737a2016-10-25 16:05:02 -07005267 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005268#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005269 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005270 int i, j;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005271 TX_SIZE tx_size;
5272 // The new intra coding scheme requires no change of transform size
5273 if (is_inter_block(&mi->mbmi)) {
5274 if (xd->lossless[mbmi->segment_id]) {
5275 tx_size = TX_4X4;
5276 } else {
5277 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
5278 }
5279#if CONFIG_EXT_TX && CONFIG_RECT_TX
5280 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
5281 [txsize_sqr_up_map[mbmi->tx_size]];
5282#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5283 } else {
5284 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
5285 }
5286
Urvang Joshi454280d2016-10-14 16:51:44 -07005287 for (j = 0; j < mi_height; j++)
5288 for (i = 0; i < mi_width; i++)
5289 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
5290 mi_8x8[mis * j + i]->mbmi.tx_size = tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005291
5292#if CONFIG_VAR_TX
5293 if (mbmi->tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
5294#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005295 }
Jingning Han9777afc2016-10-20 15:17:43 -07005296
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297 ++td->counts->tx_size_totals[txsize_sqr_map[mbmi->tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005298 ++td->counts
5299 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005300#if CONFIG_EXT_TX
5301 if (get_ext_tx_types(mbmi->tx_size, bsize, is_inter_block(mbmi)) > 1 &&
5302 cm->base_qindex > 0 && !mbmi->skip &&
5303 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
5304 int eset = get_ext_tx_set(mbmi->tx_size, bsize, is_inter_block(mbmi));
5305 if (eset > 0) {
5306 if (is_inter_block(mbmi)) {
5307 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[mbmi->tx_size]]
5308 [mbmi->tx_type];
5309 } else {
clang-format67948d32016-09-07 22:40:40 -07005310 ++td->counts->intra_ext_tx[eset][mbmi->tx_size][mbmi->mode]
5311 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005312 }
5313 }
5314 }
5315#else
5316 if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
5317 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
5318 if (is_inter_block(mbmi)) {
5319 ++td->counts->inter_ext_tx[mbmi->tx_size][mbmi->tx_type];
5320 } else {
clang-format67948d32016-09-07 22:40:40 -07005321 ++td->counts->intra_ext_tx[mbmi->tx_size]
5322 [intra_mode_to_tx_type_context[mbmi->mode]]
5323 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005324 }
5325 }
5326#endif // CONFIG_EXT_TX
5327 }
5328
5329#if CONFIG_VAR_TX
5330 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
5331 is_inter_block(mbmi) && !(mbmi->skip || seg_skip)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005332#if CONFIG_EXT_TX && CONFIG_RECT_TX
5333 if (is_rect_tx(mbmi->tx_size)) {
5334 set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, xd);
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005335 } else {
5336 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005337 }
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005338#else
5339 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005340#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005341 } else {
5342 TX_SIZE tx_size;
5343 // The new intra coding scheme requires no change of transform size
5344 if (is_inter_block(mbmi))
5345#if CONFIG_EXT_TX && CONFIG_RECT_TX
5346 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005347 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005348 max_txsize_lookup[bsize]);
5349 if (txsize_sqr_map[max_txsize_rect_lookup[bsize]] <= tx_size)
5350 tx_size = max_txsize_rect_lookup[bsize];
5351 if (xd->lossless[mbmi->segment_id]) tx_size = TX_4X4;
5352 }
5353#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005354 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 max_txsize_lookup[bsize]);
5356#endif
5357 else
5358 tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4;
5359 mbmi->tx_size = tx_size;
5360 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, xd);
5361 }
5362#endif
5363}
5364
5365#if CONFIG_SUPERTX
5366static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5367 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5368#if CONFIG_EXT_INTER
5369 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5370#endif // CONFIG_EXT_INTER
5371 return 0;
5372}
5373
Urvang Joshi52648442016-10-13 17:27:51 -07005374static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5375 int mi_row, int mi_col, BLOCK_SIZE bsize,
5376 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005377 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005378
5379 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5380 const PARTITION_TYPE partition = pc_tree->partitioning;
5381 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5382#if CONFIG_EXT_PARTITION_TYPES
5383 int i;
5384#endif
5385
5386 assert(bsize >= BLOCK_8X8);
5387
5388 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5389
5390 switch (partition) {
5391 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5392 case PARTITION_VERT:
5393 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5394 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5395 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5396 }
5397 break;
5398 case PARTITION_HORZ:
5399 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5400 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5401 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5402 }
5403 break;
5404 case PARTITION_SPLIT:
5405 if (bsize == BLOCK_8X8) {
5406 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5407 } else {
5408 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5409 pc_tree->split[0]))
5410 return 1;
5411 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5412 pc_tree->split[1]))
5413 return 1;
5414 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5415 pc_tree->split[2]))
5416 return 1;
5417 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5418 pc_tree->split[3]))
5419 return 1;
5420 }
5421 break;
5422#if CONFIG_EXT_PARTITION_TYPES
5423 case PARTITION_HORZ_A:
5424 for (i = 0; i < 3; i++) {
5425 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5426 }
5427 break;
5428 case PARTITION_HORZ_B:
5429 for (i = 0; i < 3; i++) {
5430 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5431 }
5432 break;
5433 case PARTITION_VERT_A:
5434 for (i = 0; i < 3; i++) {
5435 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5436 }
5437 break;
5438 case PARTITION_VERT_B:
5439 for (i = 0; i < 3; i++) {
5440 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5441 }
5442 break;
5443#endif // CONFIG_EXT_PARTITION_TYPES
5444 default: assert(0);
5445 }
5446 return 0;
5447}
5448
5449static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5450 return ctx->mic.mbmi.tx_size == supertx_size;
5451}
5452
5453static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5454 PC_TREE *pc_tree) {
5455 PARTITION_TYPE partition;
5456 BLOCK_SIZE subsize;
5457
5458 partition = pc_tree->partitioning;
5459 subsize = get_subsize(bsize, partition);
5460 switch (partition) {
5461 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5462 case PARTITION_VERT:
5463 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5464 case PARTITION_HORZ:
5465 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5466 case PARTITION_SPLIT:
5467 if (bsize == BLOCK_8X8)
5468 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5469 else
5470 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5471#if CONFIG_EXT_PARTITION_TYPES
5472 case PARTITION_HORZ_A:
5473 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5474 case PARTITION_HORZ_B:
5475 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5476 case PARTITION_VERT_A:
5477 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5478 case PARTITION_VERT_B:
5479 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5480#endif // CONFIG_EXT_PARTITION_TYPES
5481 default: assert(0); return 0;
5482 }
5483}
5484
Urvang Joshi52648442016-10-13 17:27:51 -07005485static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486#if CONFIG_EXT_INTER
5487 int mi_row_ori, int mi_col_ori,
5488#endif // CONFIG_EXT_INTER
5489 int mi_row_pred, int mi_col_pred,
5490 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5491 // Used in supertx
5492 // (mi_row_ori, mi_col_ori): location for mv
5493 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005494 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005495 MACROBLOCK *const x = &td->mb;
5496 MACROBLOCKD *const xd = &x->e_mbd;
5497 MODE_INFO *mi_8x8 = xd->mi[0];
5498 MODE_INFO *mi = mi_8x8;
5499 MB_MODE_INFO *mbmi = &mi->mbmi;
5500 int ref;
5501 const int is_compound = has_second_ref(mbmi);
5502
5503 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5504
5505 for (ref = 0; ref < 1 + is_compound; ++ref) {
5506 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005507 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5508 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005509 }
5510
5511 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005512 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005513#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005514 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005515#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005516 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005518 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005519#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005520 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005521#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005522 mi_row_pred, mi_col_pred,
5523 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005524}
5525
Urvang Joshi52648442016-10-13 17:27:51 -07005526static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005527 const TileInfo *const tile, int block,
5528 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5529 int mi_col_pred, int mi_row_top, int mi_col_top,
5530 uint8_t *dst_buf[3], int dst_stride[3],
5531 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005532 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005533 // Used in supertx
5534 // (mi_row_ori, mi_col_ori): location for mv
5535 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5536 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5537 // block: sub location of sub8x8 blocks
5538 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5539 // bextend: 1: region to predict is an extension of ori; 0: not
5540
5541 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005542 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543 MACROBLOCKD *const xd = &x->e_mbd;
5544 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5545 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5546 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5547 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5548
5549 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5550 mi_row_pred >= mi_row_top + mi_height_top ||
5551 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5552 mi_col_pred >= cm->mi_cols)
5553 return;
5554
5555 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5556 mi_col_ori, bsize_pred);
5557 xd->plane[0].dst.stride = dst_stride[0];
5558 xd->plane[1].dst.stride = dst_stride[1];
5559 xd->plane[2].dst.stride = dst_stride[2];
5560 xd->plane[0].dst.buf = dst_buf[0] +
5561 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5562 (c >> xd->plane[0].subsampling_x);
5563 xd->plane[1].dst.buf = dst_buf[1] +
5564 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5565 (c >> xd->plane[1].subsampling_x);
5566 xd->plane[2].dst.buf = dst_buf[2] +
5567 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5568 (c >> xd->plane[2].subsampling_x);
5569
5570 predict_superblock(cpi, td,
5571#if CONFIG_EXT_INTER
5572 mi_row_ori, mi_col_ori,
5573#endif // CONFIG_EXT_INTER
5574 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5575
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005576 if (!dry_run && !bextend) {
5577#if CONFIG_SUPERTX
5578 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
5579#else
5580 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred);
5581#endif
5582 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583}
5584
Urvang Joshi52648442016-10-13 17:27:51 -07005585static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005586 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5587 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005588 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005589 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5590 // dir: 0-lower, 1-upper, 2-left, 3-right
5591 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5592 MACROBLOCKD *xd = &td->mb.e_mbd;
5593 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5594 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5595 int xss = xd->plane[1].subsampling_x;
5596 int yss = xd->plane[1].subsampling_y;
5597 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5598
5599 BLOCK_SIZE extend_bsize;
5600 int unit, mi_row_pred, mi_col_pred;
5601
5602 if (dir == 0 || dir == 1) { // lower and upper
5603 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5604 ? BLOCK_8X8
5605 : BLOCK_16X8;
5606 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5607 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5608 mi_col_pred = mi_col;
5609
5610 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5611 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005612 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005613
5614 if (mi_width > unit) {
5615 int i;
5616 for (i = 0; i < mi_width / unit - 1; i++) {
5617 mi_col_pred += unit;
5618 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5619 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005620 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5621 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005622 }
5623 }
5624 } else if (dir == 2 || dir == 3) { // left and right
5625 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5626 ? BLOCK_8X8
5627 : BLOCK_8X16;
5628 unit = num_8x8_blocks_high_lookup[extend_bsize];
5629 mi_row_pred = mi_row;
5630 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5631
5632 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5633 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005634 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635
5636 if (mi_height > unit) {
5637 int i;
5638 for (i = 0; i < mi_height / unit - 1; i++) {
5639 mi_row_pred += unit;
5640 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5641 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005642 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5643 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005644 }
5645 }
5646 } else {
5647 extend_bsize = BLOCK_8X8;
5648 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5649 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5650
5651 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5652 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005653 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005654 }
5655}
5656
Urvang Joshi52648442016-10-13 17:27:51 -07005657static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005658 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5659 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005660 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661 uint8_t *dst_buf[3], int dst_stride[3]) {
5662 assert(block >= 0 && block < 4);
5663 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005664 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005665 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005666 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005667 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005668 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005669 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005670 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005671 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005672 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005673 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005674 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005676 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005677 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005678 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005679}
5680
5681// This function generates prediction for multiple blocks, between which
5682// discontinuity around boundary is reduced by smoothing masks. The basic
5683// smoothing mask is a soft step function along horz/vert direction. In more
5684// complicated case when a block is split into 4 subblocks, the basic mask is
5685// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5686// then applied to the 2 masked prediction mentioned above in vertical direction
5687// If the block is split into more than one level, at every stage, masked
5688// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005689static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005690 const TileInfo *const tile, int mi_row,
5691 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005692 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005693 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5694 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005695 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005696 MACROBLOCK *const x = &td->mb;
5697 MACROBLOCKD *const xd = &x->e_mbd;
5698
5699 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5700 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5701 const PARTITION_TYPE partition = pc_tree->partitioning;
5702 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5703#if CONFIG_EXT_PARTITION_TYPES
5704 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5705#endif
5706
5707 int i;
5708 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
5709 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5710 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5711 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5712 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5713 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5714 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5715
5716 assert(bsize >= BLOCK_8X8);
5717
5718 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
5719
Yaowu Xuf883b422016-08-30 14:01:10 -07005720#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005721 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5722 int len = sizeof(uint16_t);
5723 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5724 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
5725 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
5726 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5727 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
5728 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
5729 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
5730 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
5731 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
5732 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005733#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005734 dst_buf1[0] = tmp_buf1;
5735 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
5736 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
5737 dst_buf2[0] = tmp_buf2;
5738 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
5739 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
5740 dst_buf3[0] = tmp_buf3;
5741 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
5742 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005743#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005744 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005745#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005746
Urvang Joshi52648442016-10-13 17:27:51 -07005747 if (!dry_run && bsize < top_bsize) {
5748 // Explicitly cast away const.
5749 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
5750 frame_counts->partition[ctx][partition]++;
5751 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005752
5753 for (i = 0; i < MAX_MB_PLANE; i++) {
5754 xd->plane[i].dst.buf = dst_buf[i];
5755 xd->plane[i].dst.stride = dst_stride[i];
5756 }
5757
5758 switch (partition) {
5759 case PARTITION_NONE:
5760 assert(bsize < top_bsize);
5761 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5762 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005763 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005765 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005766 break;
5767 case PARTITION_HORZ:
5768 if (bsize == BLOCK_8X8) {
5769 // Fisrt half
5770 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5771 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005772 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005773 if (bsize < top_bsize)
5774 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005775 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005776
5777 // Second half
5778 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5779 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005780 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005781 if (bsize < top_bsize)
5782 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005783 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005784
5785 // Smooth
5786 xd->plane[0].dst.buf = dst_buf[0];
5787 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005788 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005789 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5790 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5791 0);
5792 } else {
5793 // First half
5794 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5795 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005796 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005797 if (bsize < top_bsize)
5798 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005799 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005800 else
5801 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005802 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803
5804 if (mi_row + hbs < cm->mi_rows) {
5805 // Second half
5806 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5807 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005808 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809 if (bsize < top_bsize)
5810 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005811 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005812 dst_stride1);
5813 else
5814 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005815 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005816 dst_stride1, 1);
5817
5818 // Smooth
5819 for (i = 0; i < MAX_MB_PLANE; i++) {
5820 xd->plane[i].dst.buf = dst_buf[i];
5821 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005822 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005823 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5824 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5825 PARTITION_HORZ, i);
5826 }
5827 }
5828 }
5829 break;
5830 case PARTITION_VERT:
5831 if (bsize == BLOCK_8X8) {
5832 // First half
5833 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5834 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005835 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836 if (bsize < top_bsize)
5837 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005838 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005839
5840 // Second half
5841 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5842 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005843 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005844 if (bsize < top_bsize)
5845 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005846 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005847
5848 // Smooth
5849 xd->plane[0].dst.buf = dst_buf[0];
5850 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005851 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005852 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5853 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5854 0);
5855 } else {
5856 // bsize: not important, not useful
5857 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5858 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005859 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005860 if (bsize < top_bsize)
5861 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005862 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863 else
5864 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005865 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005866
5867 if (mi_col + hbs < cm->mi_cols) {
5868 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5869 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005870 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005871 if (bsize < top_bsize)
5872 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005873 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
5874 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005875 else
5876 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005877 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
5878 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005879
5880 for (i = 0; i < MAX_MB_PLANE; i++) {
5881 xd->plane[i].dst.buf = dst_buf[i];
5882 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005883 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005884 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5885 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5886 PARTITION_VERT, i);
5887 }
5888 }
5889 }
5890 break;
5891 case PARTITION_SPLIT:
5892 if (bsize == BLOCK_8X8) {
5893 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5894 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005895 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005896 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5897 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005898 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005899 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5900 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005901 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005902 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
5903 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005904 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005905
5906 if (bsize < top_bsize) {
5907 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005908 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005909 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005910 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005911 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005912 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005913 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005914 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005915 }
5916 } else {
5917 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005918 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
5919 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005920 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
5921 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005922 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
5923 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
5925 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005926 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
5927 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005928 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
5929 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005930 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005931 top_bsize, dst_buf3, dst_stride3,
5932 pc_tree->split[3]);
5933 }
5934 for (i = 0; i < MAX_MB_PLANE; i++) {
5935 if (bsize == BLOCK_8X8 && i != 0)
5936 continue; // Skip <4x4 chroma smoothing
5937 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005938 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005939 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5940 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5941 PARTITION_VERT, i);
5942 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005943 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005944 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
5945 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5946 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07005947 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005948 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
5949 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5950 PARTITION_HORZ, i);
5951 }
5952 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005953 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
5955 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5956 PARTITION_HORZ, i);
5957 }
5958 }
5959 break;
5960#if CONFIG_EXT_PARTITION_TYPES
5961 case PARTITION_HORZ_A:
5962 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5963 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005964 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005966 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005967
5968 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
5969 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005970 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005971 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005972 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005973
5974 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5975 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005976 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005977 if (bsize < top_bsize)
5978 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005979 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005980 else
5981 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005982 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005983
5984 for (i = 0; i < MAX_MB_PLANE; i++) {
5985 xd->plane[i].dst.buf = dst_buf[i];
5986 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005987 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005988 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
5989 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5990 i);
5991 }
5992 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005993 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005994 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
5995 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5996 i);
5997 }
5998
5999 break;
6000 case PARTITION_VERT_A:
6001
6002 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6003 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006004 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006005 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006006 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006007
6008 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6009 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006010 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006011 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006012 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006013
6014 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6015 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006016 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006017 if (bsize < top_bsize)
6018 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006019 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006020 else
6021 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006022 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006023
6024 for (i = 0; i < MAX_MB_PLANE; i++) {
6025 xd->plane[i].dst.buf = dst_buf[i];
6026 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006027 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006028 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6029 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6030 i);
6031 }
6032 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006033 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006034 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6035 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6036 i);
6037 }
6038 break;
6039 case PARTITION_HORZ_B:
6040
6041 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6042 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006043 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006044 if (bsize < top_bsize)
6045 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006046 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006047 else
6048 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006049 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006050
6051 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6052 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006053 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006054 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006055 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006056
6057 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6058 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006059 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006061 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006062 dst_stride2);
6063
6064 for (i = 0; i < MAX_MB_PLANE; i++) {
6065 xd->plane[i].dst.buf = dst_buf1[i];
6066 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006067 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006068 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6069 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6070 PARTITION_VERT, i);
6071 }
6072 for (i = 0; i < MAX_MB_PLANE; i++) {
6073 xd->plane[i].dst.buf = dst_buf[i];
6074 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006075 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006076 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6077 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6078 i);
6079 }
6080 break;
6081 case PARTITION_VERT_B:
6082
6083 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6084 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006085 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006086 if (bsize < top_bsize)
6087 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006088 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006089 else
6090 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006091 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006092
6093 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6094 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006095 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006096 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006097 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006098
6099 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6100 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006101 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006102 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006103 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006104 dst_stride2);
6105
6106 for (i = 0; i < MAX_MB_PLANE; i++) {
6107 xd->plane[i].dst.buf = dst_buf1[i];
6108 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006109 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006110 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6111 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6112 PARTITION_HORZ, i);
6113 }
6114 for (i = 0; i < MAX_MB_PLANE; i++) {
6115 xd->plane[i].dst.buf = dst_buf[i];
6116 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006117 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006118 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6119 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6120 i);
6121 }
6122 break;
6123#endif // CONFIG_EXT_PARTITION_TYPES
6124 default: assert(0);
6125 }
6126
6127#if CONFIG_EXT_PARTITION_TYPES
6128 if (bsize < top_bsize)
6129 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6130#else
6131 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6132 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6133#endif // CONFIG_EXT_PARTITION_TYPES
6134}
6135
Urvang Joshi52648442016-10-13 17:27:51 -07006136static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006137 const TileInfo *const tile, int mi_row, int mi_col,
6138 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6139 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006140 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006141 MACROBLOCK *const x = &td->mb;
6142 MACROBLOCKD *const xd = &x->e_mbd;
6143 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6144 base_rate = *tmp_rate;
6145 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6146 uint8_t *dst_buf[3];
6147 int dst_stride[3];
6148 TX_SIZE tx_size;
6149 MB_MODE_INFO *mbmi;
6150 TX_TYPE tx_type, best_tx_nostx;
6151#if CONFIG_EXT_TX
6152 int ext_tx_set;
6153#endif // CONFIG_EXT_TX
6154 int tmp_rate_tx = 0, skip_tx = 0;
6155 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6156
6157 set_skip_context(xd, mi_row, mi_col);
6158 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006159 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006160 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006161 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6162 dst_buf[plane] = xd->plane[plane].dst.buf;
6163 dst_stride[plane] = xd->plane[plane].dst.stride;
6164 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006165 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006166 bsize, dst_buf, dst_stride, pc_tree);
6167
6168 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6169 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6170
6171 mbmi = &xd->mi[0]->mbmi;
6172 best_tx_nostx = mbmi->tx_type;
6173
6174 *best_tx = DCT_DCT;
6175
6176 // chroma
6177 skippable_uv = 1;
6178 rate_uv = 0;
6179 dist_uv = 0;
6180 sse_uv = 0;
6181 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6182#if CONFIG_VAR_TX
6183 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6184 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6185 const struct macroblockd_plane *const pd = &xd->plane[plane];
6186 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006187 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006188
Angie Chiangb5dda482016-11-02 16:19:58 -07006189 this_rd_stats.rate = 0;
6190 this_rd_stats.dist = 0;
6191 this_rd_stats.sse = 0;
6192 this_rd_stats.skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006193
6194 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006195 tx_size =
6196 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006197 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6199
Yaowu Xuf883b422016-08-30 14:01:10 -07006200 av1_subtract_plane(x, bsize, plane);
6201 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006202 get_plane_block_size(bsize, pd), coeff_ctx,
6203 &this_rd_stats);
6204
6205 this_rate = this_rd_stats.rate;
6206 this_dist = this_rd_stats.dist;
6207 pnsse = this_rd_stats.sse;
6208 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006209#else
6210 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006211 tx_size =
6212 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006213 av1_subtract_plane(x, bsize, plane);
6214 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6215 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006216#endif // CONFIG_VAR_TX
6217
6218 rate_uv += this_rate;
6219 dist_uv += this_dist;
6220 sse_uv += pnsse;
6221 skippable_uv &= pnskip;
6222 }
6223
6224 // luma
6225 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006226 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006227#if CONFIG_EXT_TX
6228 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6229#endif // CONFIG_EXT_TX
6230 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6231#if CONFIG_VAR_TX
6232 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6233 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6234 const struct macroblockd_plane *const pd = &xd->plane[0];
6235 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006236 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006237#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006238
Yaowu Xuc27fc142016-08-22 16:08:15 -07006239#if CONFIG_EXT_TX
6240 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6241#else
6242 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6243#endif // CONFIG_EXT_TX
6244 mbmi->tx_type = tx_type;
6245
6246#if CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006247 this_rd_stats.rate = 0;
6248 this_rd_stats.dist = 0;
6249 this_rd_stats.sse = 0;
6250 this_rd_stats.skip = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006251
Yaowu Xuf883b422016-08-30 14:01:10 -07006252 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006253 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006254 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6255 &this_rd_stats);
6256
6257 this_rate = this_rd_stats.rate;
6258 this_dist = this_rd_stats.dist;
6259 pnsse = this_rd_stats.sse;
6260 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006261#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006262 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6263 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006264#endif // CONFIG_VAR_TX
6265
6266#if CONFIG_EXT_TX
6267 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6268 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6269 if (ext_tx_set > 0)
6270 this_rate +=
6271 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6272 }
6273#else
6274 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6275 this_rate != INT_MAX) {
6276 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6277 }
6278#endif // CONFIG_EXT_TX
6279 *tmp_rate = rate_uv + this_rate;
6280 *tmp_dist = dist_uv + this_dist;
6281 sse = sse_uv + pnsse;
6282 skippable = skippable_uv && pnskip;
6283 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006284 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006285 x->skip = 1;
6286 } else {
6287 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6288 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006289 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006290 x->skip = 0;
6291 } else {
6292 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006293 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006294 x->skip = 1;
6295 }
6296 }
6297 *tmp_rate += base_rate;
6298 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6299 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6300 *best_tx = tx_type;
6301 bestrd_tx = rd_tx;
6302 tmp_rate_tx = *tmp_rate;
6303 tmp_dist_tx = *tmp_dist;
6304 skip_tx = x->skip;
6305 }
6306 }
6307 *tmp_rate = tmp_rate_tx;
6308 *tmp_dist = tmp_dist_tx;
6309 x->skip = skip_tx;
6310#if CONFIG_VAR_TX
6311 for (plane = 0; plane < 1; ++plane)
6312 memset(x->blk_skip[plane], x->skip,
6313 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6314#endif // CONFIG_VAR_TX
6315 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6316}
6317#endif // CONFIG_SUPERTX