blob: bbd84d5d5e6c9098d680033ecdc45db1e921568d [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"
Yushin Cho77bba8d2016-11-04 16:36:56 -070056#if CONFIG_PVQ
57#include "av1/encoder/pvq_encoder.h"
58#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070059#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070060#define IF_HBD(...) __VA_ARGS__
61#else
62#define IF_HBD(...)
Yaowu Xuf883b422016-08-30 14:01:10 -070063#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070064
Urvang Joshi52648442016-10-13 17:27:51 -070065static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
66 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
67 int mi_col, BLOCK_SIZE bsize,
68 PICK_MODE_CONTEXT *ctx, int *rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -070069
70#if CONFIG_SUPERTX
71static int check_intra_b(PICK_MODE_CONTEXT *ctx);
72
Urvang Joshi52648442016-10-13 17:27:51 -070073static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
74 int mi_row, int mi_col, BLOCK_SIZE bsize,
75 PC_TREE *pc_tree);
76static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070077#if CONFIG_EXT_INTER
78 int mi_row_ori, int mi_col_ori,
79#endif // CONFIG_EXT_INTER
80 int mi_row_pred, int mi_col_pred,
81 BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
82static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
83 PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070084static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070085 const TileInfo *const tile, int mi_row,
86 int mi_col, int mi_row_ori, int mi_col_ori,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070087 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -070088 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
89 int dst_stride[3], PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070090static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 const TileInfo *const tile, int mi_row,
92 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -070093 RUN_TYPE dry_run, PC_TREE *pc_tree);
Urvang Joshi52648442016-10-13 17:27:51 -070094static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -070095 const TileInfo *const tile, int mi_row, int mi_col,
96 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
97 TX_TYPE *best_tx, PC_TREE *pc_tree);
98#endif // CONFIG_SUPERTX
99
100// This is used as a reference when computing the source variance for the
101// purposes of activity masking.
102// Eventually this should be replaced by custom no-reference routines,
103// which will be faster.
Yaowu Xuf883b422016-08-30 14:01:10 -0700104static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700105 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, 128,
108 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
109 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
110#if CONFIG_EXT_PARTITION
111 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
113 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
114 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
116#endif // CONFIG_EXT_PARTITION
117};
118
Yaowu Xuf883b422016-08-30 14:01:10 -0700119#if CONFIG_AOM_HIGHBITDEPTH
120static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121 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, 128,
124 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
125 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
126#if CONFIG_EXT_PARTITION
127 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
128 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
129 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
130 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
131 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128
132#endif // CONFIG_EXT_PARTITION
133};
134
Yaowu Xuf883b422016-08-30 14:01:10 -0700135static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700136 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 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
143 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
144#if CONFIG_EXT_PARTITION
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 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
152 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
153#endif // CONFIG_EXT_PARTITION
154};
155
Yaowu Xuf883b422016-08-30 14:01:10 -0700156static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700157 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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
165 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
166 128 * 16,
167#if CONFIG_EXT_PARTITION
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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
176 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
177 128 * 16
178#endif // CONFIG_EXT_PARTITION
179};
Yaowu Xuf883b422016-08-30 14:01:10 -0700180#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181
Urvang Joshi52648442016-10-13 17:27:51 -0700182unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700183 const struct buf_2d *ref,
184 BLOCK_SIZE bs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700185 unsigned int sse;
186 const unsigned int var =
Yaowu Xuf883b422016-08-30 14:01:10 -0700187 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700188 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
189}
190
Yaowu Xuf883b422016-08-30 14:01:10 -0700191#if CONFIG_AOM_HIGHBITDEPTH
Urvang Joshi52648442016-10-13 17:27:51 -0700192unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
Yaowu Xuf883b422016-08-30 14:01:10 -0700193 const struct buf_2d *ref,
194 BLOCK_SIZE bs, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700195 unsigned int var, sse;
196 switch (bd) {
197 case 10:
Yaowu Xuf883b422016-08-30 14:01:10 -0700198 var =
199 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
200 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201 break;
202 case 12:
Yaowu Xuf883b422016-08-30 14:01:10 -0700203 var =
204 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
205 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700206 break;
207 case 8:
208 default:
209 var =
210 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700211 CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8), 0, &sse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700212 break;
213 }
214 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
215}
Yaowu Xuf883b422016-08-30 14:01:10 -0700216#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700217
Urvang Joshi52648442016-10-13 17:27:51 -0700218static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700219 const struct buf_2d *ref,
220 int mi_row, int mi_col,
221 BLOCK_SIZE bs) {
222 unsigned int sse, var;
223 uint8_t *last_y;
224 const YV12_BUFFER_CONFIG *last = get_ref_frame_buffer(cpi, LAST_FRAME);
225
226 assert(last != NULL);
227 last_y =
228 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
229 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
230 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
231}
232
Yaowu Xuf883b422016-08-30 14:01:10 -0700233static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
234 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700235 unsigned int var = get_sby_perpixel_diff_variance(
236 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
237 if (var < 8)
238 return BLOCK_64X64;
239 else if (var < 128)
240 return BLOCK_32X32;
241 else if (var < 2048)
242 return BLOCK_16X16;
243 else
244 return BLOCK_8X8;
245}
246
247// Lighter version of set_offsets that only sets the mode info
248// pointers.
Urvang Joshi52648442016-10-13 17:27:51 -0700249static void set_mode_info_offsets(const AV1_COMP *const cpi,
250 MACROBLOCK *const x, MACROBLOCKD *const xd,
251 int mi_row, int mi_col) {
252 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700253 const int idx_str = xd->mi_stride * mi_row + mi_col;
254 xd->mi = cm->mi_grid_visible + idx_str;
255 xd->mi[0] = cm->mi + idx_str;
256 x->mbmi_ext = cpi->mbmi_ext_base + (mi_row * cm->mi_cols + mi_col);
257}
258
Urvang Joshi52648442016-10-13 17:27:51 -0700259static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700260 const TileInfo *const tile,
261 MACROBLOCK *const x, int mi_row,
262 int mi_col, BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700263 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700264 MACROBLOCKD *const xd = &x->e_mbd;
265 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
266 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Hana6923f72016-07-15 08:50:14 -0700267 const int bwl = b_width_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
268 const int bhl = b_height_log2_lookup[AOMMAX(bsize, BLOCK_8X8)];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700269
270 set_skip_context(xd, mi_row, mi_col);
271
272 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
273
274#if CONFIG_VAR_TX
275 xd->above_txfm_context = cm->above_txfm_context + mi_col;
276 xd->left_txfm_context =
277 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
278 xd->max_tx_size = max_txsize_lookup[bsize];
279#endif
280
281 // Set up destination pointers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700282 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700283
284 // Set up limit values for MV components.
285 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700286 x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
287 x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
288 x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + AOM_INTERP_EXTEND;
289 x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700290
Jingning Hana6923f72016-07-15 08:50:14 -0700291 set_plane_n4(xd, mi_width, mi_height, bwl, bhl);
292
Yaowu Xuc27fc142016-08-22 16:08:15 -0700293 // Set up distance of MB to edge of frame in 1/8th pel units.
294 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
295 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
296 cm->mi_cols);
297
298 // Set up source buffers.
Yaowu Xuf883b422016-08-30 14:01:10 -0700299 av1_setup_src_planes(x, cpi->Source, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300
301 // R/D setup.
302 x->rddiv = cpi->rd.RDDIV;
303 x->rdmult = cpi->rd.RDMULT;
304
Yaowu Xuf883b422016-08-30 14:01:10 -0700305 // required by av1_append_sub8x8_mvs_for_idx() and av1_find_best_ref_mvs()
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306 xd->tile = *tile;
307}
308
Urvang Joshi52648442016-10-13 17:27:51 -0700309static void set_offsets(const AV1_COMP *const cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700310 MACROBLOCK *const x, int mi_row, int mi_col,
311 BLOCK_SIZE bsize) {
Urvang Joshi52648442016-10-13 17:27:51 -0700312 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700313 MACROBLOCKD *const xd = &x->e_mbd;
314 MB_MODE_INFO *mbmi;
315 const struct segmentation *const seg = &cm->seg;
316
317 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
318
319 mbmi = &xd->mi[0]->mbmi;
320
321 // Setup segment ID.
322 if (seg->enabled) {
323 if (!cpi->vaq_refresh) {
324 const uint8_t *const map =
325 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
326 mbmi->segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
327 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700328 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700329 } else {
330 mbmi->segment_id = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700331 }
332
333#if CONFIG_SUPERTX
334 mbmi->segment_id_supertx = MAX_SEGMENTS;
335#endif // CONFIG_SUPERTX
336}
337
338#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -0700339static void set_offsets_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700340 const TileInfo *const tile, int mi_row,
341 int mi_col, BLOCK_SIZE bsize) {
342 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700343 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700344 MACROBLOCKD *const xd = &x->e_mbd;
345 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
346 const int mi_height = num_8x8_blocks_high_lookup[bsize];
347
348 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
349
350 // Set up distance of MB to edge of frame in 1/8th pel units.
351 assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
352 set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
353 cm->mi_cols);
354}
355
Urvang Joshi52648442016-10-13 17:27:51 -0700356static void set_offsets_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700357 const TileInfo *const tile, int mi_row_pred,
358 int mi_col_pred, int mi_row_ori, int mi_col_ori,
359 BLOCK_SIZE bsize_pred) {
360 // Used in supertx
361 // (mi_row_ori, mi_col_ori, bsize_ori): region for mv
362 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
363 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -0700364 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700365 MACROBLOCKD *const xd = &x->e_mbd;
366 const int mi_width = num_8x8_blocks_wide_lookup[bsize_pred];
367 const int mi_height = num_8x8_blocks_high_lookup[bsize_pred];
368
369 set_mode_info_offsets(cpi, x, xd, mi_row_ori, mi_col_ori);
370
371 // Set up limit values for MV components.
372 // Mv beyond the range do not produce new/different prediction block.
Yaowu Xuf883b422016-08-30 14:01:10 -0700373 x->mv_row_min = -(((mi_row_pred + mi_height) * MI_SIZE) + AOM_INTERP_EXTEND);
374 x->mv_col_min = -(((mi_col_pred + mi_width) * MI_SIZE) + AOM_INTERP_EXTEND);
375 x->mv_row_max = (cm->mi_rows - mi_row_pred) * MI_SIZE + AOM_INTERP_EXTEND;
376 x->mv_col_max = (cm->mi_cols - mi_col_pred) * MI_SIZE + AOM_INTERP_EXTEND;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700377
378 // Set up distance of MB to edge of frame in 1/8th pel units.
379 assert(!(mi_col_pred & (mi_width - 1)) && !(mi_row_pred & (mi_height - 1)));
380 set_mi_row_col(xd, tile, mi_row_pred, mi_height, mi_col_pred, mi_width,
381 cm->mi_rows, cm->mi_cols);
382 xd->up_available = (mi_row_ori > tile->mi_row_start);
383 xd->left_available = (mi_col_ori > tile->mi_col_start);
384
385 // R/D setup.
386 x->rddiv = cpi->rd.RDDIV;
387 x->rdmult = cpi->rd.RDMULT;
388}
389
Yaowu Xuf883b422016-08-30 14:01:10 -0700390static void set_segment_id_supertx(const AV1_COMP *const cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700391 MACROBLOCK *const x, const int mi_row,
392 const int mi_col, const BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700393 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700394 const struct segmentation *seg = &cm->seg;
395 const int miw =
Yaowu Xuf883b422016-08-30 14:01:10 -0700396 AOMMIN(num_8x8_blocks_wide_lookup[bsize], cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 const int mih =
Yaowu Xuf883b422016-08-30 14:01:10 -0700398 AOMMIN(num_8x8_blocks_high_lookup[bsize], cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399 const int mi_offset = mi_row * cm->mi_stride + mi_col;
400 MODE_INFO **const mip = cm->mi_grid_visible + mi_offset;
401 int r, c;
402 int seg_id_supertx = MAX_SEGMENTS;
403
404 if (!seg->enabled) {
405 seg_id_supertx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700406 } else {
407 // Find the minimum segment_id
408 for (r = 0; r < mih; r++)
409 for (c = 0; c < miw; c++)
410 seg_id_supertx =
Yaowu Xuf883b422016-08-30 14:01:10 -0700411 AOMMIN(mip[r * cm->mi_stride + c]->mbmi.segment_id, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700412 assert(0 <= seg_id_supertx && seg_id_supertx < MAX_SEGMENTS);
413
414 // Initialize plane quantisers
Yaowu Xuf883b422016-08-30 14:01:10 -0700415 av1_init_plane_quantizers(cpi, x, seg_id_supertx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700416 }
417
418 // Assign the the segment_id back to segment_id_supertx
419 for (r = 0; r < mih; r++)
420 for (c = 0; c < miw; c++)
421 mip[r * cm->mi_stride + c]->mbmi.segment_id_supertx = seg_id_supertx;
422}
423#endif // CONFIG_SUPERTX
424
Yaowu Xuf883b422016-08-30 14:01:10 -0700425static void set_block_size(AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700426 MACROBLOCKD *const xd, int mi_row, int mi_col,
427 BLOCK_SIZE bsize) {
428 if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
429 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
430 xd->mi[0]->mbmi.sb_type = bsize;
431 }
432}
433
Yaowu Xuf883b422016-08-30 14:01:10 -0700434static void set_vt_partitioning(AV1_COMP *cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700435 MACROBLOCKD *const xd, VAR_TREE *vt, int mi_row,
436 int mi_col, const int64_t *const threshold,
437 const BLOCK_SIZE *const bsize_min) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700438 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700439 const int hbw = num_8x8_blocks_wide_lookup[vt->bsize] / 2;
440 const int hbh = num_8x8_blocks_high_lookup[vt->bsize] / 2;
441 const int has_cols = mi_col + hbw < cm->mi_cols;
442 const int has_rows = mi_row + hbh < cm->mi_rows;
443
444 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
445
446 assert(vt->bsize >= BLOCK_8X8);
447
448 assert(hbh == hbw);
449
450 if (vt->bsize == BLOCK_8X8 && cm->frame_type != KEY_FRAME) {
451 set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_8X8);
452 return;
453 }
454
455 if (vt->force_split || (!has_cols && !has_rows)) goto split;
456
457 // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
458 // variance is below threshold, otherwise split will be selected.
459 // No check for vert/horiz split as too few samples for variance.
460 if (vt->bsize == bsize_min[0]) {
461 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
462 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
463 return;
464 } else {
465 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_SPLIT);
466 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
467 if (vt->bsize > BLOCK_8X8) {
468 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
469 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
470 set_block_size(cpi, x, xd, mi_row + hbh, mi_col + hbw, subsize);
471 }
472 return;
473 }
474 } else if (vt->bsize > bsize_min[0]) {
475 // For key frame: take split for bsize above 32X32 or very high variance.
476 if (cm->frame_type == KEY_FRAME &&
477 (vt->bsize > BLOCK_32X32 ||
478 vt->variances.none.variance > (threshold[0] << 4))) {
479 goto split;
480 }
481 // If variance is low, take the bsize (no split).
482 if (has_cols && has_rows && vt->variances.none.variance < threshold[0]) {
483 set_block_size(cpi, x, xd, mi_row, mi_col, vt->bsize);
484 return;
485 }
486
487 // Check vertical split.
488 if (has_rows) {
489 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_VERT);
490 if (vt->variances.vert[0].variance < threshold[0] &&
491 vt->variances.vert[1].variance < threshold[0] &&
492 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
493 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
494 set_block_size(cpi, x, xd, mi_row, mi_col + hbw, subsize);
495 return;
496 }
497 }
498 // Check horizontal split.
499 if (has_cols) {
500 BLOCK_SIZE subsize = get_subsize(vt->bsize, PARTITION_HORZ);
501 if (vt->variances.horz[0].variance < threshold[0] &&
502 vt->variances.horz[1].variance < threshold[0] &&
503 get_plane_block_size(subsize, &xd->plane[1]) < BLOCK_INVALID) {
504 set_block_size(cpi, x, xd, mi_row, mi_col, subsize);
505 set_block_size(cpi, x, xd, mi_row + hbh, mi_col, subsize);
506 return;
507 }
508 }
509 }
510
511split : {
512 set_vt_partitioning(cpi, x, xd, vt->split[0], mi_row, mi_col, threshold + 1,
513 bsize_min + 1);
514 set_vt_partitioning(cpi, x, xd, vt->split[1], mi_row, mi_col + hbw,
515 threshold + 1, bsize_min + 1);
516 set_vt_partitioning(cpi, x, xd, vt->split[2], mi_row + hbh, mi_col,
517 threshold + 1, bsize_min + 1);
518 set_vt_partitioning(cpi, x, xd, vt->split[3], mi_row + hbh, mi_col + hbw,
519 threshold + 1, bsize_min + 1);
520 return;
521}
522}
523
524// Set the variance split thresholds for following the block sizes:
525// 0 - threshold_64x64, 1 - threshold_32x32, 2 - threshold_16x16,
526// 3 - vbp_threshold_8x8. vbp_threshold_8x8 (to split to 4x4 partition) is
527// currently only used on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -0700528static void set_vbp_thresholds(AV1_COMP *cpi, int64_t thresholds[], int q) {
529 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700530 const int is_key_frame = (cm->frame_type == KEY_FRAME);
531 const int threshold_multiplier = is_key_frame ? 20 : 1;
532 const int64_t threshold_base =
533 (int64_t)(threshold_multiplier * cpi->y_dequant[q][1]);
534 if (is_key_frame) {
535 thresholds[1] = threshold_base;
536 thresholds[2] = threshold_base >> 2;
537 thresholds[3] = threshold_base >> 2;
538 thresholds[4] = threshold_base << 2;
539 } else {
540 thresholds[2] = threshold_base;
541 if (cm->width <= 352 && cm->height <= 288) {
542 thresholds[1] = threshold_base >> 2;
543 thresholds[3] = threshold_base << 3;
544 } else {
545 thresholds[1] = threshold_base;
546 thresholds[2] = (5 * threshold_base) >> 2;
547 if (cm->width >= 1920 && cm->height >= 1080)
548 thresholds[2] = (7 * threshold_base) >> 2;
549 thresholds[3] = threshold_base << cpi->oxcf.speed;
550 }
551 }
552 thresholds[0] = INT64_MIN;
553}
554
Yaowu Xuf883b422016-08-30 14:01:10 -0700555void av1_set_variance_partition_thresholds(AV1_COMP *cpi, int q) {
556 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700557 SPEED_FEATURES *const sf = &cpi->sf;
558 const int is_key_frame = (cm->frame_type == KEY_FRAME);
559 if (sf->partition_search_type != VAR_BASED_PARTITION &&
560 sf->partition_search_type != REFERENCE_PARTITION) {
561 return;
562 } else {
563 set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
564 // The thresholds below are not changed locally.
565 if (is_key_frame) {
566 cpi->vbp_threshold_sad = 0;
567 cpi->vbp_bsize_min = BLOCK_8X8;
568 } else {
569 if (cm->width <= 352 && cm->height <= 288)
570 cpi->vbp_threshold_sad = 100;
571 else
572 cpi->vbp_threshold_sad = (cpi->y_dequant[q][1] << 1) > 1000
573 ? (cpi->y_dequant[q][1] << 1)
574 : 1000;
575 cpi->vbp_bsize_min = BLOCK_16X16;
576 }
577 cpi->vbp_threshold_minmax = 15 + (q >> 3);
578 }
579}
580
581// Compute the minmax over the 8x8 subblocks.
582static int compute_minmax_8x8(const uint8_t *src, int src_stride,
583 const uint8_t *ref, int ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700584#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700585 int highbd,
586#endif
587 int pixels_wide, int pixels_high) {
588 int k;
589 int minmax_max = 0;
590 int minmax_min = 255;
591 // Loop over the 4 8x8 subblocks.
592 for (k = 0; k < 4; k++) {
593 const int x8_idx = ((k & 1) << 3);
594 const int y8_idx = ((k >> 1) << 3);
595 int min = 0;
596 int max = 0;
597 if (x8_idx < pixels_wide && y8_idx < pixels_high) {
598 const int src_offset = y8_idx * src_stride + x8_idx;
599 const int ref_offset = y8_idx * ref_stride + x8_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -0700600#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700601 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700602 aom_highbd_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603 ref_stride, &min, &max);
604 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700605 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700606 ref_stride, &min, &max);
607 }
608#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700609 aom_minmax_8x8(src + src_offset, src_stride, ref + ref_offset, ref_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700610 &min, &max);
611#endif
612 if ((max - min) > minmax_max) minmax_max = (max - min);
613 if ((max - min) < minmax_min) minmax_min = (max - min);
614 }
615 }
616 return (minmax_max - minmax_min);
617}
618
Yaowu Xuf883b422016-08-30 14:01:10 -0700619#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700620static INLINE int avg_4x4(const uint8_t *const src, const int stride,
621 const int highbd) {
622 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700623 return aom_highbd_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700624 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700625 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700626 }
627}
628#else
629static INLINE int avg_4x4(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700630 return aom_avg_4x4(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700631}
632#endif
633
Yaowu Xuf883b422016-08-30 14:01:10 -0700634#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635static INLINE int avg_8x8(const uint8_t *const src, const int stride,
636 const int highbd) {
637 if (highbd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 return aom_highbd_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700640 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641 }
642}
643#else
644static INLINE int avg_8x8(const uint8_t *const src, const int stride) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700645 return aom_avg_8x8(src, stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646}
647#endif
648
649static void init_variance_tree(VAR_TREE *const vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700650#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700651 const int highbd,
652#endif
653 BLOCK_SIZE bsize, BLOCK_SIZE leaf_size,
654 const int width, const int height,
655 const uint8_t *const src, const int src_stride,
656 const uint8_t *const ref, const int ref_stride) {
657 assert(bsize >= leaf_size);
658
659 vt->bsize = bsize;
660
661 vt->force_split = 0;
662
663 vt->src = src;
664 vt->src_stride = src_stride;
665 vt->ref = ref;
666 vt->ref_stride = ref_stride;
667
668 vt->width = width;
669 vt->height = height;
670
Yaowu Xuf883b422016-08-30 14:01:10 -0700671#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672 vt->highbd = highbd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700673#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674
675 if (bsize > leaf_size) {
676 const BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
677 const int px = num_4x4_blocks_wide_lookup[subsize] * 4;
678
679 init_variance_tree(vt->split[0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700680#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700681 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700682#endif // CONFIG_AOM_HIGHBITDEPTH
683 subsize, leaf_size, AOMMIN(px, width),
684 AOMMIN(px, height), src, src_stride, ref, ref_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700685 init_variance_tree(vt->split[1],
Yaowu Xuf883b422016-08-30 14:01:10 -0700686#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#endif // CONFIG_AOM_HIGHBITDEPTH
689 subsize, leaf_size, width - px, AOMMIN(px, height),
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 src + px, src_stride, ref + px, ref_stride);
691 init_variance_tree(vt->split[2],
Yaowu Xuf883b422016-08-30 14:01:10 -0700692#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700693 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700694#endif // CONFIG_AOM_HIGHBITDEPTH
695 subsize, leaf_size, AOMMIN(px, width), height - px,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696 src + px * src_stride, src_stride, ref + px * ref_stride,
697 ref_stride);
698 init_variance_tree(vt->split[3],
Yaowu Xuf883b422016-08-30 14:01:10 -0700699#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700700 highbd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700701#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 subsize, leaf_size, width - px, height - px,
703 src + px * src_stride + px, src_stride,
704 ref + px * ref_stride + px, ref_stride);
705 }
706}
707
708// Fill the variance tree based on averaging pixel values (sub-sampling), at
709// the leaf node size.
710static void fill_variance_tree(VAR_TREE *const vt, const BLOCK_SIZE leaf_size) {
711 if (vt->bsize > leaf_size) {
712 fill_variance_tree(vt->split[0], leaf_size);
713 fill_variance_tree(vt->split[1], leaf_size);
714 fill_variance_tree(vt->split[2], leaf_size);
715 fill_variance_tree(vt->split[3], leaf_size);
716 fill_variance_node(vt);
717 } else if (vt->width <= 0 || vt->height <= 0) {
718 fill_variance(0, 0, 0, &vt->variances.none);
719 } else {
720 unsigned int sse = 0;
721 int sum = 0;
722 int src_avg;
723 int ref_avg;
724 assert(leaf_size == BLOCK_4X4 || leaf_size == BLOCK_8X8);
725 if (leaf_size == BLOCK_4X4) {
726 src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
727 ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
728 } else {
729 src_avg = avg_8x8(vt->src, vt->src_stride IF_HBD(, vt->highbd));
730 ref_avg = avg_8x8(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
731 }
732 sum = src_avg - ref_avg;
733 sse = sum * sum;
734 fill_variance(sse, sum, 0, &vt->variances.none);
735 }
736}
737
738static void refine_variance_tree(VAR_TREE *const vt, const int64_t threshold) {
739 if (vt->bsize >= BLOCK_8X8) {
740 if (vt->bsize == BLOCK_16X16) {
741 if (vt->variances.none.variance <= threshold)
742 return;
743 else
744 vt->force_split = 0;
745 }
746
747 refine_variance_tree(vt->split[0], threshold);
748 refine_variance_tree(vt->split[1], threshold);
749 refine_variance_tree(vt->split[2], threshold);
750 refine_variance_tree(vt->split[3], threshold);
751
752 if (vt->bsize <= BLOCK_16X16) fill_variance_node(vt);
753 } else if (vt->width <= 0 || vt->height <= 0) {
754 fill_variance(0, 0, 0, &vt->variances.none);
755 } else {
756 const int src_avg = avg_4x4(vt->src, vt->src_stride IF_HBD(, vt->highbd));
757 const int ref_avg = avg_4x4(vt->ref, vt->ref_stride IF_HBD(, vt->highbd));
758 const int sum = src_avg - ref_avg;
759 const unsigned int sse = sum * sum;
760 assert(vt->bsize == BLOCK_4X4);
761 fill_variance(sse, sum, 0, &vt->variances.none);
762 }
763}
764
765static int check_split_key_frame(VAR_TREE *const vt, const int64_t threshold) {
766 if (vt->bsize == BLOCK_32X32) {
767 vt->force_split = vt->variances.none.variance > threshold;
768 } else {
769 vt->force_split |= check_split_key_frame(vt->split[0], threshold);
770 vt->force_split |= check_split_key_frame(vt->split[1], threshold);
771 vt->force_split |= check_split_key_frame(vt->split[2], threshold);
772 vt->force_split |= check_split_key_frame(vt->split[3], threshold);
773 }
774 return vt->force_split;
775}
776
Yaowu Xuf883b422016-08-30 14:01:10 -0700777static int check_split(AV1_COMP *const cpi, VAR_TREE *const vt,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 const int segment_id, const int64_t *const thresholds) {
779 if (vt->bsize == BLOCK_16X16) {
780 vt->force_split = vt->variances.none.variance > thresholds[0];
781 if (!vt->force_split && vt->variances.none.variance > thresholds[-1] &&
782 !cyclic_refresh_segment_id_boosted(segment_id)) {
783 // We have some nominal amount of 16x16 variance (based on average),
784 // compute the minmax over the 8x8 sub-blocks, and if above threshold,
785 // force split to 8x8 block for this 16x16 block.
786 int minmax =
787 compute_minmax_8x8(vt->src, vt->src_stride, vt->ref, vt->ref_stride,
Yaowu Xuf883b422016-08-30 14:01:10 -0700788#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700789 vt->highbd,
790#endif
791 vt->width, vt->height);
792 vt->force_split = minmax > cpi->vbp_threshold_minmax;
793 }
794 } else {
795 vt->force_split |=
796 check_split(cpi, vt->split[0], segment_id, thresholds + 1);
797 vt->force_split |=
798 check_split(cpi, vt->split[1], segment_id, thresholds + 1);
799 vt->force_split |=
800 check_split(cpi, vt->split[2], segment_id, thresholds + 1);
801 vt->force_split |=
802 check_split(cpi, vt->split[3], segment_id, thresholds + 1);
803
804 if (vt->bsize == BLOCK_32X32 && !vt->force_split) {
805 vt->force_split = vt->variances.none.variance > thresholds[0];
806 }
807 }
808
809 return vt->force_split;
810}
811
812// This function chooses partitioning based on the variance between source and
813// reconstructed last (or golden), where variance is computed for down-sampled
814// inputs.
Yaowu Xuf883b422016-08-30 14:01:10 -0700815static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816 const TileInfo *const tile, MACROBLOCK *const x,
817 const int mi_row, const int mi_col) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700818 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700819 MACROBLOCKD *const xd = &x->e_mbd;
820 VAR_TREE *const vt = td->var_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
Thomas Daededebafac2016-06-20 17:56:24 -0700821#if CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822 int i;
Thomas Daededebafac2016-06-20 17:56:24 -0700823#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 const uint8_t *src;
825 const uint8_t *ref;
826 int src_stride;
827 int ref_stride;
828 int pixels_wide = 8 * num_8x8_blocks_wide_lookup[cm->sb_size];
829 int pixels_high = 8 * num_8x8_blocks_high_lookup[cm->sb_size];
830 int64_t thresholds[5] = {
831 cpi->vbp_thresholds[0], cpi->vbp_thresholds[1], cpi->vbp_thresholds[2],
832 cpi->vbp_thresholds[3], cpi->vbp_thresholds[4],
833 };
834 BLOCK_SIZE bsize_min[5] = { BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
835 cpi->vbp_bsize_min, BLOCK_8X8 };
836 const int start_level = cm->sb_size == BLOCK_64X64 ? 1 : 0;
837 const int64_t *const thre = thresholds + start_level;
838 const BLOCK_SIZE *const bmin = bsize_min + start_level;
839
840 const int is_key_frame = (cm->frame_type == KEY_FRAME);
841 const int low_res = (cm->width <= 352 && cm->height <= 288);
842
843 int segment_id = CR_SEGMENT_ID_BASE;
844
845 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled) {
846 const uint8_t *const map =
847 cm->seg.update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
848 segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
849
850 if (cyclic_refresh_segment_id_boosted(segment_id)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700851 int q = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700852 set_vbp_thresholds(cpi, thresholds, q);
853 }
854 }
855
856 set_offsets(cpi, tile, x, mi_row, mi_col, cm->sb_size);
857
858 if (xd->mb_to_right_edge < 0) pixels_wide += (xd->mb_to_right_edge >> 3);
859 if (xd->mb_to_bottom_edge < 0) pixels_high += (xd->mb_to_bottom_edge >> 3);
860
861 src = x->plane[0].src.buf;
862 src_stride = x->plane[0].src.stride;
863
864 if (!is_key_frame) {
865 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700866 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
867 const YV12_BUFFER_CONFIG *yv12_g = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
868 unsigned int y_sad, y_sad_g;
869
870 const int hbs = cm->mib_size / 2;
871 const int split_vert = mi_col + hbs >= cm->mi_cols;
872 const int split_horz = mi_row + hbs >= cm->mi_rows;
873 BLOCK_SIZE bsize;
874
875 if (split_vert && split_horz)
876 bsize = get_subsize(cm->sb_size, PARTITION_SPLIT);
877 else if (split_vert)
878 bsize = get_subsize(cm->sb_size, PARTITION_VERT);
879 else if (split_horz)
880 bsize = get_subsize(cm->sb_size, PARTITION_HORZ);
881 else
882 bsize = cm->sb_size;
883
884 assert(yv12 != NULL);
885
886 if (yv12_g && yv12_g != yv12) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700887 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
888 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700889 y_sad_g = cpi->fn_ptr[bsize].sdf(
890 x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].pre[0].buf,
891 xd->plane[0].pre[0].stride);
892 } else {
893 y_sad_g = UINT_MAX;
894 }
895
Yaowu Xuf883b422016-08-30 14:01:10 -0700896 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
897 &cm->frame_refs[LAST_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700898 mbmi->ref_frame[0] = LAST_FRAME;
899 mbmi->ref_frame[1] = NONE;
900 mbmi->sb_type = cm->sb_size;
901 mbmi->mv[0].as_int = 0;
902#if CONFIG_DUAL_FILTER
903 for (i = 0; i < 4; ++i) mbmi->interp_filter[i] = BILINEAR;
904#else
905 mbmi->interp_filter = BILINEAR;
906#endif
907
Yaowu Xuf883b422016-08-30 14:01:10 -0700908 y_sad = av1_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700909
910 if (y_sad_g < y_sad) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700911 av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,
912 &cm->frame_refs[GOLDEN_FRAME - 1].sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700913 mbmi->ref_frame[0] = GOLDEN_FRAME;
914 mbmi->mv[0].as_int = 0;
915 y_sad = y_sad_g;
916 } else {
917 x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
918 }
919
Yaowu Xuf883b422016-08-30 14:01:10 -0700920 av1_build_inter_predictors_sb(xd, mi_row, mi_col, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700921
Yaowu Xuc27fc142016-08-22 16:08:15 -0700922 ref = xd->plane[0].dst.buf;
923 ref_stride = xd->plane[0].dst.stride;
924
925 // If the y_sad is very small, take the largest partition and exit.
926 // Don't check on boosted segment for now, as largest is suppressed there.
927 if (segment_id == CR_SEGMENT_ID_BASE && y_sad < cpi->vbp_threshold_sad) {
928 if (!split_vert && !split_horz) {
929 set_block_size(cpi, x, xd, mi_row, mi_col, cm->sb_size);
930 return;
931 }
932 }
933 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700934 ref = AV1_VAR_OFFS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 ref_stride = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700936#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
938 switch (xd->bd) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700939 case 10: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_10); break;
940 case 12: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_12); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941 case 8:
Yaowu Xuf883b422016-08-30 14:01:10 -0700942 default: ref = CONVERT_TO_BYTEPTR(AV1_HIGH_VAR_OFFS_8); break;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 }
944 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700945#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 }
947
948 init_variance_tree(
949 vt,
Yaowu Xuf883b422016-08-30 14:01:10 -0700950#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH,
Yaowu Xuf883b422016-08-30 14:01:10 -0700952#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 cm->sb_size, (is_key_frame || low_res) ? BLOCK_4X4 : BLOCK_8X8,
954 pixels_wide, pixels_high, src, src_stride, ref, ref_stride);
955
956 // Fill in the entire tree of variances and compute splits.
957 if (is_key_frame) {
958 fill_variance_tree(vt, BLOCK_4X4);
959 check_split_key_frame(vt, thre[1]);
960 } else {
961 fill_variance_tree(vt, BLOCK_8X8);
962 check_split(cpi, vt, segment_id, thre);
963 if (low_res) {
964 refine_variance_tree(vt, thre[1] << 1);
965 }
966 }
967
968 vt->force_split |= mi_col + cm->mib_size > cm->mi_cols ||
969 mi_row + cm->mib_size > cm->mi_rows;
970
971 // Now go through the entire structure, splitting every block size until
972 // we get to one that's got a variance lower than our threshold.
973 set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
974}
975
976#if CONFIG_DUAL_FILTER
Urvang Joshi52648442016-10-13 17:27:51 -0700977static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700978 MB_MODE_INFO *mbmi) {
979 int dir;
980 for (dir = 0; dir < 2; ++dir) {
981 if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
982 (mbmi->ref_frame[1] == NONE ||
983 !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
984 mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
985 ? EIGHTTAP_REGULAR
986 : cm->interp_filter;
987 mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
988 }
989}
990
991static void update_filter_type_count(FRAME_COUNTS *counts,
992 const MACROBLOCKD *xd,
993 const MB_MODE_INFO *mbmi) {
994 int dir;
995 for (dir = 0; dir < 2; ++dir) {
996 if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
997 (mbmi->ref_frame[1] > INTRA_FRAME &&
998 has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700999 const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001000 ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
1001 }
1002 }
1003}
1004#endif
1005#if CONFIG_GLOBAL_MOTION
1006static void update_global_motion_used(PREDICTION_MODE mode,
Yaowu Xuf883b422016-08-30 14:01:10 -07001007 const MB_MODE_INFO *mbmi, AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001008 if (mode == ZEROMV) {
1009 ++cpi->global_motion_used[mbmi->ref_frame[0]];
1010 if (has_second_ref(mbmi)) ++cpi->global_motion_used[mbmi->ref_frame[1]];
1011 }
1012}
1013#endif // CONFIG_GLOBAL_MOTION
1014
Urvang Joshi52648442016-10-13 17:27:51 -07001015static void update_state(const AV1_COMP *const cpi, ThreadData *td,
1016 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
1017 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018 int i, x_idx, y;
Urvang Joshi52648442016-10-13 17:27:51 -07001019 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001020 RD_COUNTS *const rdc = &td->rd_counts;
1021 MACROBLOCK *const x = &td->mb;
1022 MACROBLOCKD *const xd = &x->e_mbd;
1023 struct macroblock_plane *const p = x->plane;
1024 struct macroblockd_plane *const pd = xd->plane;
1025 MODE_INFO *mi = &ctx->mic;
1026 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1027 MODE_INFO *mi_addr = xd->mi[0];
1028 const struct segmentation *const seg = &cm->seg;
1029 const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
1030 const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
Yaowu Xuf883b422016-08-30 14:01:10 -07001031 const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
1032 const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001033 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1034 int w, h;
1035
1036 const int mis = cm->mi_stride;
1037 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1038 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001039
1040#if CONFIG_REF_MV
1041 int8_t rf_type;
1042#endif
1043
1044#if !CONFIG_SUPERTX
1045 assert(mi->mbmi.sb_type == bsize);
1046#endif
1047
1048 *mi_addr = *mi;
1049 *x->mbmi_ext = ctx->mbmi_ext;
1050
1051#if CONFIG_DUAL_FILTER
1052 reset_intmv_filter_type(cm, xd, mbmi);
1053#endif
1054
1055#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001056 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001057 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1058 mbmi->mode == NEWMV) {
1059 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1060 int_mv this_mv =
1061 (i == 0)
1062 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1063 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1064 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1065 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1066 mbmi->pred_mv[i] = this_mv;
Yaowu Xu4306b6e2016-09-27 12:55:32 -07001067 mi->mbmi.pred_mv[i] = this_mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001068 }
1069 }
1070#endif
1071
1072 // If segmentation in use
1073 if (seg->enabled) {
1074 // For in frame complexity AQ copy the segment id from the segment map.
1075 if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
1076 const uint8_t *const map =
1077 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1078 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1079 }
1080 // Else for cyclic refresh mode update the segment map, set the segment id
1081 // and then update the quantizer.
1082 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001083 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1084 bsize, ctx->rate, ctx->dist, x->skip);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001085 }
1086 }
1087
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001088 for (i = 0; i < MAX_MB_PLANE; ++i) {
1089 p[i].coeff = ctx->coeff[i];
1090 p[i].qcoeff = ctx->qcoeff[i];
1091 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001092#if CONFIG_PVQ
1093 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1094#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001095 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 }
Urvang Joshib100db72016-10-12 16:28:56 -07001097#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001099#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001100
1101 // Restore the coding context of the MB to that that was in place
1102 // when the mode was picked for it
1103 for (y = 0; y < mi_height; y++)
1104 for (x_idx = 0; x_idx < mi_width; x_idx++)
1105 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1106 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1107 xd->mi[x_idx + y * mis] = mi_addr;
1108 }
1109
Arild Fuldseth07441162016-08-15 15:07:52 +02001110#if CONFIG_DELTA_Q
1111 if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001112 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001113#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001114 if (cpi->oxcf.aq_mode)
Yaowu Xuf883b422016-08-30 14:01:10 -07001115 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02001116#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001117
1118 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1119 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1120 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1121 }
1122
1123 x->skip = ctx->skip;
1124
1125#if CONFIG_VAR_TX
1126 for (i = 0; i < 1; ++i)
1127 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1128 sizeof(uint8_t) * ctx->num_4x4_blk);
1129#endif
1130
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001131 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001132
1133#if CONFIG_INTERNAL_STATS
Urvang Joshi52648442016-10-13 17:27:51 -07001134 {
1135 unsigned int *const mode_chosen_counts =
1136 (unsigned int *)cpi->mode_chosen_counts; // Cast const away.
1137 if (frame_is_intra_only(cm)) {
1138 static const int kf_mode_index[] = {
1139 THR_DC /*DC_PRED*/, THR_V_PRED /*V_PRED*/,
1140 THR_H_PRED /*H_PRED*/, THR_D45_PRED /*D45_PRED*/,
1141 THR_D135_PRED /*D135_PRED*/, THR_D117_PRED /*D117_PRED*/,
1142 THR_D153_PRED /*D153_PRED*/, THR_D207_PRED /*D207_PRED*/,
1143 THR_D63_PRED /*D63_PRED*/, THR_TM /*TM_PRED*/,
1144 };
1145 ++mode_chosen_counts[kf_mode_index[mbmi->mode]];
1146 } else {
1147 // Note how often each mode chosen as best
1148 ++mode_chosen_counts[ctx->best_mode_index];
1149 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001150 }
1151#endif
1152 if (!frame_is_intra_only(cm)) {
1153 if (is_inter_block(mbmi)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001154 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001155#if CONFIG_GLOBAL_MOTION
1156 if (bsize >= BLOCK_8X8) {
James Zernaf322e12016-10-22 12:43:15 -07001157 // TODO(sarahparker): global motion stats need to be handled per-tile
1158 // to be compatible with tile-based threading.
1159 update_global_motion_used(mbmi->mode, mbmi, (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160 } else {
1161 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
1162 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
1163 int idx, idy;
1164 for (idy = 0; idy < 2; idy += num_4x4_h) {
1165 for (idx = 0; idx < 2; idx += num_4x4_w) {
1166 const int j = idy * 2 + idx;
James Zernaf322e12016-10-22 12:43:15 -07001167 update_global_motion_used(mi->bmi[j].as_mode, mbmi,
1168 (AV1_COMP *)cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001169 }
1170 }
1171 }
1172#endif // CONFIG_GLOBAL_MOTION
1173 if (cm->interp_filter == SWITCHABLE
1174#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001175 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001176#endif
1177 ) {
1178#if CONFIG_DUAL_FILTER
1179 update_filter_type_count(td->counts, xd, mbmi);
1180#else
Urvang Joshi454280d2016-10-14 16:51:44 -07001181 const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
1182 ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001183#endif
1184 }
1185 }
1186
1187 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1188 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1189 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1190 }
1191
1192 for (h = 0; h < y_mis; ++h) {
1193 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1194 for (w = 0; w < x_mis; ++w) {
1195 MV_REF *const mv = frame_mv + w;
1196 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1197 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1198 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1199 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1200 }
1201 }
1202}
1203
1204#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07001205static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001206 PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001207 BLOCK_SIZE bsize, RUN_TYPE dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001208 int y, x_idx;
1209#if CONFIG_VAR_TX || CONFIG_REF_MV
1210 int i;
1211#endif
Urvang Joshi52648442016-10-13 17:27:51 -07001212 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213 RD_COUNTS *const rdc = &td->rd_counts;
1214 MACROBLOCK *const x = &td->mb;
1215 MACROBLOCKD *const xd = &x->e_mbd;
1216 MODE_INFO *mi = &ctx->mic;
1217 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1218 MODE_INFO *mi_addr = xd->mi[0];
1219 const struct segmentation *const seg = &cm->seg;
1220 const int mis = cm->mi_stride;
1221 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
1222 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07001223 const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
1224 const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001225 MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
1226 int w, h;
1227
1228#if CONFIG_REF_MV
1229 int8_t rf_type;
1230#endif
1231
1232 *mi_addr = *mi;
1233 *x->mbmi_ext = ctx->mbmi_ext;
1234 assert(is_inter_block(mbmi));
1235 assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
1236
1237#if CONFIG_DUAL_FILTER
1238 reset_intmv_filter_type(cm, xd, mbmi);
1239#endif
1240
1241#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07001242 rf_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001243 if (x->mbmi_ext->ref_mv_count[rf_type] > 1 && mbmi->sb_type >= BLOCK_8X8 &&
1244 mbmi->mode == NEWMV) {
1245 for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
1246 int_mv this_mv =
1247 (i == 0)
1248 ? x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].this_mv
1249 : x->mbmi_ext->ref_mv_stack[rf_type][mbmi->ref_mv_idx].comp_mv;
1250 clamp_mv_ref(&this_mv.as_mv, xd->n8_w << 3, xd->n8_h << 3, xd);
1251 lower_mv_precision(&this_mv.as_mv, cm->allow_high_precision_mv);
1252 x->mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0] = this_mv;
1253 mbmi->pred_mv[i] = this_mv;
1254 }
1255 }
1256#endif
1257
1258 // If segmentation in use
1259 if (seg->enabled) {
1260 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001261 const int energy =
1262 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1263 mi_addr->mbmi.segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001264 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
1265 // For cyclic refresh mode, now update the segment map
1266 // and set the segment id.
Yaowu Xuf883b422016-08-30 14:01:10 -07001267 av1_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, mi_row, mi_col,
1268 bsize, ctx->rate, ctx->dist, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001269 } else {
1270 // Otherwise just set the segment id based on the current segment map
1271 const uint8_t *const map =
1272 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
1273 mi_addr->mbmi.segment_id = get_segment_id(cm, map, bsize, mi_row, mi_col);
1274 }
1275 mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
1276 }
1277
1278 // Restore the coding context of the MB to that that was in place
1279 // when the mode was picked for it
1280 for (y = 0; y < mi_height; y++)
1281 for (x_idx = 0; x_idx < mi_width; x_idx++)
1282 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
1283 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
1284 xd->mi[x_idx + y * mis] = mi_addr;
1285 }
1286
1287 if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
1288 mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
1289 mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
1290 }
1291
1292 x->skip = ctx->skip;
1293
1294#if CONFIG_VAR_TX
1295 for (i = 0; i < 1; ++i)
1296 memcpy(x->blk_skip[i], ctx->blk_skip[i],
1297 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001298
1299 if (!is_inter_block(mbmi) || mbmi->skip)
1300 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001301#endif // CONFIG_VAR_TX
1302
1303#if CONFIG_VAR_TX
1304 {
1305 const TX_SIZE mtx = mbmi->tx_size;
Jingning Han32b20282016-10-28 15:42:44 -07001306 const int num_4x4_blocks_wide = tx_size_wide_unit[mtx] >> 1;
1307 const int num_4x4_blocks_high = tx_size_high_unit[mtx] >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001308 int idy, idx;
Debargha Mukherjee28d924b2016-10-05 00:48:28 -07001309 mbmi->inter_tx_size[0][0] = mtx;
1310 for (idy = 0; idy < num_4x4_blocks_high; ++idy)
1311 for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
1312 mbmi->inter_tx_size[idy][idx] = mtx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001313 }
1314#endif // CONFIG_VAR_TX
1315 // Turn motion variation off for supertx
Yue Chencb60b182016-10-13 15:18:22 -07001316 mbmi->motion_mode = SIMPLE_TRANSLATION;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001317
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001318 if (dry_run) return;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001319
1320 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001321 av1_update_mv_count(td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001322
1323 if (cm->interp_filter == SWITCHABLE
1324#if CONFIG_EXT_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -07001325 && av1_is_interp_needed(xd)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001326#endif
1327 ) {
1328#if CONFIG_DUAL_FILTER
1329 update_filter_type_count(td->counts, xd, mbmi);
1330#else
James Zern9ca190c2016-10-22 12:42:43 -07001331 const int pred_ctx = av1_get_pred_context_switchable_interp(xd);
1332 ++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001333#endif
1334 }
1335
1336 rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
1337 rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
1338 rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
1339 }
1340
1341 for (h = 0; h < y_mis; ++h) {
1342 MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
1343 for (w = 0; w < x_mis; ++w) {
1344 MV_REF *const mv = frame_mv + w;
1345 mv->ref_frame[0] = mi->mbmi.ref_frame[0];
1346 mv->ref_frame[1] = mi->mbmi.ref_frame[1];
1347 mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
1348 mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
1349 }
1350 }
1351}
1352
Urvang Joshi52648442016-10-13 17:27:51 -07001353static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001354 const TileInfo *const tile, int mi_row,
1355 int mi_col, BLOCK_SIZE bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001356 RUN_TYPE dry_run, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07001357 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001358 MACROBLOCK *const x = &td->mb;
1359 MACROBLOCKD *const xd = &x->e_mbd;
1360 struct macroblock_plane *const p = x->plane;
1361 struct macroblockd_plane *const pd = xd->plane;
1362 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1363 PARTITION_TYPE partition = pc_tree->partitioning;
1364 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1365 int i;
1366#if CONFIG_EXT_PARTITION_TYPES
1367 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
1368#endif
1369 PICK_MODE_CONTEXT *pmc = NULL;
1370
1371 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1372
1373 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07001374 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001375
1376 switch (partition) {
1377 case PARTITION_NONE:
1378 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1379 update_state_supertx(cpi, td, &pc_tree->none, mi_row, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001380 dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 break;
1382 case PARTITION_VERT:
1383 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1384 update_state_supertx(cpi, td, &pc_tree->vertical[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001385 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001386 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
1387 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1388 update_state_supertx(cpi, td, &pc_tree->vertical[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001389 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390 }
1391 pmc = &pc_tree->vertical_supertx;
1392 break;
1393 case PARTITION_HORZ:
1394 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1395 update_state_supertx(cpi, td, &pc_tree->horizontal[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001396 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001397 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
1398 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1399 update_state_supertx(cpi, td, &pc_tree->horizontal[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001400 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401 }
1402 pmc = &pc_tree->horizontal_supertx;
1403 break;
1404 case PARTITION_SPLIT:
1405 if (bsize == BLOCK_8X8) {
1406 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1407 update_state_supertx(cpi, td, pc_tree->leaf_split[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001408 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001409 } else {
1410 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001411 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, subsize, dry_run,
1412 pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001413 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1414 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001415 dry_run, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001416 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1417 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001418 dry_run, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001419 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, subsize);
1420 update_state_sb_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001421 subsize, dry_run, pc_tree->split[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001422 }
1423 pmc = &pc_tree->split_supertx;
1424 break;
1425#if CONFIG_EXT_PARTITION_TYPES
1426 case PARTITION_HORZ_A:
1427 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1428 update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001429 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001430 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1431 update_state_supertx(cpi, td, &pc_tree->horizontala[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001432 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001433 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, subsize);
1434 update_state_supertx(cpi, td, &pc_tree->horizontala[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001435 mi_col, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001436 pmc = &pc_tree->horizontala_supertx;
1437 break;
1438 case PARTITION_HORZ_B:
1439 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1440 update_state_supertx(cpi, td, &pc_tree->horizontalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001441 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001442 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1443 update_state_supertx(cpi, td, &pc_tree->horizontalb[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001444 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001445 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1446 update_state_supertx(cpi, td, &pc_tree->horizontalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001447 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001448 pmc = &pc_tree->horizontalb_supertx;
1449 break;
1450 case PARTITION_VERT_A:
1451 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
1452 update_state_supertx(cpi, td, &pc_tree->verticala[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001453 bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001454 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col, bsize2);
1455 update_state_supertx(cpi, td, &pc_tree->verticala[1], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001456 mi_col, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001457 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, subsize);
1458 update_state_supertx(cpi, td, &pc_tree->verticala[2], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001459 mi_col + hbs, subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001460 pmc = &pc_tree->verticala_supertx;
1461 break;
1462 case PARTITION_VERT_B:
1463 set_offsets_supertx(cpi, td, tile, mi_row, mi_col, subsize);
1464 update_state_supertx(cpi, td, &pc_tree->verticalb[0], mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001465 subsize, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001466 set_offsets_supertx(cpi, td, tile, mi_row, mi_col + hbs, bsize2);
1467 update_state_supertx(cpi, td, &pc_tree->verticalb[1], mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001468 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001469 set_offsets_supertx(cpi, td, tile, mi_row + hbs, mi_col + hbs, bsize2);
1470 update_state_supertx(cpi, td, &pc_tree->verticalb[2], mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07001471 mi_col + hbs, bsize2, dry_run);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 pmc = &pc_tree->verticalb_supertx;
1473 break;
1474#endif // CONFIG_EXT_PARTITION_TYPES
1475 default: assert(0);
1476 }
1477
1478 for (i = 0; i < MAX_MB_PLANE; ++i) {
1479 if (pmc != NULL) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001480 p[i].coeff = pmc->coeff[i];
1481 p[i].qcoeff = pmc->qcoeff[i];
1482 pd[i].dqcoeff = pmc->dqcoeff[i];
1483 p[i].eobs = pmc->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001484 } else {
1485 // These should never be used
1486 p[i].coeff = NULL;
1487 p[i].qcoeff = NULL;
1488 pd[i].dqcoeff = NULL;
1489 p[i].eobs = NULL;
1490 }
1491 }
1492}
1493
1494static void update_supertx_param(ThreadData *td, PICK_MODE_CONTEXT *ctx,
1495 int best_tx, TX_SIZE supertx_size) {
1496 MACROBLOCK *const x = &td->mb;
1497#if CONFIG_VAR_TX
1498 int i;
1499
1500 for (i = 0; i < 1; ++i)
1501 memcpy(ctx->blk_skip[i], x->blk_skip[i],
1502 sizeof(uint8_t) * ctx->num_4x4_blk);
Jingning Hane67b38a2016-11-04 10:30:00 -07001503 ctx->mic.mbmi.min_tx_size = get_min_tx_size(supertx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504#endif // CONFIG_VAR_TX
1505 ctx->mic.mbmi.tx_size = supertx_size;
1506 ctx->skip = x->skip;
1507 ctx->mic.mbmi.tx_type = best_tx;
1508}
1509
Urvang Joshi52648442016-10-13 17:27:51 -07001510static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
1511 int mi_row, int mi_col, BLOCK_SIZE bsize,
1512 int best_tx, TX_SIZE supertx_size,
1513 PC_TREE *pc_tree) {
1514 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001515 int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
1516 PARTITION_TYPE partition = pc_tree->partitioning;
1517 BLOCK_SIZE subsize = get_subsize(bsize, partition);
1518#if CONFIG_EXT_PARTITION_TYPES
1519 int i;
1520#endif
1521
1522 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
1523
1524 switch (partition) {
1525 case PARTITION_NONE:
1526 update_supertx_param(td, &pc_tree->none, best_tx, supertx_size);
1527 break;
1528 case PARTITION_VERT:
1529 update_supertx_param(td, &pc_tree->vertical[0], best_tx, supertx_size);
1530 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8)
1531 update_supertx_param(td, &pc_tree->vertical[1], best_tx, supertx_size);
1532 break;
1533 case PARTITION_HORZ:
1534 update_supertx_param(td, &pc_tree->horizontal[0], best_tx, supertx_size);
1535 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8)
1536 update_supertx_param(td, &pc_tree->horizontal[1], best_tx,
1537 supertx_size);
1538 break;
1539 case PARTITION_SPLIT:
1540 if (bsize == BLOCK_8X8) {
1541 update_supertx_param(td, pc_tree->leaf_split[0], best_tx, supertx_size);
1542 } else {
1543 update_supertx_param_sb(cpi, td, mi_row, mi_col, subsize, best_tx,
1544 supertx_size, pc_tree->split[0]);
1545 update_supertx_param_sb(cpi, td, mi_row, mi_col + hbs, subsize, best_tx,
1546 supertx_size, pc_tree->split[1]);
1547 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col, subsize, best_tx,
1548 supertx_size, pc_tree->split[2]);
1549 update_supertx_param_sb(cpi, td, mi_row + hbs, mi_col + hbs, subsize,
1550 best_tx, supertx_size, pc_tree->split[3]);
1551 }
1552 break;
1553#if CONFIG_EXT_PARTITION_TYPES
1554 case PARTITION_HORZ_A:
1555 for (i = 0; i < 3; i++)
1556 update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
1557 supertx_size);
1558 break;
1559 case PARTITION_HORZ_B:
1560 for (i = 0; i < 3; i++)
1561 update_supertx_param(td, &pc_tree->horizontalb[i], best_tx,
1562 supertx_size);
1563 break;
1564 case PARTITION_VERT_A:
1565 for (i = 0; i < 3; i++)
1566 update_supertx_param(td, &pc_tree->verticala[i], best_tx, supertx_size);
1567 break;
1568 case PARTITION_VERT_B:
1569 for (i = 0; i < 3; i++)
1570 update_supertx_param(td, &pc_tree->verticalb[i], best_tx, supertx_size);
1571 break;
1572#endif // CONFIG_EXT_PARTITION_TYPES
1573 default: assert(0);
1574 }
1575}
1576#endif // CONFIG_SUPERTX
1577
Yaowu Xuf883b422016-08-30 14:01:10 -07001578void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
1579 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001580 uint8_t *const buffers[3] = { src->y_buffer, src->u_buffer, src->v_buffer };
1581 const int widths[3] = { src->y_crop_width, src->uv_crop_width,
1582 src->uv_crop_width };
1583 const int heights[3] = { src->y_crop_height, src->uv_crop_height,
1584 src->uv_crop_height };
1585 const int strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
1586 int i;
1587
1588 // Set current frame pointer.
1589 x->e_mbd.cur_buf = src;
1590
1591 for (i = 0; i < MAX_MB_PLANE; i++)
1592 setup_pred_plane(&x->plane[i].src, buffers[i], widths[i], heights[i],
1593 strides[i], mi_row, mi_col, NULL,
1594 x->e_mbd.plane[i].subsampling_x,
1595 x->e_mbd.plane[i].subsampling_y);
1596}
1597
Urvang Joshi52648442016-10-13 17:27:51 -07001598static int set_segment_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001599 int8_t segment_id) {
1600 int segment_qindex;
Urvang Joshi52648442016-10-13 17:27:51 -07001601 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuf883b422016-08-30 14:01:10 -07001602 av1_init_plane_quantizers(cpi, x, segment_id);
1603 aom_clear_system_state();
1604 segment_qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
1605 return av1_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001606}
1607
Urvang Joshi52648442016-10-13 17:27:51 -07001608static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001609 MACROBLOCK *const x, int mi_row, int mi_col,
1610 RD_COST *rd_cost,
1611#if CONFIG_SUPERTX
1612 int *totalrate_nocoef,
1613#endif
1614#if CONFIG_EXT_PARTITION_TYPES
1615 PARTITION_TYPE partition,
1616#endif
1617 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
1618 int64_t best_rd) {
Urvang Joshi52648442016-10-13 17:27:51 -07001619 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620 TileInfo *const tile_info = &tile_data->tile_info;
1621 MACROBLOCKD *const xd = &x->e_mbd;
1622 MB_MODE_INFO *mbmi;
1623 struct macroblock_plane *const p = x->plane;
1624 struct macroblockd_plane *const pd = xd->plane;
1625 const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
1626 int i, orig_rdmult;
1627
Yaowu Xuf883b422016-08-30 14:01:10 -07001628 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07001629
1630 // Use the lower precision, but faster, 32x32 fdct for mode selection.
1631 x->use_lp32x32fdct = 1;
1632
Yushin Cho77bba8d2016-11-04 16:36:56 -07001633#if CONFIG_PVQ
1634 x->pvq_speed = 1;
1635 x->pvq_coded = 0;
1636#endif
1637
Yaowu Xuc27fc142016-08-22 16:08:15 -07001638 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
1639 mbmi = &xd->mi[0]->mbmi;
1640 mbmi->sb_type = bsize;
Angie Chiang394c3372016-11-03 11:13:15 -07001641#if CONFIG_RD_DEBUG
1642 mbmi->mi_row = mi_row;
1643 mbmi->mi_col = mi_col;
1644#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001645#if CONFIG_SUPERTX
1646 // We set tx_size here as skip blocks would otherwise not set it.
1647 // tx_size needs to be set at this point as supertx_enable in
1648 // write_modes_sb is computed based on this, and if the garbage in memory
1649 // just happens to be the supertx_size, then the packer will code this
1650 // block as a supertx block, even if rdopt did not pick it as such.
1651 mbmi->tx_size = max_txsize_lookup[bsize];
1652#endif
1653#if CONFIG_EXT_PARTITION_TYPES
1654 mbmi->partition = partition;
1655#endif
1656
1657 for (i = 0; i < MAX_MB_PLANE; ++i) {
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001658 p[i].coeff = ctx->coeff[i];
1659 p[i].qcoeff = ctx->qcoeff[i];
1660 pd[i].dqcoeff = ctx->dqcoeff[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001661#if CONFIG_PVQ
1662 pd[i].pvq_ref_coeff = ctx->pvq_ref_coeff[i];
1663#endif
Brennan Shacklette0b5ae82016-11-07 17:25:20 -08001664 p[i].eobs = ctx->eobs[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001665 }
1666
Urvang Joshib100db72016-10-12 16:28:56 -07001667#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001668 for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
Urvang Joshib100db72016-10-12 16:28:56 -07001669#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001670
Yaowu Xuc27fc142016-08-22 16:08:15 -07001671 ctx->skippable = 0;
1672 ctx->pred_pixel_ready = 0;
1673
1674 // Set to zero to make sure we do not use the previous encoded frame stats
1675 mbmi->skip = 0;
1676
Yaowu Xuf883b422016-08-30 14:01:10 -07001677#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001678 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001679 x->source_variance = av1_high_get_sby_perpixel_variance(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001680 cpi, &x->plane[0].src, bsize, xd->bd);
1681 } else {
1682 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001683 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001684 }
1685#else
1686 x->source_variance =
Yaowu Xuf883b422016-08-30 14:01:10 -07001687 av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
1688#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001689
1690 // Save rdmult before it might be changed, so it can be restored later.
1691 orig_rdmult = x->rdmult;
1692
1693 if (aq_mode == VARIANCE_AQ) {
1694 if (cpi->vaq_refresh) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001695 const int energy =
1696 bsize <= BLOCK_16X16 ? x->mb_energy : av1_block_energy(cpi, x, bsize);
1697 mbmi->segment_id = av1_vaq_segment_id(energy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001698 // Re-initialise quantiser
Yaowu Xuf883b422016-08-30 14:01:10 -07001699 av1_init_plane_quantizers(cpi, x, mbmi->segment_id);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001700 }
1701 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1702 } else if (aq_mode == COMPLEXITY_AQ) {
1703 x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
1704 } else if (aq_mode == CYCLIC_REFRESH_AQ) {
1705 // If segment is boosted, use rdmult for that segment.
1706 if (cyclic_refresh_segment_id_boosted(mbmi->segment_id))
Yaowu Xuf883b422016-08-30 14:01:10 -07001707 x->rdmult = av1_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001708 }
1709
1710 // Find best coding mode & reconstruct the MB so it is available
1711 // as a predictor for MBs that follow in the SB
1712 if (frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001713 av1_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001714#if CONFIG_SUPERTX
1715 *totalrate_nocoef = 0;
1716#endif // CONFIG_SUPERTX
1717 } else {
1718 if (bsize >= BLOCK_8X8) {
1719 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001720 av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
1721 ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001722#if CONFIG_SUPERTX
1723 *totalrate_nocoef = rd_cost->rate;
1724#endif // CONFIG_SUPERTX
1725 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001726 av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001727#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001728 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001729#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001730 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001731#if CONFIG_SUPERTX
1732 assert(*totalrate_nocoef >= 0);
1733#endif // CONFIG_SUPERTX
1734 }
1735 } else {
1736 if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1737 // The decoder rejects sub8x8 partitions when SEG_LVL_SKIP is set.
1738 rd_cost->rate = INT_MAX;
1739 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001740 av1_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
1741 rd_cost,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001742#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001743 totalrate_nocoef,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001744#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -07001745 bsize, ctx, best_rd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001746#if CONFIG_SUPERTX
1747 assert(*totalrate_nocoef >= 0);
1748#endif // CONFIG_SUPERTX
1749 }
1750 }
1751 }
1752
1753 // Examine the resulting rate and for AQ mode 2 make a segment choice.
1754 if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
1755 (bsize >= BLOCK_16X16) &&
1756 (cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
1757 (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001758 av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001759 }
1760
1761 x->rdmult = orig_rdmult;
1762
1763 // TODO(jingning) The rate-distortion optimization flow needs to be
1764 // refactored to provide proper exit/return handle.
1765 if (rd_cost->rate == INT_MAX) rd_cost->rdcost = INT64_MAX;
1766
1767 ctx->rate = rd_cost->rate;
1768 ctx->dist = rd_cost->dist;
1769}
1770
1771#if CONFIG_REF_MV
1772static void update_inter_mode_stats(FRAME_COUNTS *counts, PREDICTION_MODE mode,
1773#if CONFIG_EXT_INTER
1774 int is_compound,
1775#endif // CONFIG_EXT_INTER
1776 int16_t mode_context) {
1777 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
1778#if CONFIG_EXT_INTER
1779 if (mode == NEWMV || mode == NEWFROMNEARMV) {
1780 if (!is_compound) ++counts->new2mv_mode[mode == NEWFROMNEARMV];
1781#else
1782 if (mode == NEWMV) {
1783#endif // CONFIG_EXT_INTER
1784 ++counts->newmv_mode[mode_ctx][0];
1785 return;
1786 } else {
1787 ++counts->newmv_mode[mode_ctx][1];
1788
1789 if (mode_context & (1 << ALL_ZERO_FLAG_OFFSET)) {
1790 return;
1791 }
1792
1793 mode_ctx = (mode_context >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
1794 if (mode == ZEROMV) {
1795 ++counts->zeromv_mode[mode_ctx][0];
1796 return;
1797 } else {
1798 ++counts->zeromv_mode[mode_ctx][1];
1799 mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
1800
1801 if (mode_context & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
1802 if (mode_context & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
1803 if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
1804
1805 ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
1806 }
1807 }
1808}
1809#endif
1810
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001811static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
1812 int mi_col
Yaowu Xuc27fc142016-08-22 16:08:15 -07001813#if CONFIG_SUPERTX
1814 ,
1815 int supertx_enabled
1816#endif
1817 ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01001818#if CONFIG_DELTA_Q
1819 MACROBLOCK *x = &td->mb;
1820 MACROBLOCKD *const xd = &x->e_mbd;
1821#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001822 const MACROBLOCK *x = &td->mb;
1823 const MACROBLOCKD *const xd = &x->e_mbd;
Thomas Daviesf6936102016-09-05 16:51:31 +01001824#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001825 const MODE_INFO *const mi = xd->mi[0];
1826 const MB_MODE_INFO *const mbmi = &mi->mbmi;
1827 const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
1828 const BLOCK_SIZE bsize = mbmi->sb_type;
1829
Thomas Daviesf6936102016-09-05 16:51:31 +01001830#if CONFIG_DELTA_Q
1831 // delta quant applies to both intra and inter
1832 const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
1833
1834 if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
1835 super_block_upper_left) {
1836 const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
1837 const int absdq = abs(dq);
1838 int i;
1839 for (i = 0; i < absdq; ++i) {
1840 td->counts->delta_q[i][1]++;
1841 }
1842 if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
1843 xd->prev_qindex = mbmi->current_q_index;
1844 }
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07001845#else
1846 (void)mi_row;
1847 (void)mi_col;
Thomas Daviesf6936102016-09-05 16:51:31 +01001848#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001849 if (!frame_is_intra_only(cm)) {
1850 FRAME_COUNTS *const counts = td->counts;
1851 const int inter_block = is_inter_block(mbmi);
1852 const int seg_ref_active =
1853 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_REF_FRAME);
1854 if (!seg_ref_active) {
1855#if CONFIG_SUPERTX
1856 if (!supertx_enabled)
1857#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001858 counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 // If the segment reference feature is enabled we have only a single
1860 // reference frame allowed for the segment so exclude it from
1861 // the reference frame counts used to work out probabilities.
1862 if (inter_block) {
1863 const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
1864#if CONFIG_EXT_REFS
1865 const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
1866#endif // CONFIG_EXT_REFS
1867
1868 if (cm->reference_mode == REFERENCE_MODE_SELECT)
clang-format67948d32016-09-07 22:40:40 -07001869 counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
1870 [has_second_ref(mbmi)]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001871
1872 if (has_second_ref(mbmi)) {
1873#if CONFIG_EXT_REFS
1874 const int bit = (ref0 == GOLDEN_FRAME || ref0 == LAST3_FRAME);
1875
Yaowu Xuf883b422016-08-30 14:01:10 -07001876 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877 if (!bit) {
clang-format67948d32016-09-07 22:40:40 -07001878 counts->comp_ref[av1_get_pred_context_comp_ref_p1(cm, xd)][1]
1879 [ref0 == LAST_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_p2(cm, xd)][2]
1882 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 }
1884
clang-format67948d32016-09-07 22:40:40 -07001885 counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
1886 [ref1 == ALTREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001887#else
clang-format67948d32016-09-07 22:40:40 -07001888 counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
1889 [ref0 == GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001890#endif // CONFIG_EXT_REFS
1891 } else {
1892#if CONFIG_EXT_REFS
1893 const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
1894
Yaowu Xuf883b422016-08-30 14:01:10 -07001895 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001896 if (bit) {
clang-format67948d32016-09-07 22:40:40 -07001897 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1898 [ref0 != BWDREF_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899 } else {
1900 const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
clang-format67948d32016-09-07 22:40:40 -07001901 counts->single_ref[av1_get_pred_context_single_ref_p3(xd)][2]
1902 [bit1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 if (!bit1) {
clang-format67948d32016-09-07 22:40:40 -07001904 counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
1905 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001906 } else {
clang-format67948d32016-09-07 22:40:40 -07001907 counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
1908 [ref0 != LAST3_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001909 }
1910 }
1911#else
clang-format67948d32016-09-07 22:40:40 -07001912 counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0]
1913 [ref0 != LAST_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 if (ref0 != LAST_FRAME) {
clang-format67948d32016-09-07 22:40:40 -07001915 counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
1916 [ref0 != GOLDEN_FRAME]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917 }
1918#endif // CONFIG_EXT_REFS
1919 }
1920
1921#if CONFIG_EXT_INTER
1922 if (cm->reference_mode != COMPOUND_REFERENCE &&
1923#if CONFIG_SUPERTX
1924 !supertx_enabled &&
1925#endif
1926 is_interintra_allowed(mbmi)) {
1927 const int bsize_group = size_group_lookup[bsize];
1928 if (mbmi->ref_frame[1] == INTRA_FRAME) {
1929 counts->interintra[bsize_group][1]++;
1930 counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
1931 if (is_interintra_wedge_used(bsize))
1932 counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
1933 } else {
1934 counts->interintra[bsize_group][0]++;
1935 }
1936 }
1937#endif // CONFIG_EXT_INTER
1938
Yue Chencb60b182016-10-13 15:18:22 -07001939#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001940#if CONFIG_SUPERTX
1941 if (!supertx_enabled)
1942#endif // CONFIG_SUPERTX
1943#if CONFIG_EXT_INTER
1944 if (mbmi->ref_frame[1] != INTRA_FRAME)
1945#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001946 if (is_motion_variation_allowed(mbmi))
1947 counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
1948#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949
1950#if CONFIG_EXT_INTER
1951 if (cm->reference_mode != SINGLE_REFERENCE &&
1952 is_inter_compound_mode(mbmi->mode) &&
Yue Chencb60b182016-10-13 15:18:22 -07001953#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
1954 !(is_motion_variation_allowed(mbmi) &&
1955 mbmi->motion_mode != SIMPLE_TRANSLATION) &&
1956#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001957 is_interinter_wedge_used(bsize)) {
Sarah Parker6fddd182016-11-10 20:57:20 -08001958 counts->compound_interinter[bsize][mbmi->interinter_compound]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001959 }
1960#endif // CONFIG_EXT_INTER
1961 }
1962 }
1963
1964 if (inter_block &&
1965 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1966 int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
1967 if (bsize >= BLOCK_8X8) {
1968 const PREDICTION_MODE mode = mbmi->mode;
1969#if CONFIG_REF_MV
1970#if CONFIG_EXT_INTER
1971 if (has_second_ref(mbmi)) {
1972 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
1973 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
1974 } else {
1975#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001976 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
1977 mbmi->ref_frame, bsize, -1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001978 update_inter_mode_stats(counts, mode,
1979#if CONFIG_EXT_INTER
1980 has_second_ref(mbmi),
1981#endif // CONFIG_EXT_INTER
1982 mode_ctx);
1983
1984 if (mode == NEWMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001985 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001986 int idx;
1987
1988 for (idx = 0; idx < 2; ++idx) {
1989 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
1990 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07001991 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001992 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
1993
1994 if (mbmi->ref_mv_idx == idx) break;
1995 }
1996 }
1997 }
1998
1999 if (mode == NEARMV) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002000 uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002001 int idx;
2002
2003 for (idx = 1; idx < 3; ++idx) {
2004 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2005 uint8_t drl_ctx =
Yaowu Xuf883b422016-08-30 14:01:10 -07002006 av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002007 ++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
2008
2009 if (mbmi->ref_mv_idx == idx - 1) break;
2010 }
2011 }
2012 }
2013#if CONFIG_EXT_INTER
2014 }
2015#endif // CONFIG_EXT_INTER
2016#else
2017#if CONFIG_EXT_INTER
2018 if (is_inter_compound_mode(mode))
2019 ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
2020 else
2021#endif // CONFIG_EXT_INTER
2022 ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
2023#endif
2024 } else {
2025 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
2026 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
2027 int idx, idy;
2028 for (idy = 0; idy < 2; idy += num_4x4_h) {
2029 for (idx = 0; idx < 2; idx += num_4x4_w) {
2030 const int j = idy * 2 + idx;
2031 const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
2032#if CONFIG_REF_MV
2033#if CONFIG_EXT_INTER
2034 if (has_second_ref(mbmi)) {
2035 mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
clang-format67948d32016-09-07 22:40:40 -07002036 ++counts->inter_compound_mode[mode_ctx]
2037 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002038 } else {
2039#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002040 mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
2041 mbmi->ref_frame, bsize, j);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002042 update_inter_mode_stats(counts, b_mode,
2043#if CONFIG_EXT_INTER
2044 has_second_ref(mbmi),
2045#endif // CONFIG_EXT_INTER
2046 mode_ctx);
2047#if CONFIG_EXT_INTER
2048 }
2049#endif // CONFIG_EXT_INTER
2050#else
2051#if CONFIG_EXT_INTER
2052 if (is_inter_compound_mode(b_mode))
clang-format67948d32016-09-07 22:40:40 -07002053 ++counts->inter_compound_mode[mode_ctx]
2054 [INTER_COMPOUND_OFFSET(b_mode)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055 else
2056#endif // CONFIG_EXT_INTER
2057 ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
2058#endif
2059 }
2060 }
2061 }
2062 }
2063 }
2064}
2065
2066typedef struct {
2067 ENTROPY_CONTEXT a[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2068 ENTROPY_CONTEXT l[2 * MAX_MIB_SIZE * MAX_MB_PLANE];
2069 PARTITION_CONTEXT sa[MAX_MIB_SIZE];
2070 PARTITION_CONTEXT sl[MAX_MIB_SIZE];
2071#if CONFIG_VAR_TX
2072 TXFM_CONTEXT *p_ta;
2073 TXFM_CONTEXT *p_tl;
2074 TXFM_CONTEXT ta[MAX_MIB_SIZE];
2075 TXFM_CONTEXT tl[MAX_MIB_SIZE];
2076#endif
2077} RD_SEARCH_MACROBLOCK_CONTEXT;
2078
2079static void restore_context(MACROBLOCK *x,
2080 const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002081 int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002082#if CONFIG_PVQ
2083 od_rollback_buffer *rdo_buf,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002084#endif
2085 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086 MACROBLOCKD *xd = &x->e_mbd;
2087 int p;
2088 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2089 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2090 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2091 int mi_height = num_8x8_blocks_high_lookup[bsize];
2092 for (p = 0; p < MAX_MB_PLANE; p++) {
2093 memcpy(xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x),
2094 ctx->a + num_4x4_blocks_wide * p,
2095 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2096 xd->plane[p].subsampling_x);
2097 memcpy(xd->left_context[p] +
2098 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2099 ctx->l + num_4x4_blocks_high * p,
2100 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2101 xd->plane[p].subsampling_y);
2102 }
2103 memcpy(xd->above_seg_context + mi_col, ctx->sa,
2104 sizeof(*xd->above_seg_context) * mi_width);
2105 memcpy(xd->left_seg_context + (mi_row & MAX_MIB_MASK), ctx->sl,
2106 sizeof(xd->left_seg_context[0]) * mi_height);
2107#if CONFIG_VAR_TX
2108 xd->above_txfm_context = ctx->p_ta;
2109 xd->left_txfm_context = ctx->p_tl;
2110 memcpy(xd->above_txfm_context, ctx->ta,
2111 sizeof(*xd->above_txfm_context) * mi_width);
2112 memcpy(xd->left_txfm_context, ctx->tl,
2113 sizeof(*xd->left_txfm_context) * mi_height);
2114#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002115#if CONFIG_PVQ
2116 od_encode_rollback(&x->daala_enc, rdo_buf);
2117#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002118}
2119
2120static void save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002121 int mi_row, int mi_col,
Yushin Cho77bba8d2016-11-04 16:36:56 -07002122#if CONFIG_PVQ
2123 od_rollback_buffer *rdo_buf,
2124#endif
Yaowu Xud6ea71c2016-11-07 10:24:14 -08002125 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002126 const MACROBLOCKD *xd = &x->e_mbd;
2127 int p;
2128 const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
2129 const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
2130 int mi_width = num_8x8_blocks_wide_lookup[bsize];
2131 int mi_height = num_8x8_blocks_high_lookup[bsize];
2132
2133 // buffer the above/left context information of the block in search.
2134 for (p = 0; p < MAX_MB_PLANE; ++p) {
2135 memcpy(ctx->a + num_4x4_blocks_wide * p,
2136 xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x),
2137 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
2138 xd->plane[p].subsampling_x);
2139 memcpy(ctx->l + num_4x4_blocks_high * p,
2140 xd->left_context[p] +
2141 ((mi_row & MAX_MIB_MASK) * 2 >> xd->plane[p].subsampling_y),
2142 (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
2143 xd->plane[p].subsampling_y);
2144 }
2145 memcpy(ctx->sa, xd->above_seg_context + mi_col,
2146 sizeof(*xd->above_seg_context) * mi_width);
2147 memcpy(ctx->sl, xd->left_seg_context + (mi_row & MAX_MIB_MASK),
2148 sizeof(xd->left_seg_context[0]) * mi_height);
2149#if CONFIG_VAR_TX
2150 memcpy(ctx->ta, xd->above_txfm_context,
2151 sizeof(*xd->above_txfm_context) * mi_width);
2152 memcpy(ctx->tl, xd->left_txfm_context,
2153 sizeof(*xd->left_txfm_context) * mi_height);
2154 ctx->p_ta = xd->above_txfm_context;
2155 ctx->p_tl = xd->left_txfm_context;
2156#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002157#if CONFIG_PVQ
2158 od_encode_checkpoint(&x->daala_enc, rdo_buf);
2159#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002160}
2161
Urvang Joshi52648442016-10-13 17:27:51 -07002162static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
2163 ThreadData *td, TOKENEXTRA **tp, int mi_row, int mi_col,
2164 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002165#if CONFIG_EXT_PARTITION_TYPES
2166 PARTITION_TYPE partition,
2167#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002168 PICK_MODE_CONTEXT *ctx, int *rate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002169 MACROBLOCK *const x = &td->mb;
2170 set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
2171#if CONFIG_EXT_PARTITION_TYPES
2172 x->e_mbd.mi[0]->mbmi.partition = partition;
2173#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002174 update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
2175 encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, ctx, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002176
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002177 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002178#if CONFIG_SUPERTX
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002179 update_stats(&cpi->common, td, mi_row, mi_col, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002180#else
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07002181 update_stats(&cpi->common, td, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002182#endif
2183 }
2184}
2185
Urvang Joshi52648442016-10-13 17:27:51 -07002186static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
2187 const TileInfo *const tile, TOKENEXTRA **tp, int mi_row,
2188 int mi_col, RUN_TYPE dry_run, BLOCK_SIZE bsize,
2189 PC_TREE *pc_tree, int *rate) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002190 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002191 MACROBLOCK *const x = &td->mb;
2192 MACROBLOCKD *const xd = &x->e_mbd;
2193
2194 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
2195 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
2196 const PARTITION_TYPE partition = pc_tree->partitioning;
2197 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2198#if CONFIG_EXT_PARTITION_TYPES
2199 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
2200#endif
2201
2202 assert(bsize >= BLOCK_8X8);
2203
2204 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2205
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002206 if (!dry_run) td->counts->partition[ctx][partition]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002207
2208#if CONFIG_SUPERTX
2209 if (!frame_is_intra_only(cm) && bsize <= MAX_SUPERTX_BLOCK_SIZE &&
2210 partition != PARTITION_NONE && !xd->lossless[0]) {
2211 int supertx_enabled;
2212 TX_SIZE supertx_size = max_txsize_lookup[bsize];
2213 supertx_enabled = check_supertx_sb(bsize, supertx_size, pc_tree);
2214 if (supertx_enabled) {
2215 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
2216 const int mi_height = num_8x8_blocks_high_lookup[bsize];
2217 int x_idx, y_idx, i;
2218 uint8_t *dst_buf[3];
2219 int dst_stride[3];
2220 set_skip_context(xd, mi_row, mi_col);
2221 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002222 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, dry_run,
2223 pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002224
Yaowu Xuf883b422016-08-30 14:01:10 -07002225 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002226 for (i = 0; i < MAX_MB_PLANE; i++) {
2227 dst_buf[i] = xd->plane[i].dst.buf;
2228 dst_stride[i] = xd->plane[i].dst.stride;
2229 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002230 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, dry_run,
2231 bsize, bsize, dst_buf, dst_stride, pc_tree);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002232
2233 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
2234 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
2235
2236 if (!x->skip) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002237 int this_rate = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002238 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
2239
Angie Chiangff6d8902016-10-21 11:02:09 -07002240 av1_encode_sb_supertx((AV1_COMMON *)cm, x, bsize);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002241 av1_tokenize_sb_supertx(cpi, td, tp, dry_run, bsize, rate);
2242 if (rate) *rate += this_rate;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002243 } else {
2244 xd->mi[0]->mbmi.skip = 1;
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002245 if (!dry_run) td->counts->skip[av1_get_skip_context(xd)][1]++;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002246 reset_skip_context(xd, bsize);
2247 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002248 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002249 for (y_idx = 0; y_idx < mi_height; y_idx++)
2250 for (x_idx = 0; x_idx < mi_width; x_idx++) {
2251 if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width >
2252 x_idx &&
2253 (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height >
2254 y_idx) {
2255 xd->mi[x_idx + y_idx * cm->mi_stride]->mbmi.skip =
2256 xd->mi[0]->mbmi.skip;
2257 }
2258 }
2259 td->counts->supertx[partition_supertx_context_lookup[partition]]
2260 [supertx_size][1]++;
2261 td->counts->supertx_size[supertx_size]++;
2262#if CONFIG_EXT_TX
2263 if (get_ext_tx_types(supertx_size, bsize, 1) > 1 &&
2264 !xd->mi[0]->mbmi.skip) {
2265 int eset = get_ext_tx_set(supertx_size, bsize, 1);
2266 if (eset > 0) {
clang-format67948d32016-09-07 22:40:40 -07002267 ++td->counts->inter_ext_tx[eset][supertx_size]
2268 [xd->mi[0]->mbmi.tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002269 }
2270 }
2271#else
2272 if (supertx_size < TX_32X32 && !xd->mi[0]->mbmi.skip) {
2273 ++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
2274 }
2275#endif // CONFIG_EXT_TX
2276 }
2277#if CONFIG_EXT_PARTITION_TYPES
2278 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2279 partition);
2280#else
2281 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2282 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2283#endif
2284#if CONFIG_VAR_TX
2285 set_txfm_ctxs(supertx_size, mi_width, mi_height, xd);
2286#endif // CONFIG_VAR_TX
2287 return;
2288 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002289 if (!dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002290 td->counts->supertx[partition_supertx_context_lookup[partition]]
2291 [supertx_size][0]++;
2292 }
2293 }
2294 }
2295#endif // CONFIG_SUPERTX
2296
2297 switch (partition) {
2298 case PARTITION_NONE:
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->none, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304 break;
2305 case PARTITION_VERT:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002306 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002307#if CONFIG_EXT_PARTITION_TYPES
2308 partition,
2309#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002310 &pc_tree->vertical[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002311 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002312 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002313#if CONFIG_EXT_PARTITION_TYPES
2314 partition,
2315#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002316 &pc_tree->vertical[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002317 }
2318 break;
2319 case PARTITION_HORZ:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002320 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002321#if CONFIG_EXT_PARTITION_TYPES
2322 partition,
2323#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002324 &pc_tree->horizontal[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002325 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002326 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002327#if CONFIG_EXT_PARTITION_TYPES
2328 partition,
2329#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002330 &pc_tree->horizontal[1], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331 }
2332 break;
2333 case PARTITION_SPLIT:
2334 if (bsize == BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002335 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002336#if CONFIG_EXT_PARTITION_TYPES
2337 partition,
2338#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002339 pc_tree->leaf_split[0], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002340 } else {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002341 encode_sb(cpi, td, tile, tp, mi_row, mi_col, dry_run, subsize,
2342 pc_tree->split[0], rate);
2343 encode_sb(cpi, td, tile, tp, mi_row, mi_col + hbs, dry_run, subsize,
2344 pc_tree->split[1], rate);
2345 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col, dry_run, subsize,
2346 pc_tree->split[2], rate);
2347 encode_sb(cpi, td, tile, tp, mi_row + hbs, mi_col + hbs, dry_run,
2348 subsize, pc_tree->split[3], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002349 }
2350 break;
2351#if CONFIG_EXT_PARTITION_TYPES
2352 case PARTITION_HORZ_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002353 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2354 &pc_tree->horizontala[0], rate);
2355 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2356 partition, &pc_tree->horizontala[1], rate);
2357 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
2358 partition, &pc_tree->horizontala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002359 break;
2360 case PARTITION_HORZ_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002361 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2362 &pc_tree->horizontalb[0], rate);
2363 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2364 partition, &pc_tree->horizontalb[1], rate);
2365 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2366 partition, &pc_tree->horizontalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002367 break;
2368 case PARTITION_VERT_A:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002369 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
2370 &pc_tree->verticala[0], rate);
2371 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, bsize2,
2372 partition, &pc_tree->verticala[1], rate);
2373 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
2374 partition, &pc_tree->verticala[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002375
2376 break;
2377 case PARTITION_VERT_B:
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002378 encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
2379 &pc_tree->verticalb[0], rate);
2380 encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, bsize2,
2381 partition, &pc_tree->verticalb[1], rate);
2382 encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
2383 partition, &pc_tree->verticalb[2], rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002384 break;
2385#endif // CONFIG_EXT_PARTITION_TYPES
2386 default: assert(0 && "Invalid partition type."); break;
2387 }
2388
2389#if CONFIG_EXT_PARTITION_TYPES
2390 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2391#else
2392 if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
2393 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
2394#endif // CONFIG_EXT_PARTITION_TYPES
2395}
2396
2397// Check to see if the given partition size is allowed for a specified number
2398// of mi block rows and columns remaining in the image.
2399// If not then return the largest allowed partition size
2400static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left,
2401 int cols_left, int *bh, int *bw) {
2402 if (rows_left <= 0 || cols_left <= 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002403 return AOMMIN(bsize, BLOCK_8X8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002404 } else {
2405 for (; bsize > 0; bsize -= 3) {
2406 *bh = num_8x8_blocks_high_lookup[bsize];
2407 *bw = num_8x8_blocks_wide_lookup[bsize];
2408 if ((*bh <= rows_left) && (*bw <= cols_left)) {
2409 break;
2410 }
2411 }
2412 }
2413 return bsize;
2414}
2415
Yaowu Xuf883b422016-08-30 14:01:10 -07002416static void set_partial_sb_partition(const AV1_COMMON *const cm, MODE_INFO *mi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417 int bh_in, int bw_in,
2418 int mi_rows_remaining,
2419 int mi_cols_remaining, BLOCK_SIZE bsize,
2420 MODE_INFO **mib) {
2421 int bh = bh_in;
2422 int r, c;
2423 for (r = 0; r < cm->mib_size; r += bh) {
2424 int bw = bw_in;
2425 for (c = 0; c < cm->mib_size; c += bw) {
2426 const int index = r * cm->mi_stride + c;
2427 mib[index] = mi + index;
2428 mib[index]->mbmi.sb_type = find_partition_size(
2429 bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
2430 }
2431 }
2432}
2433
2434// This function attempts to set all mode info entries in a given superblock
2435// to the same block partition size.
2436// However, at the bottom and right borders of the image the requested size
2437// may not be allowed in which case this code attempts to choose the largest
2438// allowable partition.
Yaowu Xuf883b422016-08-30 14:01:10 -07002439static void set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002440 MODE_INFO **mib, int mi_row, int mi_col,
2441 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002442 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002443 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2444 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2445 int block_row, block_col;
2446 MODE_INFO *const mi_upper_left = cm->mi + mi_row * cm->mi_stride + mi_col;
2447 int bh = num_8x8_blocks_high_lookup[bsize];
2448 int bw = num_8x8_blocks_wide_lookup[bsize];
2449
2450 assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));
2451
2452 // Apply the requested partition size to the SB if it is all "in image"
2453 if ((mi_cols_remaining >= cm->mib_size) &&
2454 (mi_rows_remaining >= cm->mib_size)) {
2455 for (block_row = 0; block_row < cm->mib_size; block_row += bh) {
2456 for (block_col = 0; block_col < cm->mib_size; block_col += bw) {
2457 int index = block_row * cm->mi_stride + block_col;
2458 mib[index] = mi_upper_left + index;
2459 mib[index]->mbmi.sb_type = bsize;
2460 }
2461 }
2462 } else {
2463 // Else this is a partial SB.
2464 set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
2465 mi_cols_remaining, bsize, mib);
2466 }
2467}
2468
Yaowu Xuf883b422016-08-30 14:01:10 -07002469static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002470 TileDataEnc *tile_data, MODE_INFO **mib,
2471 TOKENEXTRA **tp, int mi_row, int mi_col,
2472 BLOCK_SIZE bsize, int *rate, int64_t *dist,
2473#if CONFIG_SUPERTX
2474 int *rate_nocoef,
2475#endif
2476 int do_recon, PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002477 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002478 TileInfo *const tile_info = &tile_data->tile_info;
2479 MACROBLOCK *const x = &td->mb;
2480 MACROBLOCKD *const xd = &x->e_mbd;
2481 const int bs = num_8x8_blocks_wide_lookup[bsize];
2482 const int hbs = bs / 2;
2483 int i;
2484 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
2485 const PARTITION_TYPE partition = get_partition(cm, mi_row, mi_col, bsize);
2486 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
2487 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
2488 RD_COST last_part_rdc, none_rdc, chosen_rdc;
2489 BLOCK_SIZE sub_subsize = BLOCK_4X4;
2490 int splits_below = 0;
2491 BLOCK_SIZE bs_type = mib[0]->mbmi.sb_type;
2492 int do_partition_search = 1;
Urvang Joshi454280d2016-10-14 16:51:44 -07002493 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002494#if CONFIG_SUPERTX
2495 int last_part_rate_nocoef = INT_MAX;
2496 int none_rate_nocoef = INT_MAX;
2497 int chosen_rate_nocoef = INT_MAX;
2498#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002499#if CONFIG_PVQ
2500 od_rollback_buffer pre_rdo_buf;
2501#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002502 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
2503
2504 assert(num_4x4_blocks_wide_lookup[bsize] ==
2505 num_4x4_blocks_high_lookup[bsize]);
2506
Yaowu Xuf883b422016-08-30 14:01:10 -07002507 av1_rd_cost_reset(&last_part_rdc);
2508 av1_rd_cost_reset(&none_rdc);
2509 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510
2511 pc_tree->partitioning = partition;
2512
2513#if CONFIG_VAR_TX
2514 xd->above_txfm_context = cm->above_txfm_context + mi_col;
2515 xd->left_txfm_context =
2516 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
2517#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002518#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002519 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002520#else
2521 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2522#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002523
2524 if (bsize == BLOCK_16X16 && cpi->vaq_refresh) {
2525 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -07002526 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002527 }
2528
2529 if (do_partition_search &&
2530 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2531 cpi->sf.adjust_partitioning_from_last_frame) {
2532 // Check if any of the sub blocks are further split.
2533 if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) {
2534 sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
2535 splits_below = 1;
2536 for (i = 0; i < 4; i++) {
2537 int jj = i >> 1, ii = i & 0x01;
2538 MODE_INFO *this_mi = mib[jj * hbs * cm->mi_stride + ii * hbs];
2539 if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) {
2540 splits_below = 0;
2541 }
2542 }
2543 }
2544
2545 // If partition is not none try none unless each of the 4 splits are split
2546 // even further..
2547 if (partition != PARTITION_NONE && !splits_below &&
2548 mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
2549 pc_tree->partitioning = PARTITION_NONE;
2550 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc,
2551#if CONFIG_SUPERTX
2552 &none_rate_nocoef,
2553#endif
2554#if CONFIG_EXT_PARTITION_TYPES
2555 PARTITION_NONE,
2556#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002557 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558
2559 if (none_rdc.rate < INT_MAX) {
2560 none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2561 none_rdc.rdcost =
2562 RDCOST(x->rdmult, x->rddiv, none_rdc.rate, none_rdc.dist);
2563#if CONFIG_SUPERTX
2564 none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2565#endif
2566 }
2567
Yushin Cho77bba8d2016-11-04 16:36:56 -07002568#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002570#else
2571 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2572#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002573 mib[0]->mbmi.sb_type = bs_type;
2574 pc_tree->partitioning = partition;
2575 }
2576 }
2577
2578 switch (partition) {
2579 case PARTITION_NONE:
2580 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2581#if CONFIG_SUPERTX
2582 &last_part_rate_nocoef,
2583#endif
2584#if CONFIG_EXT_PARTITION_TYPES
2585 PARTITION_NONE,
2586#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002587 bsize, ctx_none, INT64_MAX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 break;
2589 case PARTITION_HORZ:
2590 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2591#if CONFIG_SUPERTX
2592 &last_part_rate_nocoef,
2593#endif
2594#if CONFIG_EXT_PARTITION_TYPES
2595 PARTITION_HORZ,
2596#endif
2597 subsize, &pc_tree->horizontal[0], INT64_MAX);
2598 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2599 mi_row + hbs < cm->mi_rows) {
2600 RD_COST tmp_rdc;
2601#if CONFIG_SUPERTX
2602 int rt_nocoef = 0;
2603#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002604 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002605 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002606 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002607 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002608 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002609 rd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc,
2610#if CONFIG_SUPERTX
2611 &rt_nocoef,
2612#endif
2613#if CONFIG_EXT_PARTITION_TYPES
2614 PARTITION_HORZ,
2615#endif
2616 subsize, &pc_tree->horizontal[1], INT64_MAX);
2617 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002618 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002619#if CONFIG_SUPERTX
2620 last_part_rate_nocoef = INT_MAX;
2621#endif
2622 break;
2623 }
2624 last_part_rdc.rate += tmp_rdc.rate;
2625 last_part_rdc.dist += tmp_rdc.dist;
2626 last_part_rdc.rdcost += tmp_rdc.rdcost;
2627#if CONFIG_SUPERTX
2628 last_part_rate_nocoef += rt_nocoef;
2629#endif
2630 }
2631 break;
2632 case PARTITION_VERT:
2633 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2634#if CONFIG_SUPERTX
2635 &last_part_rate_nocoef,
2636#endif
2637#if CONFIG_EXT_PARTITION_TYPES
2638 PARTITION_VERT,
2639#endif
2640 subsize, &pc_tree->vertical[0], INT64_MAX);
2641 if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
2642 mi_col + hbs < cm->mi_cols) {
2643 RD_COST tmp_rdc;
2644#if CONFIG_SUPERTX
2645 int rt_nocoef = 0;
2646#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07002647 PICK_MODE_CONTEXT *ctx_v = &pc_tree->vertical[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07002648 av1_rd_cost_init(&tmp_rdc);
Urvang Joshi454280d2016-10-14 16:51:44 -07002649 update_state(cpi, td, ctx_v, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002650 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07002651 ctx_v, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002652 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc,
2653#if CONFIG_SUPERTX
2654 &rt_nocoef,
2655#endif
2656#if CONFIG_EXT_PARTITION_TYPES
2657 PARTITION_VERT,
2658#endif
2659 subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
2660 INT64_MAX);
2661 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002662 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002663#if CONFIG_SUPERTX
2664 last_part_rate_nocoef = INT_MAX;
2665#endif
2666 break;
2667 }
2668 last_part_rdc.rate += tmp_rdc.rate;
2669 last_part_rdc.dist += tmp_rdc.dist;
2670 last_part_rdc.rdcost += tmp_rdc.rdcost;
2671#if CONFIG_SUPERTX
2672 last_part_rate_nocoef += rt_nocoef;
2673#endif
2674 }
2675 break;
2676 case PARTITION_SPLIT:
2677 if (bsize == BLOCK_8X8) {
2678 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
2679#if CONFIG_SUPERTX
2680 &last_part_rate_nocoef,
2681#endif
2682#if CONFIG_EXT_PARTITION_TYPES
2683 PARTITION_SPLIT,
2684#endif
2685 subsize, pc_tree->leaf_split[0], INT64_MAX);
2686 break;
2687 }
2688 last_part_rdc.rate = 0;
2689 last_part_rdc.dist = 0;
2690 last_part_rdc.rdcost = 0;
2691#if CONFIG_SUPERTX
2692 last_part_rate_nocoef = 0;
2693#endif
2694 for (i = 0; i < 4; i++) {
2695 int x_idx = (i & 1) * hbs;
2696 int y_idx = (i >> 1) * hbs;
2697 int jj = i >> 1, ii = i & 0x01;
2698 RD_COST tmp_rdc;
2699#if CONFIG_SUPERTX
2700 int rt_nocoef;
2701#endif
2702 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2703 continue;
2704
Yaowu Xuf883b422016-08-30 14:01:10 -07002705 av1_rd_cost_init(&tmp_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002706 rd_use_partition(cpi, td, tile_data,
2707 mib + jj * hbs * cm->mi_stride + ii * hbs, tp,
2708 mi_row + y_idx, mi_col + x_idx, subsize, &tmp_rdc.rate,
2709 &tmp_rdc.dist,
2710#if CONFIG_SUPERTX
2711 &rt_nocoef,
2712#endif
2713 i != 3, pc_tree->split[i]);
2714 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002715 av1_rd_cost_reset(&last_part_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002716#if CONFIG_SUPERTX
2717 last_part_rate_nocoef = INT_MAX;
2718#endif
2719 break;
2720 }
2721 last_part_rdc.rate += tmp_rdc.rate;
2722 last_part_rdc.dist += tmp_rdc.dist;
2723#if CONFIG_SUPERTX
2724 last_part_rate_nocoef += rt_nocoef;
2725#endif
2726 }
2727 break;
2728#if CONFIG_EXT_PARTITION_TYPES
2729 case PARTITION_VERT_A:
2730 case PARTITION_VERT_B:
2731 case PARTITION_HORZ_A:
2732 case PARTITION_HORZ_B: assert(0 && "Cannot handle extended partiton types");
2733#endif // CONFIG_EXT_PARTITION_TYPES
2734 default: assert(0); break;
2735 }
2736
2737 if (last_part_rdc.rate < INT_MAX) {
2738 last_part_rdc.rate += cpi->partition_cost[pl][partition];
2739 last_part_rdc.rdcost =
2740 RDCOST(x->rdmult, x->rddiv, last_part_rdc.rate, last_part_rdc.dist);
2741#if CONFIG_SUPERTX
2742 last_part_rate_nocoef += cpi->partition_cost[pl][partition];
2743#endif
2744 }
2745
2746 if (do_partition_search && cpi->sf.adjust_partitioning_from_last_frame &&
2747 cpi->sf.partition_search_type == SEARCH_PARTITION &&
2748 partition != PARTITION_SPLIT && bsize > BLOCK_8X8 &&
2749 (mi_row + bs < cm->mi_rows || mi_row + hbs == cm->mi_rows) &&
2750 (mi_col + bs < cm->mi_cols || mi_col + hbs == cm->mi_cols)) {
2751 BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
2752 chosen_rdc.rate = 0;
2753 chosen_rdc.dist = 0;
2754#if CONFIG_SUPERTX
2755 chosen_rate_nocoef = 0;
2756#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002757#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002758 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002759#else
2760 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2761#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 pc_tree->partitioning = PARTITION_SPLIT;
2763
2764 // Split partition.
2765 for (i = 0; i < 4; i++) {
2766 int x_idx = (i & 1) * hbs;
2767 int y_idx = (i >> 1) * hbs;
2768 RD_COST tmp_rdc;
2769#if CONFIG_SUPERTX
2770 int rt_nocoef = 0;
2771#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07002772#if CONFIG_PVQ
2773 od_rollback_buffer buf;
2774#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002775 if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
2776 continue;
2777
Yushin Cho77bba8d2016-11-04 16:36:56 -07002778#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002780#else
2781 save_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2782#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002783 pc_tree->split[i]->partitioning = PARTITION_NONE;
2784 rd_pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx,
2785 &tmp_rdc,
2786#if CONFIG_SUPERTX
2787 &rt_nocoef,
2788#endif
2789#if CONFIG_EXT_PARTITION_TYPES
2790 PARTITION_SPLIT,
2791#endif
2792 split_subsize, &pc_tree->split[i]->none, INT64_MAX);
2793
Yushin Cho77bba8d2016-11-04 16:36:56 -07002794#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002795 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002796#else
2797 restore_context(x, &x_ctx, mi_row, mi_col, &buf, bsize);
2798#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002799 if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002800 av1_rd_cost_reset(&chosen_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002801#if CONFIG_SUPERTX
2802 chosen_rate_nocoef = INT_MAX;
2803#endif
2804 break;
2805 }
2806
2807 chosen_rdc.rate += tmp_rdc.rate;
2808 chosen_rdc.dist += tmp_rdc.dist;
2809#if CONFIG_SUPERTX
2810 chosen_rate_nocoef += rt_nocoef;
2811#endif
2812
2813 if (i != 3)
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002814 encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
2815 OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002816
2817 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
2818#if CONFIG_SUPERTX
2819 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
2820#endif
2821 }
2822 if (chosen_rdc.rate < INT_MAX) {
2823 chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
2824 chosen_rdc.rdcost =
2825 RDCOST(x->rdmult, x->rddiv, chosen_rdc.rate, chosen_rdc.dist);
2826#if CONFIG_SUPERTX
2827 chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
2828#endif
2829 }
2830 }
2831
2832 // If last_part is better set the partitioning to that.
2833 if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
2834 mib[0]->mbmi.sb_type = bsize;
2835 if (bsize >= BLOCK_8X8) pc_tree->partitioning = partition;
2836 chosen_rdc = last_part_rdc;
2837#if CONFIG_SUPERTX
2838 chosen_rate_nocoef = last_part_rate_nocoef;
2839#endif
2840 }
2841 // If none was better set the partitioning to that.
2842 if (none_rdc.rdcost < chosen_rdc.rdcost) {
2843 if (bsize >= BLOCK_8X8) pc_tree->partitioning = PARTITION_NONE;
2844 chosen_rdc = none_rdc;
2845#if CONFIG_SUPERTX
2846 chosen_rate_nocoef = none_rate_nocoef;
2847#endif
2848 }
2849
Yushin Cho77bba8d2016-11-04 16:36:56 -07002850#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07002851 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07002852#else
2853 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
2854#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855
2856 // We must have chosen a partitioning and encoding or we'll fail later on.
2857 // No other opportunities for success.
2858 if (bsize == cm->sb_size)
2859 assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
2860
2861 if (do_recon) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07002862 if (bsize == cm->sb_size) {
2863 // NOTE: To get estimate for rate due to the tokens, use:
2864 // int rate_coeffs = 0;
2865 // encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_COSTCOEFFS,
2866 // bsize, pc_tree, &rate_coeffs);
2867 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
2868 pc_tree, NULL);
2869 } else {
2870 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
2871 pc_tree, NULL);
2872 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002873 }
2874
2875 *rate = chosen_rdc.rate;
2876 *dist = chosen_rdc.dist;
2877#if CONFIG_SUPERTX
2878 *rate_nocoef = chosen_rate_nocoef;
2879#endif
2880}
2881
2882/* clang-format off */
2883static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
2884 BLOCK_4X4, // 4x4
2885 BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, // 4x8, 8x4, 8x8
2886 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 8x16, 16x8, 16x16
2887 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 16x32, 32x16, 32x32
2888 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 32x64, 64x32, 64x64
2889#if CONFIG_EXT_PARTITION
2890 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 // 64x128, 128x64, 128x128
2891#endif // CONFIG_EXT_PARTITION
2892};
2893
2894static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
2895 BLOCK_8X8, // 4x4
2896 BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 4x8, 8x4, 8x8
2897 BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, // 8x16, 16x8, 16x16
2898 BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, // 16x32, 32x16, 32x32
2899 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 32x64, 64x32, 64x64
2900#if CONFIG_EXT_PARTITION
2901 BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST // 64x128, 128x64, 128x128
2902#endif // CONFIG_EXT_PARTITION
2903};
2904
2905// Next square block size less or equal than current block size.
2906static const BLOCK_SIZE next_square_size[BLOCK_SIZES] = {
2907 BLOCK_4X4, // 4x4
2908 BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x8, 8x4, 8x8
2909 BLOCK_8X8, BLOCK_8X8, BLOCK_16X16, // 8x16, 16x8, 16x16
2910 BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 16x32, 32x16, 32x32
2911 BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, // 32x64, 64x32, 64x64
2912#if CONFIG_EXT_PARTITION
2913 BLOCK_64X64, BLOCK_64X64, BLOCK_128X128 // 64x128, 128x64, 128x128
2914#endif // CONFIG_EXT_PARTITION
2915};
2916/* clang-format on */
2917
2918// Look at all the mode_info entries for blocks that are part of this
2919// partition and find the min and max values for sb_type.
2920// At the moment this is designed to work on a superblock but could be
2921// adjusted to use a size parameter.
2922//
2923// The min and max are assumed to have been initialized prior to calling this
2924// function so repeat calls can accumulate a min and max of more than one
2925// superblock.
Yaowu Xuf883b422016-08-30 14:01:10 -07002926static void get_sb_partition_size_range(const AV1_COMMON *const cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002927 MACROBLOCKD *xd, MODE_INFO **mib,
2928 BLOCK_SIZE *min_block_size,
2929 BLOCK_SIZE *max_block_size) {
2930 int i, j;
2931 int index = 0;
2932
2933 // Check the sb_type for each block that belongs to this region.
2934 for (i = 0; i < cm->mib_size; ++i) {
2935 for (j = 0; j < cm->mib_size; ++j) {
2936 MODE_INFO *mi = mib[index + j];
2937 BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : BLOCK_4X4;
Yaowu Xuf883b422016-08-30 14:01:10 -07002938 *min_block_size = AOMMIN(*min_block_size, sb_type);
2939 *max_block_size = AOMMAX(*max_block_size, sb_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002940 }
2941 index += xd->mi_stride;
2942 }
2943}
2944
2945// Look at neighboring blocks and set a min and max partition size based on
2946// what they chose.
Yaowu Xuf883b422016-08-30 14:01:10 -07002947static void rd_auto_partition_range(AV1_COMP *cpi, const TileInfo *const tile,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002948 MACROBLOCKD *const xd, int mi_row,
2949 int mi_col, BLOCK_SIZE *min_block_size,
2950 BLOCK_SIZE *max_block_size) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002951 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952 MODE_INFO **mi = xd->mi;
2953 const int left_in_image = xd->left_available && mi[-1];
2954 const int above_in_image = xd->up_available && mi[-xd->mi_stride];
2955 const int mi_rows_remaining = tile->mi_row_end - mi_row;
2956 const int mi_cols_remaining = tile->mi_col_end - mi_col;
2957 int bh, bw;
2958 BLOCK_SIZE min_size = BLOCK_4X4;
2959 BLOCK_SIZE max_size = BLOCK_LARGEST;
2960
2961 // Trap case where we do not have a prediction.
2962 if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
2963 // Default "min to max" and "max to min"
2964 min_size = BLOCK_LARGEST;
2965 max_size = BLOCK_4X4;
2966
2967 // NOTE: each call to get_sb_partition_size_range() uses the previous
2968 // passed in values for min and max as a starting point.
2969 // Find the min and max partition used in previous frame at this location
2970 if (cm->frame_type != KEY_FRAME) {
2971 MODE_INFO **prev_mi =
2972 &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
2973 get_sb_partition_size_range(cm, xd, prev_mi, &min_size, &max_size);
2974 }
2975 // Find the min and max partition sizes used in the left superblock
2976 if (left_in_image) {
2977 MODE_INFO **left_sb_mi = &mi[-cm->mib_size];
2978 get_sb_partition_size_range(cm, xd, left_sb_mi, &min_size, &max_size);
2979 }
2980 // Find the min and max partition sizes used in the above suprblock.
2981 if (above_in_image) {
2982 MODE_INFO **above_sb_mi = &mi[-xd->mi_stride * cm->mib_size];
2983 get_sb_partition_size_range(cm, xd, above_sb_mi, &min_size, &max_size);
2984 }
2985
2986 // Adjust observed min and max for "relaxed" auto partition case.
2987 if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
2988 min_size = min_partition_size[min_size];
2989 max_size = max_partition_size[max_size];
2990 }
2991 }
2992
2993 // Check border cases where max and min from neighbors may not be legal.
2994 max_size = find_partition_size(max_size, mi_rows_remaining, mi_cols_remaining,
2995 &bh, &bw);
Yaowu Xuf883b422016-08-30 14:01:10 -07002996 min_size = AOMMIN(min_size, max_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002997
2998 // Test for blocks at the edge of the active image.
2999 // This may be the actual edge of the image or where there are formatting
3000 // bars.
Yaowu Xuf883b422016-08-30 14:01:10 -07003001 if (av1_active_edge_sb(cpi, mi_row, mi_col)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003002 min_size = BLOCK_4X4;
3003 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003004 min_size = AOMMIN(cpi->sf.rd_auto_partition_min_limit, min_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003005 }
3006
3007 // When use_square_partition_only is true, make sure at least one square
3008 // partition is allowed by selecting the next smaller square size as
3009 // *min_block_size.
3010 if (cpi->sf.use_square_partition_only) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003011 min_size = AOMMIN(min_size, next_square_size[max_size]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003012 }
3013
Yaowu Xuf883b422016-08-30 14:01:10 -07003014 *min_block_size = AOMMIN(min_size, cm->sb_size);
3015 *max_block_size = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016}
3017
3018// TODO(jingning) refactor functions setting partition search range
Urvang Joshi52648442016-10-13 17:27:51 -07003019static void set_partition_range(const AV1_COMMON *const cm,
3020 const MACROBLOCKD *const xd, int mi_row,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003021 int mi_col, BLOCK_SIZE bsize,
Urvang Joshi52648442016-10-13 17:27:51 -07003022 BLOCK_SIZE *const min_bs,
3023 BLOCK_SIZE *const max_bs) {
3024 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
3025 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003026 int idx, idy;
3027
Yaowu Xuc27fc142016-08-22 16:08:15 -07003028 const int idx_str = cm->mi_stride * mi_row + mi_col;
Urvang Joshi52648442016-10-13 17:27:51 -07003029 MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
3030 BLOCK_SIZE min_size = BLOCK_64X64; // default values
3031 BLOCK_SIZE max_size = BLOCK_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003032
3033 if (prev_mi) {
3034 for (idy = 0; idy < mi_height; ++idy) {
3035 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003036 const MODE_INFO *const mi = prev_mi[idy * cm->mi_stride + idx];
3037 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003038 min_size = AOMMIN(min_size, bs);
3039 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003040 }
3041 }
3042 }
3043
3044 if (xd->left_available) {
3045 for (idy = 0; idy < mi_height; ++idy) {
Urvang Joshi52648442016-10-13 17:27:51 -07003046 const MODE_INFO *const mi = xd->mi[idy * cm->mi_stride - 1];
3047 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003048 min_size = AOMMIN(min_size, bs);
3049 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003050 }
3051 }
3052
3053 if (xd->up_available) {
3054 for (idx = 0; idx < mi_width; ++idx) {
Urvang Joshi52648442016-10-13 17:27:51 -07003055 const MODE_INFO *const mi = xd->mi[idx - cm->mi_stride];
3056 const BLOCK_SIZE bs = mi ? mi->mbmi.sb_type : bsize;
Yaowu Xuf883b422016-08-30 14:01:10 -07003057 min_size = AOMMIN(min_size, bs);
3058 max_size = AOMMAX(max_size, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059 }
3060 }
3061
3062 if (min_size == max_size) {
3063 min_size = min_partition_size[min_size];
3064 max_size = max_partition_size[max_size];
3065 }
3066
Yaowu Xuf883b422016-08-30 14:01:10 -07003067 *min_bs = AOMMIN(min_size, cm->sb_size);
3068 *max_bs = AOMMIN(max_size, cm->sb_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069}
3070
3071static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3072 memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv));
3073}
3074
3075static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
3076 memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv));
3077}
3078
3079#if CONFIG_FP_MB_STATS
3080const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
3081 0,
3082 10,
3083 10,
3084 30,
3085 40,
3086 40,
3087 60,
3088 80,
3089 80,
3090 90,
3091 100,
3092 100,
3093 120,
3094#if CONFIG_EXT_PARTITION
3095 // TODO(debargha): What are the correct numbers here?
3096 130,
3097 130,
3098 150
3099#endif // CONFIG_EXT_PARTITION
3100};
3101const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
3102 0,
3103 3,
3104 3,
3105 7,
3106 15,
3107 15,
3108 30,
3109 40,
3110 40,
3111 60,
3112 80,
3113 80,
3114 120,
3115#if CONFIG_EXT_PARTITION
3116 // TODO(debargha): What are the correct numbers here?
3117 160,
3118 160,
3119 240
3120#endif // CONFIG_EXT_PARTITION
3121};
3122const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
3123 1,
3124 1,
3125 1,
3126 1,
3127 1,
3128 1,
3129 1,
3130 1,
3131 1,
3132 1,
3133 4,
3134 4,
3135 6
3136#if CONFIG_EXT_PARTITION
3137 // TODO(debargha): What are the correct numbers here?
3138 8,
3139 8,
3140 10
3141#endif // CONFIG_EXT_PARTITION
3142};
3143
3144typedef enum {
3145 MV_ZERO = 0,
3146 MV_LEFT = 1,
3147 MV_UP = 2,
3148 MV_RIGHT = 3,
3149 MV_DOWN = 4,
3150 MV_INVALID
3151} MOTION_DIRECTION;
3152
3153static INLINE MOTION_DIRECTION get_motion_direction_fp(uint8_t fp_byte) {
3154 if (fp_byte & FPMB_MOTION_ZERO_MASK) {
3155 return MV_ZERO;
3156 } else if (fp_byte & FPMB_MOTION_LEFT_MASK) {
3157 return MV_LEFT;
3158 } else if (fp_byte & FPMB_MOTION_RIGHT_MASK) {
3159 return MV_RIGHT;
3160 } else if (fp_byte & FPMB_MOTION_UP_MASK) {
3161 return MV_UP;
3162 } else {
3163 return MV_DOWN;
3164 }
3165}
3166
3167static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
3168 MOTION_DIRECTION that_mv) {
3169 if (this_mv == that_mv) {
3170 return 0;
3171 } else {
3172 return abs(this_mv - that_mv) == 2 ? 2 : 1;
3173 }
3174}
3175#endif
3176
3177#if CONFIG_EXT_PARTITION_TYPES
3178static void rd_test_partition3(
Urvang Joshi52648442016-10-13 17:27:51 -07003179 const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
3180 TOKENEXTRA **tp, PC_TREE *pc_tree, RD_COST *best_rdc,
3181 PICK_MODE_CONTEXT ctxs[3], PICK_MODE_CONTEXT *ctx, int mi_row, int mi_col,
3182 BLOCK_SIZE bsize, PARTITION_TYPE partition,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003183#if CONFIG_SUPERTX
3184 int64_t best_rd, int *best_rate_nocoef, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
3185#endif
3186 int mi_row0, int mi_col0, BLOCK_SIZE subsize0, int mi_row1, int mi_col1,
3187 BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
3188 MACROBLOCK *const x = &td->mb;
3189 MACROBLOCKD *const xd = &x->e_mbd;
3190 RD_COST this_rdc, sum_rdc;
3191#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003192 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003193 TileInfo *const tile_info = &tile_data->tile_info;
3194 int this_rate_nocoef, sum_rate_nocoef;
3195 int abort_flag;
3196 const int supertx_allowed = !frame_is_intra_only(cm) &&
3197 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3198 !xd->lossless[0];
3199#endif
3200 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
3201
3202 rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
3203#if CONFIG_SUPERTX
3204 &sum_rate_nocoef,
3205#endif
3206#if CONFIG_EXT_PARTITION_TYPES
3207 partition,
3208#endif
3209 subsize0, &ctxs[0], best_rdc->rdcost);
3210#if CONFIG_SUPERTX
3211 abort_flag = sum_rdc.rdcost >= best_rd;
3212#endif
3213
3214#if CONFIG_SUPERTX
3215 if (sum_rdc.rdcost < INT64_MAX) {
3216#else
3217 if (sum_rdc.rdcost < best_rdc->rdcost) {
3218#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003219 PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
3220 update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003221 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003222 ctx_0, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003223
Urvang Joshi368fbc92016-10-17 16:31:34 -07003224 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003225
3226#if CONFIG_SUPERTX
3227 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3228 &this_rate_nocoef,
3229#if CONFIG_EXT_PARTITION_TYPES
3230 partition,
3231#endif
3232 subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
3233#else
3234 rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
3235#if CONFIG_EXT_PARTITION_TYPES
3236 partition,
3237#endif
3238 subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
3239#endif // CONFIG_SUPERTX
3240
3241 if (this_rdc.rate == INT_MAX) {
3242 sum_rdc.rdcost = INT64_MAX;
3243#if CONFIG_SUPERTX
3244 sum_rate_nocoef = INT_MAX;
3245#endif
3246 } else {
3247 sum_rdc.rate += this_rdc.rate;
3248 sum_rdc.dist += this_rdc.dist;
3249 sum_rdc.rdcost += this_rdc.rdcost;
3250#if CONFIG_SUPERTX
3251 sum_rate_nocoef += this_rate_nocoef;
3252#endif
3253 }
3254
3255#if CONFIG_SUPERTX
3256 if (sum_rdc.rdcost < INT64_MAX) {
3257#else
3258 if (sum_rdc.rdcost < best_rdc->rdcost) {
3259#endif
Urvang Joshi368fbc92016-10-17 16:31:34 -07003260 PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
3261 update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003262 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
Urvang Joshi368fbc92016-10-17 16:31:34 -07003263 ctx_1, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003264
Urvang Joshi368fbc92016-10-17 16:31:34 -07003265 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003266
3267#if CONFIG_SUPERTX
3268 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3269 &this_rate_nocoef,
3270#if CONFIG_EXT_PARTITION_TYPES
3271 partition,
3272#endif
3273 subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
3274#else
3275 rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
3276#if CONFIG_EXT_PARTITION_TYPES
3277 partition,
3278#endif
3279 subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
3280#endif // CONFIG_SUPERTX
3281
3282 if (this_rdc.rate == INT_MAX) {
3283 sum_rdc.rdcost = INT64_MAX;
3284#if CONFIG_SUPERTX
3285 sum_rate_nocoef = INT_MAX;
3286#endif
3287 } else {
3288 sum_rdc.rate += this_rdc.rate;
3289 sum_rdc.dist += this_rdc.dist;
3290 sum_rdc.rdcost += this_rdc.rdcost;
3291#if CONFIG_SUPERTX
3292 sum_rate_nocoef += this_rate_nocoef;
3293#endif
3294 }
3295
3296#if CONFIG_SUPERTX
3297 if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
3298 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3299 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3300 pc_tree->partitioning = partition;
Yaowu Xuf883b422016-08-30 14:01:10 -07003301 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003302 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3303 [supertx_size],
3304 0);
3305 sum_rdc.rdcost =
3306 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3307
3308 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3309 TX_TYPE best_tx = DCT_DCT;
3310 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3311
3312 restore_context(x, x_ctx, mi_row, mi_col, bsize);
3313
3314 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3315 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3316
Yaowu Xuf883b422016-08-30 14:01:10 -07003317 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318 cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
3319 [supertx_size],
3320 1);
3321 tmp_rdc.rdcost =
3322 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3323 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3324 sum_rdc = tmp_rdc;
3325 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3326 supertx_size, pc_tree);
3327 }
3328 }
3329
3330 pc_tree->partitioning = best_partition;
3331 }
3332#endif // CONFIG_SUPERTX
3333
3334 if (sum_rdc.rdcost < best_rdc->rdcost) {
3335 int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
3336 sum_rdc.rate += cpi->partition_cost[pl][partition];
3337 sum_rdc.rdcost =
3338 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3339#if CONFIG_SUPERTX
3340 sum_rate_nocoef += cpi->partition_cost[pl][partition];
3341#endif
3342 if (sum_rdc.rdcost < best_rdc->rdcost) {
3343#if CONFIG_SUPERTX
3344 *best_rate_nocoef = sum_rate_nocoef;
3345 assert(*best_rate_nocoef >= 0);
3346#endif
3347 *best_rdc = sum_rdc;
3348 pc_tree->partitioning = partition;
3349 }
3350 }
3351 }
3352 }
3353}
3354#endif // CONFIG_EXT_PARTITION_TYPES
3355
3356// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
3357// unlikely to be selected depending on previous rate-distortion optimization
3358// results, for encoding speed-up.
Urvang Joshi52648442016-10-13 17:27:51 -07003359static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003360 TileDataEnc *tile_data, TOKENEXTRA **tp,
3361 int mi_row, int mi_col, BLOCK_SIZE bsize,
3362 RD_COST *rd_cost,
3363#if CONFIG_SUPERTX
3364 int *rate_nocoef,
3365#endif
3366 int64_t best_rd, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07003367 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003368 TileInfo *const tile_info = &tile_data->tile_info;
3369 MACROBLOCK *const x = &td->mb;
3370 MACROBLOCKD *const xd = &x->e_mbd;
3371 const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
3372 RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
Urvang Joshi52648442016-10-13 17:27:51 -07003373 const TOKENEXTRA *const tp_orig = *tp;
Urvang Joshi454280d2016-10-14 16:51:44 -07003374 PICK_MODE_CONTEXT *ctx_none = &pc_tree->none;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003375 const int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
Urvang Joshi52648442016-10-13 17:27:51 -07003376 const int *partition_cost = cpi->partition_cost[pl];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003377 int tmp_partition_cost[PARTITION_TYPES];
3378 BLOCK_SIZE subsize;
3379 RD_COST this_rdc, sum_rdc, best_rdc;
3380#if CONFIG_SUPERTX
3381 int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
3382 int abort_flag;
3383 const int supertx_allowed = !frame_is_intra_only(cm) &&
3384 bsize <= MAX_SUPERTX_BLOCK_SIZE &&
3385 !xd->lossless[0];
3386#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003387 const int bsize_at_least_8x8 = (bsize >= BLOCK_8X8);
3388 int do_square_split = bsize_at_least_8x8;
3389 int do_rectangular_split = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003390#if CONFIG_EXT_PARTITION_TYPES
3391 BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
3392#endif
3393
3394 // Override skipping rectangular partition operations for edge blocks
3395 const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
3396 const int force_vert_split = (mi_col + mi_step >= cm->mi_cols);
3397 const int xss = x->e_mbd.plane[1].subsampling_x;
3398 const int yss = x->e_mbd.plane[1].subsampling_y;
3399
3400 BLOCK_SIZE min_size = x->min_partition_size;
3401 BLOCK_SIZE max_size = x->max_partition_size;
3402
3403#if CONFIG_FP_MB_STATS
3404 unsigned int src_diff_var = UINT_MAX;
3405 int none_complexity = 0;
3406#endif
3407
3408 int partition_none_allowed = !force_horz_split && !force_vert_split;
3409 int partition_horz_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003410 !force_vert_split && yss <= xss && bsize_at_least_8x8;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003411 int partition_vert_allowed =
Urvang Joshi52648442016-10-13 17:27:51 -07003412 !force_horz_split && xss <= yss && bsize_at_least_8x8;
Yushin Cho77bba8d2016-11-04 16:36:56 -07003413
3414#if CONFIG_PVQ
3415 od_rollback_buffer pre_rdo_buf;
3416#endif
3417
Yaowu Xuc27fc142016-08-22 16:08:15 -07003418 (void)*tp_orig;
3419
3420 if (force_horz_split || force_vert_split) {
3421 tmp_partition_cost[PARTITION_NONE] = INT_MAX;
3422
3423 if (!force_vert_split) { // force_horz_split only
3424 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3425 tmp_partition_cost[PARTITION_HORZ] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003426 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003427 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003428 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_HORZ], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003429 } else if (!force_horz_split) { // force_vert_split only
3430 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3431 tmp_partition_cost[PARTITION_VERT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003432 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003433 tmp_partition_cost[PARTITION_SPLIT] =
Yaowu Xuf883b422016-08-30 14:01:10 -07003434 av1_cost_bit(cm->fc->partition_prob[pl][PARTITION_VERT], 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003435 } else { // force_ horz_split && force_vert_split horz_split
3436 tmp_partition_cost[PARTITION_HORZ] = INT_MAX;
3437 tmp_partition_cost[PARTITION_VERT] = INT_MAX;
3438 tmp_partition_cost[PARTITION_SPLIT] = 0;
3439 }
3440
3441 partition_cost = tmp_partition_cost;
3442 }
3443
3444#if CONFIG_VAR_TX
3445#ifndef NDEBUG
3446 // Nothing should rely on the default value of this array (which is just
3447 // leftover from encoding the previous block. Setting it to magic number
3448 // when debugging.
3449 memset(x->blk_skip[0], 234, sizeof(x->blk_skip[0]));
3450#endif // NDEBUG
3451#endif // CONFIG_VAR_TX
3452
3453 assert(num_8x8_blocks_wide_lookup[bsize] ==
3454 num_8x8_blocks_high_lookup[bsize]);
3455
Yaowu Xuf883b422016-08-30 14:01:10 -07003456 av1_rd_cost_init(&this_rdc);
3457 av1_rd_cost_init(&sum_rdc);
3458 av1_rd_cost_reset(&best_rdc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003459 best_rdc.rdcost = best_rd;
3460
3461 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3462
3463 if (bsize == BLOCK_16X16 && cpi->vaq_refresh)
Yaowu Xuf883b422016-08-30 14:01:10 -07003464 x->mb_energy = av1_block_energy(cpi, x, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003465
3466 if (cpi->sf.cb_partition_search && bsize == BLOCK_16X16) {
Urvang Joshi52648442016-10-13 17:27:51 -07003467 const int cb_partition_search_ctrl =
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468 ((pc_tree->index == 0 || pc_tree->index == 3) +
3469 get_chessboard_index(cm->current_video_frame)) &
3470 0x1;
3471
3472 if (cb_partition_search_ctrl && bsize > min_size && bsize < max_size)
3473 set_partition_range(cm, xd, mi_row, mi_col, bsize, &min_size, &max_size);
3474 }
3475
3476 // Determine partition types in search according to the speed features.
3477 // The threshold set here has to be of square block size.
3478 if (cpi->sf.auto_min_max_partition_size) {
Urvang Joshi52648442016-10-13 17:27:51 -07003479 const int no_partition_allowed = (bsize <= max_size && bsize >= min_size);
3480 // Note: Further partitioning is NOT allowed when bsize == min_size already.
3481 const int partition_allowed = (bsize <= max_size && bsize > min_size);
3482 partition_none_allowed &= no_partition_allowed;
3483 partition_horz_allowed &= partition_allowed || force_horz_split;
3484 partition_vert_allowed &= partition_allowed || force_vert_split;
3485 do_square_split &= bsize > min_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003486 }
3487 if (cpi->sf.use_square_partition_only) {
3488 partition_horz_allowed &= force_horz_split;
3489 partition_vert_allowed &= force_vert_split;
3490 }
3491
3492#if CONFIG_VAR_TX
3493 xd->above_txfm_context = cm->above_txfm_context + mi_col;
3494 xd->left_txfm_context =
3495 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
3496#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07003497#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003498 save_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003499#else
3500 save_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3501#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003502
3503#if CONFIG_FP_MB_STATS
3504 if (cpi->use_fp_mb_stats) {
3505 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3506 src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
3507 mi_col, bsize);
3508 }
3509#endif
3510
3511#if CONFIG_FP_MB_STATS
3512 // Decide whether we shall split directly and skip searching NONE by using
3513 // the first pass block statistics
Urvang Joshi52648442016-10-13 17:27:51 -07003514 if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003515 partition_none_allowed && src_diff_var > 4 &&
3516 cm->base_qindex < qindex_split_threshold_lookup[bsize]) {
3517 int mb_row = mi_row >> 1;
3518 int mb_col = mi_col >> 1;
3519 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003520 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003521 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003522 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003523 int r, c;
3524
3525 // compute a complexity measure, basically measure inconsistency of motion
3526 // vectors obtained from the first pass in the current block
3527 for (r = mb_row; r < mb_row_end; r++) {
3528 for (c = mb_col; c < mb_col_end; c++) {
3529 const int mb_index = r * cm->mb_cols + c;
3530
3531 MOTION_DIRECTION this_mv;
3532 MOTION_DIRECTION right_mv;
3533 MOTION_DIRECTION bottom_mv;
3534
3535 this_mv =
3536 get_motion_direction_fp(cpi->twopass.this_frame_mb_stats[mb_index]);
3537
3538 // to its right
3539 if (c != mb_col_end - 1) {
3540 right_mv = get_motion_direction_fp(
3541 cpi->twopass.this_frame_mb_stats[mb_index + 1]);
3542 none_complexity += get_motion_inconsistency(this_mv, right_mv);
3543 }
3544
3545 // to its bottom
3546 if (r != mb_row_end - 1) {
3547 bottom_mv = get_motion_direction_fp(
3548 cpi->twopass.this_frame_mb_stats[mb_index + cm->mb_cols]);
3549 none_complexity += get_motion_inconsistency(this_mv, bottom_mv);
3550 }
3551
3552 // do not count its left and top neighbors to avoid double counting
3553 }
3554 }
3555
3556 if (none_complexity > complexity_16x16_blocks_threshold[bsize]) {
3557 partition_none_allowed = 0;
3558 }
3559 }
3560#endif
3561
3562 // PARTITION_NONE
3563 if (partition_none_allowed) {
3564 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
3565#if CONFIG_SUPERTX
3566 &this_rate_nocoef,
3567#endif
3568#if CONFIG_EXT_PARTITION_TYPES
3569 PARTITION_NONE,
3570#endif
Urvang Joshi454280d2016-10-14 16:51:44 -07003571 bsize, ctx_none, best_rdc.rdcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003572 if (this_rdc.rate != INT_MAX) {
Urvang Joshi52648442016-10-13 17:27:51 -07003573 if (bsize_at_least_8x8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003574 this_rdc.rate += partition_cost[PARTITION_NONE];
3575 this_rdc.rdcost =
3576 RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
3577#if CONFIG_SUPERTX
3578 this_rate_nocoef += partition_cost[PARTITION_NONE];
3579#endif
3580 }
3581
3582 if (this_rdc.rdcost < best_rdc.rdcost) {
Urvang Joshi52648442016-10-13 17:27:51 -07003583 // Adjust dist breakout threshold according to the partition size.
3584 const int64_t dist_breakout_thr =
3585 cpi->sf.partition_search_breakout_dist_thr >>
3586 ((2 * (MAX_SB_SIZE_LOG2 - 2)) -
3587 (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]));
3588 const int rate_breakout_thr =
3589 cpi->sf.partition_search_breakout_rate_thr *
3590 num_pels_log2_lookup[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003591
3592 best_rdc = this_rdc;
3593#if CONFIG_SUPERTX
3594 best_rate_nocoef = this_rate_nocoef;
3595 assert(best_rate_nocoef >= 0);
3596#endif
Urvang Joshi52648442016-10-13 17:27:51 -07003597 if (bsize_at_least_8x8) pc_tree->partitioning = PARTITION_NONE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003598
3599 // If all y, u, v transform blocks in this partition are skippable, and
3600 // the dist & rate are within the thresholds, the partition search is
3601 // terminated for current branch of the partition search tree.
3602 // The dist & rate thresholds are set to 0 at speed 0 to disable the
3603 // early termination at that speed.
3604 if (!x->e_mbd.lossless[xd->mi[0]->mbmi.segment_id] &&
Urvang Joshi454280d2016-10-14 16:51:44 -07003605 (ctx_none->skippable && best_rdc.dist < dist_breakout_thr &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003606 best_rdc.rate < rate_breakout_thr)) {
Urvang Joshi52648442016-10-13 17:27:51 -07003607 do_square_split = 0;
3608 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003609 }
3610
3611#if CONFIG_FP_MB_STATS
3612 // Check if every 16x16 first pass block statistics has zero
3613 // motion and the corresponding first pass residue is small enough.
3614 // If that is the case, check the difference variance between the
3615 // current frame and the last frame. If the variance is small enough,
3616 // stop further splitting in RD optimization
Urvang Joshi52648442016-10-13 17:27:51 -07003617 if (cpi->use_fp_mb_stats && do_square_split &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003618 cm->base_qindex > qindex_skip_threshold_lookup[bsize]) {
3619 int mb_row = mi_row >> 1;
3620 int mb_col = mi_col >> 1;
3621 int mb_row_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003622 AOMMIN(mb_row + num_16x16_blocks_high_lookup[bsize], cm->mb_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003623 int mb_col_end =
Yaowu Xuf883b422016-08-30 14:01:10 -07003624 AOMMIN(mb_col + num_16x16_blocks_wide_lookup[bsize], cm->mb_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003625 int r, c;
3626
3627 int skip = 1;
3628 for (r = mb_row; r < mb_row_end; r++) {
3629 for (c = mb_col; c < mb_col_end; c++) {
3630 const int mb_index = r * cm->mb_cols + c;
3631 if (!(cpi->twopass.this_frame_mb_stats[mb_index] &
3632 FPMB_MOTION_ZERO_MASK) ||
3633 !(cpi->twopass.this_frame_mb_stats[mb_index] &
3634 FPMB_ERROR_SMALL_MASK)) {
3635 skip = 0;
3636 break;
3637 }
3638 }
3639 if (skip == 0) {
3640 break;
3641 }
3642 }
3643 if (skip) {
3644 if (src_diff_var == UINT_MAX) {
3645 set_offsets(cpi, tile_info, x, mi_row, mi_col, bsize);
3646 src_diff_var = get_sby_perpixel_diff_variance(
3647 cpi, &x->plane[0].src, mi_row, mi_col, bsize);
3648 }
3649 if (src_diff_var < 8) {
Urvang Joshi52648442016-10-13 17:27:51 -07003650 do_square_split = 0;
3651 do_rectangular_split = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003652 }
3653 }
3654 }
3655#endif
3656 }
3657 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003658#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003659 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003660#else
3661 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3662#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003663 }
3664
3665 // store estimated motion vector
Urvang Joshi454280d2016-10-14 16:51:44 -07003666 if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003667
3668 // PARTITION_SPLIT
3669 // TODO(jingning): use the motion vectors given by the above search as
3670 // the starting point of motion search in the following partition type check.
Urvang Joshi52648442016-10-13 17:27:51 -07003671 if (do_square_split) {
3672 int reached_last_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003673 subsize = get_subsize(bsize, PARTITION_SPLIT);
3674 if (bsize == BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003675#if CONFIG_DUAL_FILTER
3676 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3677 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003678 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003679#else
3680 if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
3681 pc_tree->leaf_split[0]->pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003682 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003683#endif
3684#if CONFIG_SUPERTX
3685 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3686 &sum_rate_nocoef,
3687#if CONFIG_EXT_PARTITION_TYPES
3688 PARTITION_SPLIT,
3689#endif
3690 subsize, pc_tree->leaf_split[0], INT64_MAX);
3691#else
3692 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3693#if CONFIG_EXT_PARTITION_TYPES
3694 PARTITION_SPLIT,
3695#endif
3696 subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
3697#endif // CONFIG_SUPERTX
3698 if (sum_rdc.rate == INT_MAX) {
3699 sum_rdc.rdcost = INT64_MAX;
3700#if CONFIG_SUPERTX
3701 sum_rate_nocoef = INT_MAX;
3702#endif
3703 }
3704#if CONFIG_SUPERTX
3705 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX) {
3706 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3707 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3708
3709 pc_tree->partitioning = PARTITION_SPLIT;
3710
clang-format67948d32016-09-07 22:40:40 -07003711 sum_rdc.rate +=
3712 av1_cost_bit(cm->fc->supertx_prob
3713 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3714 [supertx_size],
3715 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003716 sum_rdc.rdcost =
3717 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3718
3719 if (is_inter_mode(pc_tree->leaf_split[0]->mic.mbmi.mode)) {
3720 TX_TYPE best_tx = DCT_DCT;
3721 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3722
3723 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3724
3725 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3726 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3727
Yaowu Xuf883b422016-08-30 14:01:10 -07003728 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003729 cm->fc->supertx_prob
3730 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3731 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003732 1);
3733 tmp_rdc.rdcost =
3734 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3735 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3736 sum_rdc = tmp_rdc;
3737 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3738 supertx_size, pc_tree);
3739 }
3740 }
3741
3742 pc_tree->partitioning = best_partition;
3743 }
3744#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003745 reached_last_index = 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003746 } else {
Urvang Joshi52648442016-10-13 17:27:51 -07003747 int idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003748#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003749 for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003750#else
Urvang Joshi52648442016-10-13 17:27:51 -07003751 for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003753 const int x_idx = (idx & 1) * mi_step;
3754 const int y_idx = (idx >> 1) * mi_step;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003755
3756 if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
3757 continue;
3758
Urvang Joshi454280d2016-10-14 16:51:44 -07003759 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003760
Urvang Joshi52648442016-10-13 17:27:51 -07003761 pc_tree->split[idx]->index = idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003762#if CONFIG_SUPERTX
3763 rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
3764 mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
Urvang Joshi52648442016-10-13 17:27:51 -07003765 INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003766#else
Urvang Joshi52648442016-10-13 17:27:51 -07003767 rd_pick_partition(
3768 cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
3769 &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003770#endif // CONFIG_SUPERTX
3771
3772 if (this_rdc.rate == INT_MAX) {
3773 sum_rdc.rdcost = INT64_MAX;
3774#if CONFIG_SUPERTX
3775 sum_rate_nocoef = INT_MAX;
3776#endif // CONFIG_SUPERTX
3777 break;
3778 } else {
3779 sum_rdc.rate += this_rdc.rate;
3780 sum_rdc.dist += this_rdc.dist;
3781 sum_rdc.rdcost += this_rdc.rdcost;
3782#if CONFIG_SUPERTX
3783 sum_rate_nocoef += this_rate_nocoef;
3784#endif // CONFIG_SUPERTX
3785 }
3786 }
Urvang Joshi52648442016-10-13 17:27:51 -07003787 reached_last_index = (idx == 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788#if CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003789 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && reached_last_index) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003790 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3791 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3792
3793 pc_tree->partitioning = PARTITION_SPLIT;
3794
clang-format67948d32016-09-07 22:40:40 -07003795 sum_rdc.rate +=
3796 av1_cost_bit(cm->fc->supertx_prob
3797 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3798 [supertx_size],
3799 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003800 sum_rdc.rdcost =
3801 RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3802
3803 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3804 TX_TYPE best_tx = DCT_DCT;
3805 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3806
3807 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3808
3809 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
3810 &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
3811
Yaowu Xuf883b422016-08-30 14:01:10 -07003812 tmp_rdc.rate += av1_cost_bit(
clang-format67948d32016-09-07 22:40:40 -07003813 cm->fc->supertx_prob
3814 [partition_supertx_context_lookup[PARTITION_SPLIT]]
3815 [supertx_size],
Yaowu Xuc27fc142016-08-22 16:08:15 -07003816 1);
3817 tmp_rdc.rdcost =
3818 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3819 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3820 sum_rdc = tmp_rdc;
3821 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3822 supertx_size, pc_tree);
3823 }
3824 }
3825
3826 pc_tree->partitioning = best_partition;
3827 }
3828#endif // CONFIG_SUPERTX
3829 }
3830
Urvang Joshi52648442016-10-13 17:27:51 -07003831 if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003832 sum_rdc.rate += partition_cost[PARTITION_SPLIT];
3833 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3834#if CONFIG_SUPERTX
3835 sum_rate_nocoef += partition_cost[PARTITION_SPLIT];
3836#endif // CONFIG_SUPERTX
3837
3838 if (sum_rdc.rdcost < best_rdc.rdcost) {
3839 best_rdc = sum_rdc;
3840#if CONFIG_SUPERTX
3841 best_rate_nocoef = sum_rate_nocoef;
3842 assert(best_rate_nocoef >= 0);
3843#endif // CONFIG_SUPERTX
3844 pc_tree->partitioning = PARTITION_SPLIT;
3845 }
Urvang Joshi52648442016-10-13 17:27:51 -07003846 } else if (cpi->sf.less_rectangular_check) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847 // skip rectangular partition test when larger block size
3848 // gives better rd cost
Urvang Joshi52648442016-10-13 17:27:51 -07003849 do_rectangular_split &= !partition_none_allowed;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003850 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003851#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003852 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003853#else
3854 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3855#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003856 } // if (do_split)
3857
3858 // PARTITION_HORZ
3859 if (partition_horz_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07003860 (do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003861 subsize = get_subsize(bsize, PARTITION_HORZ);
Urvang Joshi454280d2016-10-14 16:51:44 -07003862 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863#if CONFIG_DUAL_FILTER
3864 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3865 partition_none_allowed)
3866 pc_tree->horizontal[0].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003867 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003868#else
3869 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3870 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003871 pc_tree->horizontal[0].pred_interp_filter =
3872 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003873#endif
3874 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
3875#if CONFIG_SUPERTX
3876 &sum_rate_nocoef,
3877#endif // CONFIG_SUPERTX
3878#if CONFIG_EXT_PARTITION_TYPES
3879 PARTITION_HORZ,
3880#endif
3881 subsize, &pc_tree->horizontal[0], best_rdc.rdcost);
3882
3883#if CONFIG_SUPERTX
3884 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
3885 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
3886 if (sum_rdc.rdcost < INT64_MAX &&
3887#else
3888 if (sum_rdc.rdcost < best_rdc.rdcost &&
3889#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07003890 !force_horz_split && bsize > BLOCK_8X8) {
Urvang Joshi454280d2016-10-14 16:51:44 -07003891 PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
3892 update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07003893 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
Urvang Joshi454280d2016-10-14 16:51:44 -07003894 ctx_h, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895
Urvang Joshi454280d2016-10-14 16:51:44 -07003896 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003897
3898#if CONFIG_DUAL_FILTER
3899 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3900 partition_none_allowed)
3901 pc_tree->horizontal[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07003902 ctx_h->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003903#else
3904 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
3905 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07003906 pc_tree->horizontal[1].pred_interp_filter =
3907 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003908#endif
3909#if CONFIG_SUPERTX
3910 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3911 &this_rate_nocoef,
3912#if CONFIG_EXT_PARTITION_TYPES
3913 PARTITION_HORZ,
3914#endif
3915 subsize, &pc_tree->horizontal[1], INT64_MAX);
3916#else
3917 rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
3918#if CONFIG_EXT_PARTITION_TYPES
3919 PARTITION_HORZ,
3920#endif
3921 subsize, &pc_tree->horizontal[1],
3922 best_rdc.rdcost - sum_rdc.rdcost);
3923#endif // CONFIG_SUPERTX
3924 if (this_rdc.rate == INT_MAX) {
3925 sum_rdc.rdcost = INT64_MAX;
3926#if CONFIG_SUPERTX
3927 sum_rate_nocoef = INT_MAX;
3928#endif // CONFIG_SUPERTX
3929 } else {
3930 sum_rdc.rate += this_rdc.rate;
3931 sum_rdc.dist += this_rdc.dist;
3932 sum_rdc.rdcost += this_rdc.rdcost;
3933#if CONFIG_SUPERTX
3934 sum_rate_nocoef += this_rate_nocoef;
3935#endif // CONFIG_SUPERTX
3936 }
3937 }
3938
3939#if CONFIG_SUPERTX
3940 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
3941 TX_SIZE supertx_size = max_txsize_lookup[bsize];
3942 const PARTITION_TYPE best_partition = pc_tree->partitioning;
3943
3944 pc_tree->partitioning = PARTITION_HORZ;
3945
Yaowu Xuf883b422016-08-30 14:01:10 -07003946 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003947 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3948 [supertx_size],
3949 0);
3950 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3951
3952 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
3953 TX_TYPE best_tx = DCT_DCT;
3954 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
3955
3956 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
3957
3958 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
3959 &tmp_rdc.dist, &best_tx, pc_tree);
3960
Yaowu Xuf883b422016-08-30 14:01:10 -07003961 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003962 cm->fc
3963 ->supertx_prob[partition_supertx_context_lookup[PARTITION_HORZ]]
3964 [supertx_size],
3965 1);
3966 tmp_rdc.rdcost =
3967 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
3968 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
3969 sum_rdc = tmp_rdc;
3970 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
3971 supertx_size, pc_tree);
3972 }
3973 }
3974
3975 pc_tree->partitioning = best_partition;
3976 }
3977#endif // CONFIG_SUPERTX
3978
3979 if (sum_rdc.rdcost < best_rdc.rdcost) {
3980 sum_rdc.rate += partition_cost[PARTITION_HORZ];
3981 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
3982#if CONFIG_SUPERTX
3983 sum_rate_nocoef += partition_cost[PARTITION_HORZ];
3984#endif // CONFIG_SUPERTX
3985 if (sum_rdc.rdcost < best_rdc.rdcost) {
3986 best_rdc = sum_rdc;
3987#if CONFIG_SUPERTX
3988 best_rate_nocoef = sum_rate_nocoef;
3989 assert(best_rate_nocoef >= 0);
3990#endif // CONFIG_SUPERTX
3991 pc_tree->partitioning = PARTITION_HORZ;
3992 }
3993 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07003994#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07003995 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07003996#else
3997 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
3998#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003999 }
4000
4001 // PARTITION_VERT
4002 if (partition_vert_allowed &&
Urvang Joshi52648442016-10-13 17:27:51 -07004003 (do_rectangular_split || av1_active_v_edge(cpi, mi_col, mi_step))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004004 subsize = get_subsize(bsize, PARTITION_VERT);
4005
Urvang Joshi454280d2016-10-14 16:51:44 -07004006 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004007
4008#if CONFIG_DUAL_FILTER
4009 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4010 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004011 pc_tree->vertical[0].pred_interp_filter =
4012 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004013#else
4014 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4015 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004016 pc_tree->vertical[0].pred_interp_filter =
4017 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004018#endif
4019 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
4020#if CONFIG_SUPERTX
4021 &sum_rate_nocoef,
4022#endif // CONFIG_SUPERTX
4023#if CONFIG_EXT_PARTITION_TYPES
4024 PARTITION_VERT,
4025#endif
4026 subsize, &pc_tree->vertical[0], best_rdc.rdcost);
4027#if CONFIG_SUPERTX
4028 abort_flag = (sum_rdc.rdcost >= best_rd && bsize > BLOCK_8X8) ||
4029 (sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
4030 if (sum_rdc.rdcost < INT64_MAX &&
4031#else
4032 if (sum_rdc.rdcost < best_rdc.rdcost &&
4033#endif // CONFIG_SUPERTX
Urvang Joshi52648442016-10-13 17:27:51 -07004034 !force_vert_split && bsize > BLOCK_8X8) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004035 update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
4036 encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
4037 &pc_tree->vertical[0], NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004038
Urvang Joshi454280d2016-10-14 16:51:44 -07004039 if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004040
4041#if CONFIG_DUAL_FILTER
4042 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4043 partition_none_allowed)
4044 pc_tree->vertical[1].pred_interp_filter =
Urvang Joshi454280d2016-10-14 16:51:44 -07004045 ctx_none->mic.mbmi.interp_filter[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07004046#else
4047 if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
4048 partition_none_allowed)
Urvang Joshi454280d2016-10-14 16:51:44 -07004049 pc_tree->vertical[1].pred_interp_filter =
4050 ctx_none->mic.mbmi.interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004051#endif
4052#if CONFIG_SUPERTX
4053 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4054 &this_rate_nocoef,
4055#if CONFIG_EXT_PARTITION_TYPES
4056 PARTITION_VERT,
4057#endif
4058 subsize, &pc_tree->vertical[1],
4059 INT64_MAX - sum_rdc.rdcost);
4060#else
4061 rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
4062#if CONFIG_EXT_PARTITION_TYPES
4063 PARTITION_VERT,
4064#endif
4065 subsize, &pc_tree->vertical[1],
4066 best_rdc.rdcost - sum_rdc.rdcost);
4067#endif // CONFIG_SUPERTX
4068 if (this_rdc.rate == INT_MAX) {
4069 sum_rdc.rdcost = INT64_MAX;
4070#if CONFIG_SUPERTX
4071 sum_rate_nocoef = INT_MAX;
4072#endif // CONFIG_SUPERTX
4073 } else {
4074 sum_rdc.rate += this_rdc.rate;
4075 sum_rdc.dist += this_rdc.dist;
4076 sum_rdc.rdcost += this_rdc.rdcost;
4077#if CONFIG_SUPERTX
4078 sum_rate_nocoef += this_rate_nocoef;
4079#endif // CONFIG_SUPERTX
4080 }
4081 }
4082#if CONFIG_SUPERTX
4083 if (supertx_allowed && sum_rdc.rdcost < INT64_MAX && !abort_flag) {
4084 TX_SIZE supertx_size = max_txsize_lookup[bsize];
4085 const PARTITION_TYPE best_partition = pc_tree->partitioning;
4086
4087 pc_tree->partitioning = PARTITION_VERT;
4088
Yaowu Xuf883b422016-08-30 14:01:10 -07004089 sum_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090 cm->fc->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4091 [supertx_size],
4092 0);
4093 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4094
4095 if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
4096 TX_TYPE best_tx = DCT_DCT;
4097 RD_COST tmp_rdc = { sum_rate_nocoef, 0, 0 };
4098
4099 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4100
4101 rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
4102 &tmp_rdc.dist, &best_tx, pc_tree);
4103
Yaowu Xuf883b422016-08-30 14:01:10 -07004104 tmp_rdc.rate += av1_cost_bit(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 cm->fc
4106 ->supertx_prob[partition_supertx_context_lookup[PARTITION_VERT]]
4107 [supertx_size],
4108 1);
4109 tmp_rdc.rdcost =
4110 RDCOST(x->rdmult, x->rddiv, tmp_rdc.rate, tmp_rdc.dist);
4111 if (tmp_rdc.rdcost < sum_rdc.rdcost) {
4112 sum_rdc = tmp_rdc;
4113 update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
4114 supertx_size, pc_tree);
4115 }
4116 }
4117
4118 pc_tree->partitioning = best_partition;
4119 }
4120#endif // CONFIG_SUPERTX
4121
4122 if (sum_rdc.rdcost < best_rdc.rdcost) {
4123 sum_rdc.rate += partition_cost[PARTITION_VERT];
4124 sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
4125#if CONFIG_SUPERTX
4126 sum_rate_nocoef += partition_cost[PARTITION_VERT];
4127#endif // CONFIG_SUPERTX
4128 if (sum_rdc.rdcost < best_rdc.rdcost) {
4129 best_rdc = sum_rdc;
4130#if CONFIG_SUPERTX
4131 best_rate_nocoef = sum_rate_nocoef;
4132 assert(best_rate_nocoef >= 0);
4133#endif // CONFIG_SUPERTX
4134 pc_tree->partitioning = PARTITION_VERT;
4135 }
4136 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004137#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004139#else
4140 restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
4141#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004142 }
4143
4144#if CONFIG_EXT_PARTITION_TYPES
4145 // PARTITION_HORZ_A
Urvang Joshi52648442016-10-13 17:27:51 -07004146 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 partition_none_allowed) {
4148 subsize = get_subsize(bsize, PARTITION_HORZ_A);
4149 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004150 pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151 PARTITION_HORZ_A,
4152#if CONFIG_SUPERTX
4153 best_rd, &best_rate_nocoef, &x_ctx,
4154#endif
4155 mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
4156 mi_row + mi_step, mi_col, subsize);
4157 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4158 }
4159 // PARTITION_HORZ_B
Urvang Joshi52648442016-10-13 17:27:51 -07004160 if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004161 partition_none_allowed) {
4162 subsize = get_subsize(bsize, PARTITION_HORZ_B);
4163 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004164 pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004165 PARTITION_HORZ_B,
4166#if CONFIG_SUPERTX
4167 best_rd, &best_rate_nocoef, &x_ctx,
4168#endif
4169 mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
4170 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4171 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4172 }
4173 // PARTITION_VERT_A
Urvang Joshi52648442016-10-13 17:27:51 -07004174 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004175 partition_none_allowed) {
4176 subsize = get_subsize(bsize, PARTITION_VERT_A);
4177 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004178 pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004179 PARTITION_VERT_A,
4180#if CONFIG_SUPERTX
4181 best_rd, &best_rate_nocoef, &x_ctx,
4182#endif
4183 mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
4184 mi_row, mi_col + mi_step, subsize);
4185 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4186 }
4187 // PARTITION_VERT_B
Urvang Joshi52648442016-10-13 17:27:51 -07004188 if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 partition_none_allowed) {
4190 subsize = get_subsize(bsize, PARTITION_VERT_B);
4191 rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
Urvang Joshi454280d2016-10-14 16:51:44 -07004192 pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004193 PARTITION_VERT_B,
4194#if CONFIG_SUPERTX
4195 best_rd, &best_rate_nocoef, &x_ctx,
4196#endif
4197 mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
4198 bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
4199 restore_context(x, &x_ctx, mi_row, mi_col, bsize);
4200 }
4201#endif // CONFIG_EXT_PARTITION_TYPES
4202
4203 // TODO(jbb): This code added so that we avoid static analysis
4204 // warning related to the fact that best_rd isn't used after this
4205 // point. This code should be refactored so that the duplicate
4206 // checks occur in some sub function and thus are used...
4207 (void)best_rd;
4208 *rd_cost = best_rdc;
4209#if CONFIG_SUPERTX
4210 *rate_nocoef = best_rate_nocoef;
4211#endif // CONFIG_SUPERTX
4212
4213 if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
4214 pc_tree->index != 3) {
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07004215 if (bsize == cm->sb_size) {
4216 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
4217 pc_tree, NULL);
4218 } else {
4219 encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
4220 pc_tree, NULL);
4221 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004222 }
4223
4224 if (bsize == cm->sb_size) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07004225#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226 assert(tp_orig < *tp || (tp_orig == *tp && xd->mi[0]->mbmi.skip));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004227#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228 assert(best_rdc.rate < INT_MAX);
4229 assert(best_rdc.dist < INT64_MAX);
4230 } else {
4231 assert(tp_orig == *tp);
4232 }
4233}
4234
Yaowu Xuf883b422016-08-30 14:01:10 -07004235static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236 TileDataEnc *tile_data, int mi_row,
4237 TOKENEXTRA **tp) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004238 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004239 const TileInfo *const tile_info = &tile_data->tile_info;
4240 MACROBLOCK *const x = &td->mb;
4241 MACROBLOCKD *const xd = &x->e_mbd;
4242 SPEED_FEATURES *const sf = &cpi->sf;
4243 int mi_col;
4244#if CONFIG_EXT_PARTITION
4245 const int leaf_nodes = 256;
4246#else
4247 const int leaf_nodes = 64;
4248#endif // CONFIG_EXT_PARTITION
4249
4250 // Initialize the left context for the new SB row
Yaowu Xuf883b422016-08-30 14:01:10 -07004251 av1_zero_left_context(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004252
Thomas Daviesf6936102016-09-05 16:51:31 +01004253#if CONFIG_DELTA_Q
4254 // Reset delta for every tile
4255 if (cm->delta_q_present_flag)
4256 if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
4257#endif
4258
Yaowu Xuc27fc142016-08-22 16:08:15 -07004259 // Code each SB in the row
4260 for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
4261 mi_col += cm->mib_size) {
4262 const struct segmentation *const seg = &cm->seg;
4263 int dummy_rate;
4264 int64_t dummy_dist;
4265 RD_COST dummy_rdc;
4266#if CONFIG_SUPERTX
4267 int dummy_rate_nocoef;
4268#endif // CONFIG_SUPERTX
4269 int i;
4270 int seg_skip = 0;
4271
4272 const int idx_str = cm->mi_stride * mi_row + mi_col;
4273 MODE_INFO **mi = cm->mi_grid_visible + idx_str;
4274 PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
4275
4276 if (sf->adaptive_pred_interp_filter) {
4277 for (i = 0; i < leaf_nodes; ++i)
4278 td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
4279
4280 for (i = 0; i < leaf_nodes; ++i) {
4281 td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
4282 td->pc_tree[i].vertical[1].pred_interp_filter = SWITCHABLE;
4283 td->pc_tree[i].horizontal[0].pred_interp_filter = SWITCHABLE;
4284 td->pc_tree[i].horizontal[1].pred_interp_filter = SWITCHABLE;
4285 }
4286 }
4287
Yaowu Xuf883b422016-08-30 14:01:10 -07004288 av1_zero(x->pred_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004289 pc_root->index = 0;
4290
4291 if (seg->enabled) {
4292 const uint8_t *const map =
4293 seg->update_map ? cpi->segmentation_map : cm->last_frame_seg_map;
4294 int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
4295 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
4296 }
4297
Arild Fuldseth07441162016-08-15 15:07:52 +02004298#if CONFIG_DELTA_Q
4299 if (cpi->oxcf.aq_mode == DELTA_AQ) {
Thomas Daviesf6936102016-09-05 16:51:31 +01004300 // Test mode for delta quantization
Arild Fuldseth07441162016-08-15 15:07:52 +02004301 int sb_row = mi_row >> 3;
4302 int sb_col = mi_col >> 3;
4303 int sb_stride = (cm->width + MAX_SB_SIZE - 1) >> MAX_SB_SIZE_LOG2;
4304 int index = ((sb_row * sb_stride + sb_col + 8) & 31) - 16;
Thomas Daviesf6936102016-09-05 16:51:31 +01004305
4306 // Ensure divisibility of delta_qindex by delta_q_res
4307 int offset_qindex = (index < 0 ? -index - 8 : index - 8);
4308 int qmask = ~(cm->delta_q_res - 1);
4309 int current_qindex = clamp(cm->base_qindex + offset_qindex,
4310 cm->delta_q_res, 256 - cm->delta_q_res);
4311 current_qindex =
4312 ((current_qindex - cm->base_qindex + cm->delta_q_res / 2) & qmask) +
4313 cm->base_qindex;
4314
Arild Fuldseth07441162016-08-15 15:07:52 +02004315 xd->delta_qindex = current_qindex - cm->base_qindex;
4316 set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
4317 xd->mi[0]->mbmi.current_q_index = current_qindex;
4318 xd->mi[0]->mbmi.segment_id = 0;
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07004319 av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
Arild Fuldseth07441162016-08-15 15:07:52 +02004320 }
4321#endif
4322
Yaowu Xuc27fc142016-08-22 16:08:15 -07004323 x->source_variance = UINT_MAX;
4324 if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
4325 BLOCK_SIZE bsize;
4326 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4327 bsize = seg_skip ? cm->sb_size : sf->always_this_block_size;
4328 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4329 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4330 &dummy_rate, &dummy_dist,
4331#if CONFIG_SUPERTX
4332 &dummy_rate_nocoef,
4333#endif // CONFIG_SUPERTX
4334 1, pc_root);
4335 } else if (cpi->partition_search_skippable_frame) {
4336 BLOCK_SIZE bsize;
4337 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4338 bsize = get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
4339 set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
4340 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4341 &dummy_rate, &dummy_dist,
4342#if CONFIG_SUPERTX
4343 &dummy_rate_nocoef,
4344#endif // CONFIG_SUPERTX
4345 1, pc_root);
4346 } else if (sf->partition_search_type == VAR_BASED_PARTITION) {
4347 choose_partitioning(cpi, td, tile_info, x, mi_row, mi_col);
4348 rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, cm->sb_size,
4349 &dummy_rate, &dummy_dist,
4350#if CONFIG_SUPERTX
4351 &dummy_rate_nocoef,
4352#endif // CONFIG_SUPERTX
4353 1, pc_root);
4354 } else {
4355 // If required set upper and lower partition size limits
4356 if (sf->auto_min_max_partition_size) {
4357 set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
4358 rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
4359 &x->min_partition_size, &x->max_partition_size);
4360 }
4361 rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
4362 &dummy_rdc,
4363#if CONFIG_SUPERTX
4364 &dummy_rate_nocoef,
4365#endif // CONFIG_SUPERTX
4366 INT64_MAX, pc_root);
4367 }
4368 }
4369#if CONFIG_ENTROPY
4370 if (cm->do_subframe_update &&
4371 cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4372 if ((mi_row + MI_SIZE) %
4373 (MI_SIZE *
Yaowu Xuf883b422016-08-30 14:01:10 -07004374 AOMMAX(cm->mi_rows / MI_SIZE / COEF_PROBS_BUFS, 1)) ==
Yaowu Xuc27fc142016-08-22 16:08:15 -07004375 0 &&
4376 mi_row + MI_SIZE < cm->mi_rows &&
4377 cm->coef_probs_update_idx < COEF_PROBS_BUFS - 1) {
4378 TX_SIZE t;
4379 SUBFRAME_STATS *subframe_stats = &cpi->subframe_stats;
4380
4381 for (t = TX_4X4; t <= TX_32X32; ++t)
Yaowu Xuf883b422016-08-30 14:01:10 -07004382 av1_full_to_model_counts(cpi->td.counts->coef[t],
4383 cpi->td.rd_counts.coef_counts[t]);
4384 av1_partial_adapt_probs(cm, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004385 ++cm->coef_probs_update_idx;
Yaowu Xuf883b422016-08-30 14:01:10 -07004386 av1_copy(subframe_stats->coef_probs_buf[cm->coef_probs_update_idx],
4387 cm->fc->coef_probs);
4388 av1_copy(subframe_stats->coef_counts_buf[cm->coef_probs_update_idx],
4389 cpi->td.rd_counts.coef_counts);
4390 av1_copy(subframe_stats->eob_counts_buf[cm->coef_probs_update_idx],
4391 cm->counts.eob_branch);
Alex Converseccf472b2016-10-12 13:03:55 -07004392 av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004393 }
4394 }
4395#endif // CONFIG_ENTROPY
4396}
4397
Yaowu Xuf883b422016-08-30 14:01:10 -07004398static void init_encode_frame_mb_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004399 MACROBLOCK *const x = &cpi->td.mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004400 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004401 MACROBLOCKD *const xd = &x->e_mbd;
4402
4403 // Copy data over into macro block data structures.
Yaowu Xuf883b422016-08-30 14:01:10 -07004404 av1_setup_src_planes(x, cpi->Source, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004405
Yaowu Xuf883b422016-08-30 14:01:10 -07004406 av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004407}
4408
Yaowu Xuf883b422016-08-30 14:01:10 -07004409static int check_dual_ref_flags(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004410 const int ref_flags = cpi->ref_frame_flags;
4411
4412 if (segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) {
4413 return 0;
4414 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004415 return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004416#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004417 !!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
4418 !!(ref_flags & AOM_BWD_FLAG) +
Yaowu Xuc27fc142016-08-22 16:08:15 -07004419#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004420 !!(ref_flags & AOM_ALT_FLAG)) >= 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004421 }
4422}
4423
4424#if !CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -07004425static void reset_skip_tx_size(AV1_COMMON *cm, TX_SIZE max_tx_size) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004426 int mi_row, mi_col;
4427 const int mis = cm->mi_stride;
4428 MODE_INFO **mi_ptr = cm->mi_grid_visible;
4429
4430 for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) {
4431 for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) {
4432 if (txsize_sqr_up_map[mi_ptr[mi_col]->mbmi.tx_size] > max_tx_size)
4433 mi_ptr[mi_col]->mbmi.tx_size = max_tx_size;
4434 }
4435 }
4436}
4437#endif
4438
Yaowu Xuf883b422016-08-30 14:01:10 -07004439static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004440 if (frame_is_intra_only(&cpi->common)) return INTRA_FRAME;
4441#if CONFIG_EXT_REFS
4442 // We will not update the golden frame with an internal overlay frame
4443 else if ((cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) ||
4444 cpi->rc.is_src_frame_ext_arf)
4445#else
4446 else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
4447#endif
4448 return ALTREF_FRAME;
4449 else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
4450 return GOLDEN_FRAME;
4451 else
4452 // TODO(zoeliu): To investigate whether a frame_type other than
4453 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4454 return LAST_FRAME;
4455}
4456
Yaowu Xuf883b422016-08-30 14:01:10 -07004457static TX_MODE select_tx_mode(const AV1_COMP *cpi, MACROBLOCKD *const xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004458 if (xd->lossless[0]) return ONLY_4X4;
4459 if (cpi->sf.tx_size_search_method == USE_LARGESTALL)
4460 return ALLOW_32X32;
4461 else if (cpi->sf.tx_size_search_method == USE_FULL_RD ||
4462 cpi->sf.tx_size_search_method == USE_TX_8X8)
4463 return TX_MODE_SELECT;
4464 else
4465 return cpi->common.tx_mode;
4466}
4467
Yaowu Xuf883b422016-08-30 14:01:10 -07004468void av1_init_tile_data(AV1_COMP *cpi) {
4469 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004470 const int tile_cols = cm->tile_cols;
4471 const int tile_rows = cm->tile_rows;
4472 int tile_col, tile_row;
4473 TOKENEXTRA *pre_tok = cpi->tile_tok[0][0];
4474 unsigned int tile_tok = 0;
4475
4476 if (cpi->tile_data == NULL || cpi->allocated_tiles < tile_cols * tile_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004477 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
4478 CHECK_MEM_ERROR(cm, cpi->tile_data, aom_malloc(tile_cols * tile_rows *
Yaowu Xuc27fc142016-08-22 16:08:15 -07004479 sizeof(*cpi->tile_data)));
4480 cpi->allocated_tiles = tile_cols * tile_rows;
4481
4482 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
4483 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4484 TileDataEnc *const tile_data =
4485 &cpi->tile_data[tile_row * tile_cols + tile_col];
4486 int i, j;
4487 for (i = 0; i < BLOCK_SIZES; ++i) {
4488 for (j = 0; j < MAX_MODES; ++j) {
4489 tile_data->thresh_freq_fact[i][j] = 32;
4490 tile_data->mode_map[i][j] = j;
4491 }
4492 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07004493#if CONFIG_PVQ
4494 // This will be dynamically increased as more pvq block is encoded.
4495 tile_data->pvq_q.buf_len = 1000;
Yaowu Xud6ea71c2016-11-07 10:24:14 -08004496 CHECK_MEM_ERROR(
4497 cm, tile_data->pvq_q.buf,
4498 aom_malloc(tile_data->pvq_q.buf_len * sizeof(PVQ_INFO)));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004499 tile_data->pvq_q.curr_pos = 0;
4500#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004501 }
4502 }
4503
4504 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4505 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
4506 TileInfo *const tile_info =
4507 &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
Yaowu Xuf883b422016-08-30 14:01:10 -07004508 av1_tile_init(tile_info, cm, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509
4510 cpi->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
4511 pre_tok = cpi->tile_tok[tile_row][tile_col];
4512 tile_tok = allocated_tokens(*tile_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07004513#if CONFIG_PVQ
4514 cpi->tile_data[tile_row * tile_cols + tile_col].pvq_q.curr_pos = 0;
4515#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004516 }
4517 }
4518}
4519
Yaowu Xuf883b422016-08-30 14:01:10 -07004520void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
4521 int tile_col) {
4522 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004523 TileDataEnc *const this_tile =
4524 &cpi->tile_data[tile_row * cm->tile_cols + tile_col];
4525 const TileInfo *const tile_info = &this_tile->tile_info;
4526 TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
4527 int mi_row;
Yushin Cho77bba8d2016-11-04 16:36:56 -07004528#if CONFIG_PVQ
4529 od_adapt_ctx *adapt;
4530#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004531
Yaowu Xuf883b422016-08-30 14:01:10 -07004532 av1_zero_above_context(cm, tile_info->mi_col_start, tile_info->mi_col_end);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004533
4534 // Set up pointers to per thread motion search counters.
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07004535 this_tile->m_search_count = 0; // Count of motion search hits.
4536 this_tile->ex_search_count = 0; // Exhaustive mesh search hits.
4537 td->mb.m_search_count_ptr = &this_tile->m_search_count;
4538 td->mb.ex_search_count_ptr = &this_tile->ex_search_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004539
Yushin Cho77bba8d2016-11-04 16:36:56 -07004540#if CONFIG_PVQ
4541 td->mb.pvq_q = &this_tile->pvq_q;
4542
4543 // TODO(yushin)
4544 // If activity masking is enabled, change below to OD_HVS_QM
4545 td->mb.daala_enc.qm = OD_FLAT_QM; // Hard coded. Enc/dec required to sync.
4546 {
4547 // FIXME: Multiple segments support
4548 int segment_id = 0;
4549 int rdmult = set_segment_rdmult(cpi, &td->mb, segment_id);
4550 int qindex = av1_get_qindex(&cm->seg, segment_id, cm->base_qindex);
4551 int64_t q_ac = av1_ac_quant(qindex, 0, cpi->common.bit_depth);
4552 int64_t q_dc = av1_dc_quant(qindex, 0, cpi->common.bit_depth);
4553 /* td->mb.daala_enc.pvq_norm_lambda = OD_PVQ_LAMBDA; */
4554 td->mb.daala_enc.pvq_norm_lambda =
4555 (double)rdmult * (64 / 16) / (q_ac * q_ac * (1 << RDDIV_BITS));
4556 td->mb.daala_enc.pvq_norm_lambda_dc =
4557 (double)rdmult * (64 / 16) / (q_dc * q_dc * (1 << RDDIV_BITS));
4558 // printf("%f\n", td->mb.daala_enc.pvq_norm_lambda);
4559 }
4560 od_init_qm(td->mb.daala_enc.state.qm, td->mb.daala_enc.state.qm_inv,
4561 td->mb.daala_enc.qm == OD_HVS_QM ? OD_QM8_Q4_HVS : OD_QM8_Q4_FLAT);
4562 od_ec_enc_init(&td->mb.daala_enc.ec, 65025);
4563
4564 adapt = &td->mb.daala_enc.state.adapt;
4565 od_ec_enc_reset(&td->mb.daala_enc.ec);
4566 od_adapt_ctx_reset(adapt, 0);
4567#endif
4568
Yaowu Xuc27fc142016-08-22 16:08:15 -07004569 for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
4570 mi_row += cm->mib_size) {
4571 encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
4572 }
4573
4574 cpi->tok_count[tile_row][tile_col] =
4575 (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
4576 assert(cpi->tok_count[tile_row][tile_col] <= allocated_tokens(*tile_info));
Yushin Cho77bba8d2016-11-04 16:36:56 -07004577#if CONFIG_PVQ
4578 od_ec_enc_clear(&td->mb.daala_enc.ec);
4579
4580 td->mb.pvq_q->last_pos = td->mb.pvq_q->curr_pos;
4581 // rewind current position so that bitstream can be written
4582 // from the 1st pvq block
4583 td->mb.pvq_q->curr_pos = 0;
4584
4585 td->mb.pvq_q = NULL;
4586#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004587}
4588
Yaowu Xuf883b422016-08-30 14:01:10 -07004589static void encode_tiles(AV1_COMP *cpi) {
4590 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004591 int tile_col, tile_row;
4592
Yaowu Xuf883b422016-08-30 14:01:10 -07004593 av1_init_tile_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004594
4595 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row)
4596 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col)
Yaowu Xuf883b422016-08-30 14:01:10 -07004597 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004598}
4599
4600#if CONFIG_FP_MB_STATS
4601static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07004602 AV1_COMMON *cm, uint8_t **this_frame_mb_stats) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004603 uint8_t *mb_stats_in = firstpass_mb_stats->mb_stats_start +
4604 cm->current_video_frame * cm->MBs * sizeof(uint8_t);
4605
4606 if (mb_stats_in > firstpass_mb_stats->mb_stats_end) return EOF;
4607
4608 *this_frame_mb_stats = mb_stats_in;
4609
4610 return 1;
4611}
4612#endif
4613
4614#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004615#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
David Barkerf4909db2016-11-11 16:58:36 +00004616#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.75
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004617
4618// Adds some offset to a global motion parameter and handles
4619// all of the necessary precision shifts, clamping, and
4620// zero-centering.
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004621static int32_t add_param_offset(int param_index, int32_t param_value,
4622 int32_t offset) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004623 const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
4624 GM_ROW3HOMO_PREC_DIFF };
4625 const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
4626 // type of param: 0 - translation, 1 - affine, 2 - homography
4627 const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
4628 const int is_one_centered = (param_index == 2 || param_index == 5);
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004629
4630 // Make parameter zero-centered and offset the shift that was done to make
4631 // it compatible with the warped model
4632 param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004633 scale_vals[param_type];
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004634 // Add desired offset to the rescaled/zero-centered parameter
4635 param_value += offset;
4636 // Clamp the parameter so it does not overflow the number of bits allotted
4637 // to it in the bitstream
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004638 param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
4639 clamp_vals[param_type]);
Sarah Parkerb3dab492016-10-26 11:45:50 -07004640 // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004641 // with the warped motion library
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004642 param_value *= (1 << scale_vals[param_type]);
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004643
Sarah Parkerb3dab492016-10-26 11:45:50 -07004644 // Undo the zero-centering step if necessary
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004645 return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
4646}
4647
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004648static void refine_integerized_param(WarpedMotionParams *wm,
4649#if CONFIG_AOM_HIGHBITDEPTH
4650 int use_hbd, int bd,
4651#endif // CONFIG_AOM_HIGHBITDEPTH
4652 uint8_t *ref, int r_width, int r_height,
4653 int r_stride, uint8_t *dst, int d_width,
4654 int d_height, int d_stride,
4655 int n_refinements) {
4656 int i = 0, p;
4657 int n_params = n_trans_model_params[wm->wmtype];
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004658 int32_t *param_mat = wm->wmmat;
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004659 double step_error;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004660 int32_t step;
4661 int32_t *param;
4662 int32_t curr_param;
4663 int32_t best_param;
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004664
4665 double best_error =
4666 av1_warp_erroradv(wm,
4667#if CONFIG_AOM_HIGHBITDEPTH
4668 use_hbd, bd,
4669#endif // CONFIG_AOM_HIGHBITDEPTH
4670 ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
4671 d_height, d_stride, 0, 0, 16, 16);
4672 for (p = 0; p < n_params; ++p) {
4673 param = param_mat + p;
4674 step = 1 << (n_refinements + 1);
4675 curr_param = *param;
4676 best_param = curr_param;
4677 for (i = 0; i < n_refinements; i++) {
4678 // look to the left
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004679 *param = add_param_offset(p, curr_param, -step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004680 step_error =
4681 av1_warp_erroradv(wm,
4682#if CONFIG_AOM_HIGHBITDEPTH
4683 use_hbd, bd,
4684#endif // CONFIG_AOM_HIGHBITDEPTH
4685 ref, r_width, r_height, r_stride, dst, 0, 0,
4686 d_width, d_height, d_stride, 0, 0, 16, 16);
4687 if (step_error < best_error) {
4688 step >>= 1;
4689 best_error = step_error;
4690 best_param = *param;
4691 curr_param = best_param;
4692 continue;
4693 }
4694
4695 // look to the right
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004696 *param = add_param_offset(p, curr_param, step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004697 step_error =
4698 av1_warp_erroradv(wm,
4699#if CONFIG_AOM_HIGHBITDEPTH
4700 use_hbd, bd,
4701#endif // CONFIG_AOM_HIGHBITDEPTH
4702 ref, r_width, r_height, r_stride, dst, 0, 0,
4703 d_width, d_height, d_stride, 0, 0, 16, 16);
4704 if (step_error < best_error) {
4705 step >>= 1;
4706 best_error = step_error;
4707 best_param = *param;
4708 curr_param = best_param;
4709 continue;
4710 }
4711
4712 // no improvement found-> means we're either already at a minimum or
4713 // step is too wide
4714 step >>= 1;
4715 }
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004716 *param = best_param;
4717 }
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004718 // For rotzoom model enforce the constraints on mat[4] and mat[5]
4719 if (wm->wmtype == ROTZOOM) {
4720 param_mat[5] = param_mat[2];
4721 param_mat[4] = -param_mat[3];
4722 }
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004723}
4724
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004725static void convert_to_params(const double *params, int32_t *model) {
4726 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004727 int alpha_present = 0;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004728 model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4729 model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4730 model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004731 GM_TRANS_DECODE_FACTOR;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004732 model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004733 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004734
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004735 for (i = 2; i < 6; ++i) {
4736 const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004737 model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004738 model[i] =
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004739 (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
4740 alpha_present |= (model[i] != 0);
4741 model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
4742 }
4743 for (; i < 8; ++i) {
4744 model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
4745 model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
4746 GM_ROW3HOMO_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004747 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004748 }
4749
4750 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004751 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4752 model[0] = 0;
4753 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004754 }
4755 }
4756}
4757
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004758static void convert_model_to_params(const double *params,
David Barkercf3d0b02016-11-10 10:14:49 +00004759 WarpedMotionParams *model) {
4760 convert_to_params(params, model->wmmat);
4761 model->wmtype = get_gmtype(model);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762}
4763#endif // CONFIG_GLOBAL_MOTION
4764
Yaowu Xuf883b422016-08-30 14:01:10 -07004765static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004766 ThreadData *const td = &cpi->td;
4767 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004768 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004769 MACROBLOCKD *const xd = &x->e_mbd;
4770 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4771 int i;
4772
Yaowu Xuf883b422016-08-30 14:01:10 -07004773 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4774 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Dengca8d24d2016-10-17 14:06:35 +08004775#if CONFIG_SIMP_MV_PRED
4776 cm->setup_mi(cm);
4777#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004778
4779 xd->mi = cm->mi_grid_visible;
4780 xd->mi[0] = cm->mi;
4781
Yaowu Xuf883b422016-08-30 14:01:10 -07004782 av1_zero(*td->counts);
4783 av1_zero(rdc->coef_counts);
4784 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004785
4786#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004787 aom_clear_system_state();
4788 av1_zero(cpi->global_motion_used);
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004789 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
4790 set_default_gmparams(&cm->global_motion[i]);
4791 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004792 if (cpi->common.frame_type == INTER_FRAME && cpi->Source) {
4793 YV12_BUFFER_CONFIG *ref_buf;
4794 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004795 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004796 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004797 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4798 ref_buf = get_ref_frame_buffer(cpi, frame);
4799 if (ref_buf) {
Debargha Mukherjee3fb33f02016-11-12 10:43:50 -08004800 if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004801 cpi->Source, ref_buf, params)) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004802 convert_model_to_params(params, &cm->global_motion[frame]);
David Barkercf3d0b02016-11-10 10:14:49 +00004803 if (cm->global_motion[frame].wmtype != IDENTITY) {
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004804 refine_integerized_param(
David Barkercf3d0b02016-11-10 10:14:49 +00004805 &cm->global_motion[frame],
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004806#if CONFIG_AOM_HIGHBITDEPTH
4807 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4808#endif // CONFIG_AOM_HIGHBITDEPTH
4809 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4810 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4811 cpi->Source->y_height, cpi->Source->y_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004812 // compute the advantage of using gm parameters over 0 motion
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004813 erroradvantage = av1_warp_erroradv(
David Barkercf3d0b02016-11-10 10:14:49 +00004814 &cm->global_motion[frame],
Yaowu Xuf883b422016-08-30 14:01:10 -07004815#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004816 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Yaowu Xuf883b422016-08-30 14:01:10 -07004817#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004818 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4819 ref_buf->y_stride, cpi->Source->y_buffer, 0, 0,
4820 cpi->Source->y_width, cpi->Source->y_height,
4821 cpi->Source->y_stride, 0, 0, 16, 16);
4822 if (erroradvantage > GLOBAL_MOTION_ADVANTAGE_THRESH)
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004823 // Not enough advantage in using a global model. Make identity.
4824 set_default_gmparams(&cm->global_motion[frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004825 }
4826 }
4827 }
4828 }
4829 }
4830#endif // CONFIG_GLOBAL_MOTION
4831
4832 for (i = 0; i < MAX_SEGMENTS; ++i) {
4833 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004834 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004835 : cm->base_qindex;
4836 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4837 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4838 }
4839
4840 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4841
4842 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004843 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004844
Yaowu Xuf883b422016-08-30 14:01:10 -07004845 av1_initialize_rd_consts(cpi);
4846 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004847 init_encode_frame_mb_context(cpi);
4848
4849 cm->use_prev_frame_mvs =
4850 !cm->error_resilient_mode && cm->width == cm->last_width &&
4851 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004852
4853#if CONFIG_DELTA_Q
4854 // Fix delta q resolution for the moment
4855 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4856#endif
4857
Yaowu Xuc27fc142016-08-22 16:08:15 -07004858#if CONFIG_EXT_REFS
4859 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4860 // show_exisiting_frame=1, nor can it take a frame not used as
4861 // a reference, it is probable that by the time it is being
4862 // referred to, the frame buffer it originally points to may
4863 // already get expired and have been reassigned to the current
4864 // newly coded frame. Hence, we need to check whether this is
4865 // the case, and if yes, we have 2 choices:
4866 // (1) Simply disable the use of previous frame mvs; or
4867 // (2) Have cm->prev_frame point to one reference frame buffer,
4868 // e.g. LAST_FRAME.
4869 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4870 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4871 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4872 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4873 }
4874#endif // CONFIG_EXT_REFS
4875
4876 // Special case: set prev_mi to NULL when the previous mode info
4877 // context cannot be used.
4878 cm->prev_mi =
4879 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4880
4881#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004882 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004883#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004884 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885#endif
4886#endif
4887
4888 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4889 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004890 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004891
4892 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004893 struct aom_usec_timer emr_timer;
4894 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004895
4896#if CONFIG_FP_MB_STATS
4897 if (cpi->use_fp_mb_stats) {
4898 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4899 &cpi->twopass.this_frame_mb_stats);
4900 }
4901#endif
4902
4903 // If allowed, encoding tiles in parallel with one thread handling one tile.
4904 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4905 // 1 tile rows, as it uses the single above_context et al arrays from
4906 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004907 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4908 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004909 else
4910 encode_tiles(cpi);
4911
Yaowu Xuf883b422016-08-30 14:01:10 -07004912 aom_usec_timer_mark(&emr_timer);
4913 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004914 }
4915
4916#if 0
4917 // Keep record of the total distortion this time around for future use
4918 cpi->last_frame_distortion = cpi->frame_distortion;
4919#endif
4920}
4921
Yaowu Xuf883b422016-08-30 14:01:10 -07004922void av1_encode_frame(AV1_COMP *cpi) {
4923 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004924
4925 // In the longer term the encoder should be generalized to match the
4926 // decoder such that we allow compound where one of the 3 buffers has a
4927 // different sign bias and that buffer is then the fixed ref. However, this
4928 // requires further work in the rd loop. For now the only supported encoder
4929 // side behavior is where the ALT ref buffer has opposite sign bias to
4930 // the other two.
4931 if (!frame_is_intra_only(cm)) {
4932 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4933 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4934 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4935 cm->ref_frame_sign_bias[LAST_FRAME])) {
4936 cpi->allow_comp_inter_inter = 0;
4937 } else {
4938 cpi->allow_comp_inter_inter = 1;
4939
4940#if CONFIG_EXT_REFS
4941 cm->comp_fwd_ref[0] = LAST_FRAME;
4942 cm->comp_fwd_ref[1] = LAST2_FRAME;
4943 cm->comp_fwd_ref[2] = LAST3_FRAME;
4944 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4945 cm->comp_bwd_ref[0] = BWDREF_FRAME;
4946 cm->comp_bwd_ref[1] = ALTREF_FRAME;
4947#else
4948 cm->comp_fixed_ref = ALTREF_FRAME;
4949 cm->comp_var_ref[0] = LAST_FRAME;
4950 cm->comp_var_ref[1] = GOLDEN_FRAME;
4951#endif // CONFIG_EXT_REFS
4952 }
4953 } else {
4954 cpi->allow_comp_inter_inter = 0;
4955 }
4956
4957 if (cpi->sf.frame_parameter_update) {
4958 int i;
4959 RD_OPT *const rd_opt = &cpi->rd;
4960 FRAME_COUNTS *counts = cpi->td.counts;
4961 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4962
4963 // This code does a single RD pass over the whole frame assuming
4964 // either compound, single or hybrid prediction as per whatever has
4965 // worked best for that type of frame in the past.
4966 // It also predicts whether another coding mode would have worked
4967 // better than this coding mode. If that is the case, it remembers
4968 // that for subsequent frames.
4969 // It does the same analysis for transform size selection also.
4970 //
4971 // TODO(zoeliu): To investigate whether a frame_type other than
4972 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4973 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4974 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4975 const int is_alt_ref = frame_type == ALTREF_FRAME;
4976
4977 /* prediction (compound, single or hybrid) mode selection */
4978 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4979 cm->reference_mode = SINGLE_REFERENCE;
4980 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4981 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4982 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4983 cm->reference_mode = COMPOUND_REFERENCE;
4984 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4985 cm->reference_mode = SINGLE_REFERENCE;
4986 else
4987 cm->reference_mode = REFERENCE_MODE_SELECT;
4988
4989#if CONFIG_DUAL_FILTER
4990 cm->interp_filter = SWITCHABLE;
4991#endif
4992
4993 encode_frame_internal(cpi);
4994
4995 for (i = 0; i < REFERENCE_MODES; ++i)
4996 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4997
4998 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
4999 int single_count_zero = 0;
5000 int comp_count_zero = 0;
5001
5002 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5003 single_count_zero += counts->comp_inter[i][0];
5004 comp_count_zero += counts->comp_inter[i][1];
5005 }
5006
5007 if (comp_count_zero == 0) {
5008 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005009 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005010 } else if (single_count_zero == 0) {
5011 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005012 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005013 }
5014 }
5015
Jingning Han9777afc2016-10-20 15:17:43 -07005016#if CONFIG_VAR_TX
5017 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
5018 cm->tx_mode = ALLOW_32X32;
5019#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005020 if (cm->tx_mode == TX_MODE_SELECT) {
5021 int count4x4 = 0;
5022 int count8x8_lp = 0, count8x8_8x8p = 0;
5023 int count16x16_16x16p = 0, count16x16_lp = 0;
5024 int count32x32 = 0;
5025 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005026 // counts->tx_size[max_depth][context_idx][this_depth_level]
5027 count4x4 += counts->tx_size[0][i][0];
5028 count4x4 += counts->tx_size[1][i][0];
5029 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005030
Jingning Han2adcfb12016-10-27 11:19:53 -07005031 count8x8_lp += counts->tx_size[1][i][1];
5032 count8x8_lp += counts->tx_size[2][i][1];
5033 count8x8_8x8p += counts->tx_size[0][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005034
Jingning Han2adcfb12016-10-27 11:19:53 -07005035 count16x16_16x16p += counts->tx_size[1][i][2];
5036 count16x16_lp += counts->tx_size[2][i][2];
5037 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005038 }
5039#if CONFIG_EXT_TX && CONFIG_RECT_TX
5040 count4x4 += counts->tx_size_implied[0][TX_4X4];
5041 count4x4 += counts->tx_size_implied[1][TX_4X4];
5042 count4x4 += counts->tx_size_implied[2][TX_4X4];
5043 count4x4 += counts->tx_size_implied[3][TX_4X4];
5044 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5045 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5046 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5047 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5048 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5049 count32x32 += counts->tx_size_implied[3][TX_32X32];
5050#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5051 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5052#if CONFIG_SUPERTX
5053 cm->counts.supertx_size[TX_16X16] == 0 &&
5054 cm->counts.supertx_size[TX_32X32] == 0 &&
5055#endif // CONFIG_SUPERTX
5056 count32x32 == 0) {
5057 cm->tx_mode = ALLOW_8X8;
5058 reset_skip_tx_size(cm, TX_8X8);
5059 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5060 count8x8_lp == 0 && count16x16_lp == 0 &&
5061#if CONFIG_SUPERTX
5062 cm->counts.supertx_size[TX_8X8] == 0 &&
5063 cm->counts.supertx_size[TX_16X16] == 0 &&
5064 cm->counts.supertx_size[TX_32X32] == 0 &&
5065#endif // CONFIG_SUPERTX
5066 count32x32 == 0) {
5067 cm->tx_mode = ONLY_4X4;
5068 reset_skip_tx_size(cm, TX_4X4);
5069 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5070 cm->tx_mode = ALLOW_32X32;
5071 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5072#if CONFIG_SUPERTX
5073 cm->counts.supertx_size[TX_32X32] == 0 &&
5074#endif // CONFIG_SUPERTX
5075 count4x4 == 0) {
5076 cm->tx_mode = ALLOW_16X16;
5077 reset_skip_tx_size(cm, TX_16X16);
5078 }
5079 }
5080#endif
5081 } else {
5082 encode_frame_internal(cpi);
5083 }
5084}
5085
5086static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5087 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
5088 const int intraonly) {
5089 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5090 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5091 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
5092
5093 if (bsize < BLOCK_8X8) {
5094 int idx, idy;
5095 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5096 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5097 for (idy = 0; idy < 2; idy += num_4x4_h)
5098 for (idx = 0; idx < 2; idx += num_4x4_w) {
5099 const int bidx = idy * 2 + idx;
5100 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5101 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005102 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5103 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005104 ++counts->kf_y_mode[a][l][bmode];
5105 } else {
5106 ++counts->y_mode[0][bmode];
5107 }
5108 }
5109 } else {
5110 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005111 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5112 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005113 ++counts->kf_y_mode[above][left][y_mode];
5114 } else {
5115 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5116 }
5117 }
5118
5119 ++counts->uv_mode[y_mode][uv_mode];
5120}
5121
5122#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005123static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005124 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005125 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5127 const int tx_row = blk_row >> 1;
5128 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005129 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5130 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005132 xd->left_txfm_context + tx_row,
5133 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005134 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5135
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5137
5138 if (tx_size == plane_tx_size) {
5139 ++counts->txfm_partition[ctx][0];
5140 mbmi->tx_size = tx_size;
5141 txfm_partition_update(xd->above_txfm_context + tx_col,
5142 xd->left_txfm_context + tx_row, tx_size);
5143 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005144 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5145 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005147
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005149 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005150
5151 if (tx_size == TX_8X8) {
5152 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5153 mbmi->tx_size = TX_4X4;
5154 txfm_partition_update(xd->above_txfm_context + tx_col,
5155 xd->left_txfm_context + tx_row, TX_4X4);
5156 return;
5157 }
5158
5159 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005160 int offsetr = (i >> 1) * bs;
5161 int offsetc = (i & 0x01) * bs;
5162 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5163 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005164 }
5165 }
5166}
5167
Jingning Han9777afc2016-10-20 15:17:43 -07005168static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5169 BLOCK_SIZE plane_bsize, int mi_row,
5170 int mi_col, FRAME_COUNTS *td_counts) {
5171 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005172 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5173 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005174 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005175 const int bh = tx_size_high_unit[max_tx_size];
5176 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005177 int idx, idy;
5178
5179 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5180 xd->left_txfm_context =
5181 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5182
5183 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005184 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005185 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5186 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187}
5188
5189static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5190 int blk_col) {
5191 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5192 const int tx_row = blk_row >> 1;
5193 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005194 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5195 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005196 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5197
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5199
5200 if (tx_size == plane_tx_size) {
5201 mbmi->tx_size = tx_size;
5202 txfm_partition_update(xd->above_txfm_context + tx_col,
5203 xd->left_txfm_context + tx_row, tx_size);
5204
5205 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005206 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5207 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005208 int i;
5209
5210 if (tx_size == TX_8X8) {
5211 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5212 mbmi->tx_size = TX_4X4;
5213 txfm_partition_update(xd->above_txfm_context + tx_col,
5214 xd->left_txfm_context + tx_row, TX_4X4);
5215 return;
5216 }
5217
5218 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005219 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005220 int offsetr = (i >> 1) * bsl;
5221 int offsetc = (i & 0x01) * bsl;
5222 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005223 }
5224 }
5225}
5226
Urvang Joshi52648442016-10-13 17:27:51 -07005227static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5228 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5229 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005230 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5231 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005232 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005233 const int bh = tx_size_high_unit[max_tx_size];
5234 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005235 int idx, idy;
5236
5237 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5238 xd->left_txfm_context =
5239 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5240
5241 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005242 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005243 set_txfm_context(xd, max_tx_size, idy, idx);
5244}
5245#endif
5246
Urvang Joshi52648442016-10-13 17:27:51 -07005247static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5248 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5249 int mi_col, BLOCK_SIZE bsize,
5250 PICK_MODE_CONTEXT *ctx, int *rate) {
5251 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005252 MACROBLOCK *const x = &td->mb;
5253 MACROBLOCKD *const xd = &x->e_mbd;
5254 MODE_INFO **mi_8x8 = xd->mi;
5255 MODE_INFO *mi = mi_8x8[0];
5256 MB_MODE_INFO *mbmi = &mi->mbmi;
5257 const int seg_skip =
5258 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5259 const int mis = cm->mi_stride;
5260 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5261 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005262 const int is_inter = is_inter_block(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005263
Yaowu Xuc27fc142016-08-22 16:08:15 -07005264 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5265
Yushin Cho77bba8d2016-11-04 16:36:56 -07005266#if CONFIG_PVQ
5267 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005268 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005269#endif
5270
Jingning Han94ea1aa2016-11-08 12:10:46 -08005271 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005272 int plane;
5273 mbmi->skip = 1;
5274 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Angie Chiangff6d8902016-10-21 11:02:09 -07005275 av1_encode_intra_block_plane((AV1_COMMON *)cm, x,
5276 AOMMAX(bsize, BLOCK_8X8), plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005277 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005278 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5279 frame_is_intra_only(cm));
5280
hui su5db97432016-10-14 16:10:14 -07005281 // TODO(huisu): move this into sum_intra_stats().
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005282 if (!dry_run && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005283 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005284 (void)counts;
5285#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005286 if (mbmi->mode == DC_PRED
5287#if CONFIG_PALETTE
5288 && mbmi->palette_mode_info.palette_size[0] == 0
5289#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005290 ) {
5291 const int use_filter_intra_mode =
5292 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5293 ++counts->filter_intra[0][use_filter_intra_mode];
5294 }
Urvang Joshib100db72016-10-12 16:28:56 -07005295 if (mbmi->uv_mode == DC_PRED
5296#if CONFIG_PALETTE
5297 && mbmi->palette_mode_info.palette_size[1] == 0
5298#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005299 ) {
5300 const int use_filter_intra_mode =
5301 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5302 ++counts->filter_intra[1][use_filter_intra_mode];
5303 }
5304#endif // CONFIG_FILTER_INTRA
5305#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005306 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5307 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005308 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005309 p_angle =
5310 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005311 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005312 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5313 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005314#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005315 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005316
Urvang Joshib100db72016-10-12 16:28:56 -07005317#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005318 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005319 for (plane = 0; plane <= 1; ++plane) {
5320 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5321 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5322 xd->plane[plane].color_index_map[0];
5323 // TODO(huisu): this increases the use of token buffer. Needs stretch
5324 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005325 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005326 }
5327 }
5328 }
Urvang Joshib100db72016-10-12 16:28:56 -07005329#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005330#if CONFIG_VAR_TX
5331 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5332#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005333 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005334 } else {
5335 int ref;
5336 const int is_compound = has_second_ref(mbmi);
5337
5338 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5339 for (ref = 0; ref < 1 + is_compound; ++ref) {
5340 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5341 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005342 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5343 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005344 }
5345 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Yaowu Xuf883b422016-08-30 14:01:10 -07005346 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5347 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005348
Yaowu Xuf883b422016-08-30 14:01:10 -07005349 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5350 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005351
Yue Chencb60b182016-10-13 15:18:22 -07005352#if CONFIG_MOTION_VAR
5353 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005354 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005355 }
Yue Chencb60b182016-10-13 15:18:22 -07005356#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357
Angie Chiangff6d8902016-10-21 11:02:09 -07005358 av1_encode_sb((AV1_COMMON *)cm, x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005359#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005360 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005361#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005362 if (is_rect_tx(mbmi->tx_size))
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005363 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005364 else
5365#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005366 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5367 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005368#else
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005369 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005370#endif
5371 }
5372
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005373 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005374#if CONFIG_VAR_TX
5375 TX_SIZE tx_size =
5376 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5377#else
5378 TX_SIZE tx_size = mbmi->tx_size;
5379#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005380 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
Jingning Han94ea1aa2016-11-08 12:10:46 -08005381 !(is_inter && (mbmi->skip || seg_skip))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005382 const int tx_size_ctx = get_tx_size_context(xd);
5383 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5384 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005385 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005386 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005387#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005388 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5390#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005391#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005392 if (is_rect_tx_allowed(xd, mbmi)) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005393 td->counts->rect_tx[tx_size_cat][is_rect_tx(tx_size)]++;
Yue Chena1e48dc2016-08-29 17:29:33 -07005394 }
Jingning Hane67b38a2016-11-04 10:30:00 -07005395 if (!is_rect_tx_allowed(xd, mbmi) || !is_rect_tx(tx_size)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005396#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005397 if (is_inter) {
5398 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5399 } else {
Jingning Han4e1737a2016-10-25 16:05:02 -07005400 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Hane67b38a2016-11-04 10:30:00 -07005401 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005402 }
Yue Chena1e48dc2016-08-29 17:29:33 -07005403#if CONFIG_EXT_TX && CONFIG_RECT_TX
5404 }
5405#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005406#endif
Jingning Handc9ad312016-10-20 12:00:15 -07005407#if !CONFIG_VAR_TX
Jingning Han4e1737a2016-10-25 16:05:02 -07005408 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005409#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005410 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005411 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005412 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005413 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005414 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005415 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005416 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005418 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005419 }
5420#if CONFIG_EXT_TX && CONFIG_RECT_TX
5421 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
Jingning Hane67b38a2016-11-04 10:30:00 -07005422 [txsize_sqr_up_map[tx_size]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005423#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5424 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005425 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005426 }
5427
Urvang Joshi454280d2016-10-14 16:51:44 -07005428 for (j = 0; j < mi_height; j++)
5429 for (i = 0; i < mi_width; i++)
5430 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005431 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005432
5433#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005434 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5435 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005436#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005437 }
Jingning Han9777afc2016-10-20 15:17:43 -07005438
Jingning Hane67b38a2016-11-04 10:30:00 -07005439 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005440 ++td->counts
5441 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005442#if CONFIG_EXT_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005443 if (get_ext_tx_types(tx_size, bsize, is_inter) > 1 && cm->base_qindex > 0 &&
5444 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005445 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005446 int eset = get_ext_tx_set(tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005447 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005448 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005449 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
Yaowu Xuc27fc142016-08-22 16:08:15 -07005450 [mbmi->tx_type];
5451 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005452 ++td->counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005453 }
5454 }
5455 }
5456#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005457 if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005459 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005460 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005461 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005462 ++td->counts->intra_ext_tx[tx_size]
clang-format67948d32016-09-07 22:40:40 -07005463 [intra_mode_to_tx_type_context[mbmi->mode]]
5464 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005465 }
5466 }
5467#endif // CONFIG_EXT_TX
5468 }
5469
5470#if CONFIG_VAR_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005471 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 && is_inter &&
5472 !(mbmi->skip || seg_skip)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005473#if CONFIG_EXT_TX && CONFIG_RECT_TX
5474 if (is_rect_tx(mbmi->tx_size)) {
5475 set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, xd);
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005476 } else {
5477 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005478 }
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005479#else
5480 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005481#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005482 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005483 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005484 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005485 if (is_inter)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486#if CONFIG_EXT_TX && CONFIG_RECT_TX
5487 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005488 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005489 max_txsize_lookup[bsize]);
5490 if (txsize_sqr_map[max_txsize_rect_lookup[bsize]] <= tx_size)
5491 tx_size = max_txsize_rect_lookup[bsize];
5492 if (xd->lossless[mbmi->segment_id]) tx_size = TX_4X4;
5493 }
5494#else
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005495 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005496#endif
5497 else
Jingning Hane67b38a2016-11-04 10:30:00 -07005498 tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005499 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005500 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005501 }
5502#endif
5503}
5504
5505#if CONFIG_SUPERTX
5506static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5507 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5508#if CONFIG_EXT_INTER
5509 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5510#endif // CONFIG_EXT_INTER
5511 return 0;
5512}
5513
Urvang Joshi52648442016-10-13 17:27:51 -07005514static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5515 int mi_row, int mi_col, BLOCK_SIZE bsize,
5516 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005517 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518
5519 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5520 const PARTITION_TYPE partition = pc_tree->partitioning;
5521 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5522#if CONFIG_EXT_PARTITION_TYPES
5523 int i;
5524#endif
5525
5526 assert(bsize >= BLOCK_8X8);
5527
5528 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5529
5530 switch (partition) {
5531 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5532 case PARTITION_VERT:
5533 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5534 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5535 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5536 }
5537 break;
5538 case PARTITION_HORZ:
5539 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5540 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5541 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5542 }
5543 break;
5544 case PARTITION_SPLIT:
5545 if (bsize == BLOCK_8X8) {
5546 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5547 } else {
5548 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5549 pc_tree->split[0]))
5550 return 1;
5551 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5552 pc_tree->split[1]))
5553 return 1;
5554 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5555 pc_tree->split[2]))
5556 return 1;
5557 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5558 pc_tree->split[3]))
5559 return 1;
5560 }
5561 break;
5562#if CONFIG_EXT_PARTITION_TYPES
5563 case PARTITION_HORZ_A:
5564 for (i = 0; i < 3; i++) {
5565 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5566 }
5567 break;
5568 case PARTITION_HORZ_B:
5569 for (i = 0; i < 3; i++) {
5570 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5571 }
5572 break;
5573 case PARTITION_VERT_A:
5574 for (i = 0; i < 3; i++) {
5575 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5576 }
5577 break;
5578 case PARTITION_VERT_B:
5579 for (i = 0; i < 3; i++) {
5580 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5581 }
5582 break;
5583#endif // CONFIG_EXT_PARTITION_TYPES
5584 default: assert(0);
5585 }
5586 return 0;
5587}
5588
5589static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5590 return ctx->mic.mbmi.tx_size == supertx_size;
5591}
5592
5593static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5594 PC_TREE *pc_tree) {
5595 PARTITION_TYPE partition;
5596 BLOCK_SIZE subsize;
5597
5598 partition = pc_tree->partitioning;
5599 subsize = get_subsize(bsize, partition);
5600 switch (partition) {
5601 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5602 case PARTITION_VERT:
5603 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5604 case PARTITION_HORZ:
5605 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5606 case PARTITION_SPLIT:
5607 if (bsize == BLOCK_8X8)
5608 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5609 else
5610 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5611#if CONFIG_EXT_PARTITION_TYPES
5612 case PARTITION_HORZ_A:
5613 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5614 case PARTITION_HORZ_B:
5615 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5616 case PARTITION_VERT_A:
5617 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5618 case PARTITION_VERT_B:
5619 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5620#endif // CONFIG_EXT_PARTITION_TYPES
5621 default: assert(0); return 0;
5622 }
5623}
5624
Urvang Joshi52648442016-10-13 17:27:51 -07005625static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005626#if CONFIG_EXT_INTER
5627 int mi_row_ori, int mi_col_ori,
5628#endif // CONFIG_EXT_INTER
5629 int mi_row_pred, int mi_col_pred,
5630 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5631 // Used in supertx
5632 // (mi_row_ori, mi_col_ori): location for mv
5633 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005634 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635 MACROBLOCK *const x = &td->mb;
5636 MACROBLOCKD *const xd = &x->e_mbd;
5637 MODE_INFO *mi_8x8 = xd->mi[0];
5638 MODE_INFO *mi = mi_8x8;
5639 MB_MODE_INFO *mbmi = &mi->mbmi;
5640 int ref;
5641 const int is_compound = has_second_ref(mbmi);
5642
5643 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5644
5645 for (ref = 0; ref < 1 + is_compound; ++ref) {
5646 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005647 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5648 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005649 }
5650
5651 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005652 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005653#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005654 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005656 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005657 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005658 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005659#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005660 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005662 mi_row_pred, mi_col_pred,
5663 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005664}
5665
Urvang Joshi52648442016-10-13 17:27:51 -07005666static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005667 const TileInfo *const tile, int block,
5668 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5669 int mi_col_pred, int mi_row_top, int mi_col_top,
5670 uint8_t *dst_buf[3], int dst_stride[3],
5671 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005672 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005673 // Used in supertx
5674 // (mi_row_ori, mi_col_ori): location for mv
5675 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5676 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5677 // block: sub location of sub8x8 blocks
5678 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5679 // bextend: 1: region to predict is an extension of ori; 0: not
5680
5681 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005682 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005683 MACROBLOCKD *const xd = &x->e_mbd;
5684 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5685 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5686 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5687 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5688
5689 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5690 mi_row_pred >= mi_row_top + mi_height_top ||
5691 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5692 mi_col_pred >= cm->mi_cols)
5693 return;
5694
5695 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5696 mi_col_ori, bsize_pred);
5697 xd->plane[0].dst.stride = dst_stride[0];
5698 xd->plane[1].dst.stride = dst_stride[1];
5699 xd->plane[2].dst.stride = dst_stride[2];
5700 xd->plane[0].dst.buf = dst_buf[0] +
5701 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5702 (c >> xd->plane[0].subsampling_x);
5703 xd->plane[1].dst.buf = dst_buf[1] +
5704 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5705 (c >> xd->plane[1].subsampling_x);
5706 xd->plane[2].dst.buf = dst_buf[2] +
5707 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5708 (c >> xd->plane[2].subsampling_x);
5709
5710 predict_superblock(cpi, td,
5711#if CONFIG_EXT_INTER
5712 mi_row_ori, mi_col_ori,
5713#endif // CONFIG_EXT_INTER
5714 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5715
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005716 if (!dry_run && !bextend) {
5717#if CONFIG_SUPERTX
5718 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
5719#else
5720 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred);
5721#endif
5722 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005723}
5724
Urvang Joshi52648442016-10-13 17:27:51 -07005725static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005726 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5727 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005728 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005729 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5730 // dir: 0-lower, 1-upper, 2-left, 3-right
5731 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5732 MACROBLOCKD *xd = &td->mb.e_mbd;
5733 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5734 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5735 int xss = xd->plane[1].subsampling_x;
5736 int yss = xd->plane[1].subsampling_y;
5737 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5738
5739 BLOCK_SIZE extend_bsize;
5740 int unit, mi_row_pred, mi_col_pred;
5741
5742 if (dir == 0 || dir == 1) { // lower and upper
5743 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5744 ? BLOCK_8X8
5745 : BLOCK_16X8;
5746 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5747 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5748 mi_col_pred = mi_col;
5749
5750 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5751 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005752 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005753
5754 if (mi_width > unit) {
5755 int i;
5756 for (i = 0; i < mi_width / unit - 1; i++) {
5757 mi_col_pred += unit;
5758 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5759 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005760 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5761 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005762 }
5763 }
5764 } else if (dir == 2 || dir == 3) { // left and right
5765 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5766 ? BLOCK_8X8
5767 : BLOCK_8X16;
5768 unit = num_8x8_blocks_high_lookup[extend_bsize];
5769 mi_row_pred = mi_row;
5770 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5771
5772 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5773 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005774 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005775
5776 if (mi_height > unit) {
5777 int i;
5778 for (i = 0; i < mi_height / unit - 1; i++) {
5779 mi_row_pred += unit;
5780 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5781 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005782 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5783 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005784 }
5785 }
5786 } else {
5787 extend_bsize = BLOCK_8X8;
5788 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5789 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5790
5791 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5792 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005793 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005794 }
5795}
5796
Urvang Joshi52648442016-10-13 17:27:51 -07005797static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005798 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5799 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005800 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005801 uint8_t *dst_buf[3], int dst_stride[3]) {
5802 assert(block >= 0 && block < 4);
5803 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005804 mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005805 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005806 mi_col_top, dry_run, dst_buf, dst_stride, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005807 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005808 mi_col_top, dry_run, dst_buf, dst_stride, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005809 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005810 mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005811 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005812 mi_col_top, dry_run, dst_buf, dst_stride, 4);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005813 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005814 mi_col_top, dry_run, dst_buf, dst_stride, 5);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005815 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005816 mi_col_top, dry_run, dst_buf, dst_stride, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005817 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005818 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819}
5820
5821// This function generates prediction for multiple blocks, between which
5822// discontinuity around boundary is reduced by smoothing masks. The basic
5823// smoothing mask is a soft step function along horz/vert direction. In more
5824// complicated case when a block is split into 4 subblocks, the basic mask is
5825// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5826// then applied to the 2 masked prediction mentioned above in vertical direction
5827// If the block is split into more than one level, at every stage, masked
5828// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005829static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005830 const TileInfo *const tile, int mi_row,
5831 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005832 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005833 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5834 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005835 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005836 MACROBLOCK *const x = &td->mb;
5837 MACROBLOCKD *const xd = &x->e_mbd;
5838
5839 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5840 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5841 const PARTITION_TYPE partition = pc_tree->partitioning;
5842 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5843#if CONFIG_EXT_PARTITION_TYPES
5844 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5845#endif
5846
5847 int i;
5848 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
5849 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5850 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5851 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5852 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5853 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5854 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5855
5856 assert(bsize >= BLOCK_8X8);
5857
5858 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
5859
Yaowu Xuf883b422016-08-30 14:01:10 -07005860#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005861 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5862 int len = sizeof(uint16_t);
5863 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5864 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
5865 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
5866 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5867 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
5868 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
5869 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
5870 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
5871 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
5872 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005873#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005874 dst_buf1[0] = tmp_buf1;
5875 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
5876 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
5877 dst_buf2[0] = tmp_buf2;
5878 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
5879 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
5880 dst_buf3[0] = tmp_buf3;
5881 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
5882 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005883#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005884 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005885#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886
Urvang Joshi52648442016-10-13 17:27:51 -07005887 if (!dry_run && bsize < top_bsize) {
5888 // Explicitly cast away const.
5889 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
5890 frame_counts->partition[ctx][partition]++;
5891 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005892
5893 for (i = 0; i < MAX_MB_PLANE; i++) {
5894 xd->plane[i].dst.buf = dst_buf[i];
5895 xd->plane[i].dst.stride = dst_stride[i];
5896 }
5897
5898 switch (partition) {
5899 case PARTITION_NONE:
5900 assert(bsize < top_bsize);
5901 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5902 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005903 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005904 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005905 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005906 break;
5907 case PARTITION_HORZ:
5908 if (bsize == BLOCK_8X8) {
5909 // Fisrt half
5910 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5911 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005912 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005913 if (bsize < top_bsize)
5914 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005915 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005916
5917 // Second half
5918 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5919 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005920 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005921 if (bsize < top_bsize)
5922 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005923 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005924
5925 // Smooth
5926 xd->plane[0].dst.buf = dst_buf[0];
5927 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005928 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005929 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5930 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5931 0);
5932 } else {
5933 // First half
5934 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5935 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005936 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005937 if (bsize < top_bsize)
5938 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005939 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005940 else
5941 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005942 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005943
5944 if (mi_row + hbs < cm->mi_rows) {
5945 // Second half
5946 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5947 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005948 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005949 if (bsize < top_bsize)
5950 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005951 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005952 dst_stride1);
5953 else
5954 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005955 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005956 dst_stride1, 1);
5957
5958 // Smooth
5959 for (i = 0; i < MAX_MB_PLANE; i++) {
5960 xd->plane[i].dst.buf = dst_buf[i];
5961 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005962 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005963 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5964 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5965 PARTITION_HORZ, i);
5966 }
5967 }
5968 }
5969 break;
5970 case PARTITION_VERT:
5971 if (bsize == BLOCK_8X8) {
5972 // First half
5973 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5974 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005975 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005976 if (bsize < top_bsize)
5977 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005978 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005979
5980 // Second half
5981 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5982 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005983 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005984 if (bsize < top_bsize)
5985 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005986 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005987
5988 // Smooth
5989 xd->plane[0].dst.buf = dst_buf[0];
5990 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005991 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005992 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5993 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5994 0);
5995 } else {
5996 // bsize: not important, not useful
5997 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5998 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005999 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006000 if (bsize < top_bsize)
6001 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006002 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006003 else
6004 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006005 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006006
6007 if (mi_col + hbs < cm->mi_cols) {
6008 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6009 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006010 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006011 if (bsize < top_bsize)
6012 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006013 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6014 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006015 else
6016 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006017 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6018 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006019
6020 for (i = 0; i < MAX_MB_PLANE; i++) {
6021 xd->plane[i].dst.buf = dst_buf[i];
6022 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006023 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006024 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6025 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6026 PARTITION_VERT, i);
6027 }
6028 }
6029 }
6030 break;
6031 case PARTITION_SPLIT:
6032 if (bsize == BLOCK_8X8) {
6033 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6034 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006035 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006036 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6037 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006038 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006039 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6040 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006041 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006042 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6043 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006044 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006045
6046 if (bsize < top_bsize) {
6047 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006048 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006049 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006050 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006051 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006052 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006053 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006054 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006055 }
6056 } else {
6057 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006058 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6059 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006060 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6061 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006062 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6063 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006064 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6065 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006066 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6067 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006068 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6069 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006070 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006071 top_bsize, dst_buf3, dst_stride3,
6072 pc_tree->split[3]);
6073 }
6074 for (i = 0; i < MAX_MB_PLANE; i++) {
6075 if (bsize == BLOCK_8X8 && i != 0)
6076 continue; // Skip <4x4 chroma smoothing
6077 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006078 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006079 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6080 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6081 PARTITION_VERT, i);
6082 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006083 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006084 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6085 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6086 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006087 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006088 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6089 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6090 PARTITION_HORZ, i);
6091 }
6092 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006093 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006094 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6095 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6096 PARTITION_HORZ, i);
6097 }
6098 }
6099 break;
6100#if CONFIG_EXT_PARTITION_TYPES
6101 case PARTITION_HORZ_A:
6102 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6103 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006104 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006105 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006106 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006107
6108 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6109 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006110 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006111 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006112 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006113
6114 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6115 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006116 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006117 if (bsize < top_bsize)
6118 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006119 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006120 else
6121 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006122 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006123
6124 for (i = 0; i < MAX_MB_PLANE; i++) {
6125 xd->plane[i].dst.buf = dst_buf[i];
6126 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006127 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006128 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6129 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6130 i);
6131 }
6132 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006133 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006134 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6135 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6136 i);
6137 }
6138
6139 break;
6140 case PARTITION_VERT_A:
6141
6142 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6143 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006144 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006145 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006146 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006147
6148 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6149 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006150 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006151 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006152 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153
6154 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6155 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006156 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006157 if (bsize < top_bsize)
6158 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006159 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006160 else
6161 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006162 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006163
6164 for (i = 0; i < MAX_MB_PLANE; i++) {
6165 xd->plane[i].dst.buf = dst_buf[i];
6166 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006167 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006168 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6169 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6170 i);
6171 }
6172 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006173 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006174 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6175 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6176 i);
6177 }
6178 break;
6179 case PARTITION_HORZ_B:
6180
6181 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6182 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006183 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006184 if (bsize < top_bsize)
6185 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006186 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006187 else
6188 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006189 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006190
6191 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6192 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006193 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006194 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006195 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196
6197 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6198 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006199 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006200 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006201 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 dst_stride2);
6203
6204 for (i = 0; i < MAX_MB_PLANE; i++) {
6205 xd->plane[i].dst.buf = dst_buf1[i];
6206 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006207 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006208 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6209 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6210 PARTITION_VERT, i);
6211 }
6212 for (i = 0; i < MAX_MB_PLANE; i++) {
6213 xd->plane[i].dst.buf = dst_buf[i];
6214 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006215 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006216 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6217 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6218 i);
6219 }
6220 break;
6221 case PARTITION_VERT_B:
6222
6223 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6224 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006225 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006226 if (bsize < top_bsize)
6227 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006228 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006229 else
6230 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006231 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006232
6233 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6234 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006235 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006236 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006237 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006238
6239 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6240 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006241 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006242 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006243 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006244 dst_stride2);
6245
6246 for (i = 0; i < MAX_MB_PLANE; i++) {
6247 xd->plane[i].dst.buf = dst_buf1[i];
6248 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006249 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006250 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6251 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6252 PARTITION_HORZ, i);
6253 }
6254 for (i = 0; i < MAX_MB_PLANE; i++) {
6255 xd->plane[i].dst.buf = dst_buf[i];
6256 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006257 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006258 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6259 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6260 i);
6261 }
6262 break;
6263#endif // CONFIG_EXT_PARTITION_TYPES
6264 default: assert(0);
6265 }
6266
6267#if CONFIG_EXT_PARTITION_TYPES
6268 if (bsize < top_bsize)
6269 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6270#else
6271 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6272 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6273#endif // CONFIG_EXT_PARTITION_TYPES
6274}
6275
Urvang Joshi52648442016-10-13 17:27:51 -07006276static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006277 const TileInfo *const tile, int mi_row, int mi_col,
6278 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6279 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006280 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006281 MACROBLOCK *const x = &td->mb;
6282 MACROBLOCKD *const xd = &x->e_mbd;
6283 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6284 base_rate = *tmp_rate;
6285 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6286 uint8_t *dst_buf[3];
6287 int dst_stride[3];
6288 TX_SIZE tx_size;
6289 MB_MODE_INFO *mbmi;
6290 TX_TYPE tx_type, best_tx_nostx;
6291#if CONFIG_EXT_TX
6292 int ext_tx_set;
6293#endif // CONFIG_EXT_TX
6294 int tmp_rate_tx = 0, skip_tx = 0;
6295 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6296
6297 set_skip_context(xd, mi_row, mi_col);
6298 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006299 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006300 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006301 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6302 dst_buf[plane] = xd->plane[plane].dst.buf;
6303 dst_stride[plane] = xd->plane[plane].dst.stride;
6304 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006305 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006306 bsize, dst_buf, dst_stride, pc_tree);
6307
6308 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6309 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6310
6311 mbmi = &xd->mi[0]->mbmi;
6312 best_tx_nostx = mbmi->tx_type;
6313
6314 *best_tx = DCT_DCT;
6315
6316 // chroma
6317 skippable_uv = 1;
6318 rate_uv = 0;
6319 dist_uv = 0;
6320 sse_uv = 0;
6321 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6322#if CONFIG_VAR_TX
6323 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6324 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6325 const struct macroblockd_plane *const pd = &xd->plane[plane];
6326 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006327 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006328 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006329
6330 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006331 tx_size =
6332 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006333 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006334 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6335
Yaowu Xuf883b422016-08-30 14:01:10 -07006336 av1_subtract_plane(x, bsize, plane);
6337 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006338 get_plane_block_size(bsize, pd), coeff_ctx,
6339 &this_rd_stats);
6340
6341 this_rate = this_rd_stats.rate;
6342 this_dist = this_rd_stats.dist;
6343 pnsse = this_rd_stats.sse;
6344 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006345#else
6346 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006347 tx_size =
6348 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006349 av1_subtract_plane(x, bsize, plane);
6350 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6351 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006352#endif // CONFIG_VAR_TX
6353
6354 rate_uv += this_rate;
6355 dist_uv += this_dist;
6356 sse_uv += pnsse;
6357 skippable_uv &= pnskip;
6358 }
6359
6360 // luma
6361 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006362 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006363#if CONFIG_EXT_TX
6364 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6365#endif // CONFIG_EXT_TX
6366 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6367#if CONFIG_VAR_TX
6368 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6369 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6370 const struct macroblockd_plane *const pd = &xd->plane[0];
6371 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006372 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006373#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006374
Yaowu Xuc27fc142016-08-22 16:08:15 -07006375#if CONFIG_EXT_TX
6376 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6377#else
6378 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6379#endif // CONFIG_EXT_TX
6380 mbmi->tx_type = tx_type;
6381
6382#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006383 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006384
Yaowu Xuf883b422016-08-30 14:01:10 -07006385 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006386 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006387 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6388 &this_rd_stats);
6389
6390 this_rate = this_rd_stats.rate;
6391 this_dist = this_rd_stats.dist;
6392 pnsse = this_rd_stats.sse;
6393 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006394#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006395 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6396 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006397#endif // CONFIG_VAR_TX
6398
6399#if CONFIG_EXT_TX
6400 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6401 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6402 if (ext_tx_set > 0)
6403 this_rate +=
6404 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6405 }
6406#else
6407 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6408 this_rate != INT_MAX) {
6409 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6410 }
6411#endif // CONFIG_EXT_TX
6412 *tmp_rate = rate_uv + this_rate;
6413 *tmp_dist = dist_uv + this_dist;
6414 sse = sse_uv + pnsse;
6415 skippable = skippable_uv && pnskip;
6416 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006417 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006418 x->skip = 1;
6419 } else {
6420 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6421 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006422 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006423 x->skip = 0;
6424 } else {
6425 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006426 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006427 x->skip = 1;
6428 }
6429 }
6430 *tmp_rate += base_rate;
6431 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6432 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6433 *best_tx = tx_type;
6434 bestrd_tx = rd_tx;
6435 tmp_rate_tx = *tmp_rate;
6436 tmp_dist_tx = *tmp_dist;
6437 skip_tx = x->skip;
6438 }
6439 }
6440 *tmp_rate = tmp_rate_tx;
6441 *tmp_dist = tmp_dist_tx;
6442 x->skip = skip_tx;
6443#if CONFIG_VAR_TX
6444 for (plane = 0; plane < 1; ++plane)
6445 memset(x->blk_skip[plane], x->skip,
6446 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6447#endif // CONFIG_VAR_TX
6448 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6449}
6450#endif // CONFIG_SUPERTX