blob: ffa77d636e078a364a0bf87f60f5d90abf4f439c [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)) {
1958 counts->wedge_interinter[bsize][mbmi->use_wedge_interinter]++;
1959 }
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)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004617#define GLOBAL_MOTION_MODEL ROTZOOM
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004618
4619// Adds some offset to a global motion parameter and handles
4620// all of the necessary precision shifts, clamping, and
4621// zero-centering.
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004622static int32_t add_param_offset(int param_index, int32_t param_value,
4623 int32_t offset) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004624 const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
4625 GM_ROW3HOMO_PREC_DIFF };
4626 const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
4627 // type of param: 0 - translation, 1 - affine, 2 - homography
4628 const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
4629 const int is_one_centered = (param_index == 2 || param_index == 5);
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004630
4631 // Make parameter zero-centered and offset the shift that was done to make
4632 // it compatible with the warped model
4633 param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004634 scale_vals[param_type];
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004635 // Add desired offset to the rescaled/zero-centered parameter
4636 param_value += offset;
4637 // Clamp the parameter so it does not overflow the number of bits allotted
4638 // to it in the bitstream
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004639 param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
4640 clamp_vals[param_type]);
Sarah Parkerb3dab492016-10-26 11:45:50 -07004641 // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004642 // with the warped motion library
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004643 param_value *= (1 << scale_vals[param_type]);
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004644
Sarah Parkerb3dab492016-10-26 11:45:50 -07004645 // Undo the zero-centering step if necessary
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004646 return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
4647}
4648
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004649static void refine_integerized_param(WarpedMotionParams *wm,
4650#if CONFIG_AOM_HIGHBITDEPTH
4651 int use_hbd, int bd,
4652#endif // CONFIG_AOM_HIGHBITDEPTH
4653 uint8_t *ref, int r_width, int r_height,
4654 int r_stride, uint8_t *dst, int d_width,
4655 int d_height, int d_stride,
4656 int n_refinements) {
4657 int i = 0, p;
4658 int n_params = n_trans_model_params[wm->wmtype];
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004659 int32_t *param_mat = wm->wmmat;
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004660 double step_error;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004661 int32_t step;
4662 int32_t *param;
4663 int32_t curr_param;
4664 int32_t best_param;
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004665
4666 double best_error =
4667 av1_warp_erroradv(wm,
4668#if CONFIG_AOM_HIGHBITDEPTH
4669 use_hbd, bd,
4670#endif // CONFIG_AOM_HIGHBITDEPTH
4671 ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
4672 d_height, d_stride, 0, 0, 16, 16);
4673 for (p = 0; p < n_params; ++p) {
4674 param = param_mat + p;
4675 step = 1 << (n_refinements + 1);
4676 curr_param = *param;
4677 best_param = curr_param;
4678 for (i = 0; i < n_refinements; i++) {
4679 // look to the left
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004680 *param = add_param_offset(p, curr_param, -step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004681 step_error =
4682 av1_warp_erroradv(wm,
4683#if CONFIG_AOM_HIGHBITDEPTH
4684 use_hbd, bd,
4685#endif // CONFIG_AOM_HIGHBITDEPTH
4686 ref, r_width, r_height, r_stride, dst, 0, 0,
4687 d_width, d_height, d_stride, 0, 0, 16, 16);
4688 if (step_error < best_error) {
4689 step >>= 1;
4690 best_error = step_error;
4691 best_param = *param;
4692 curr_param = best_param;
4693 continue;
4694 }
4695
4696 // look to the right
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004697 *param = add_param_offset(p, curr_param, step);
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004698 step_error =
4699 av1_warp_erroradv(wm,
4700#if CONFIG_AOM_HIGHBITDEPTH
4701 use_hbd, bd,
4702#endif // CONFIG_AOM_HIGHBITDEPTH
4703 ref, r_width, r_height, r_stride, dst, 0, 0,
4704 d_width, d_height, d_stride, 0, 0, 16, 16);
4705 if (step_error < best_error) {
4706 step >>= 1;
4707 best_error = step_error;
4708 best_param = *param;
4709 curr_param = best_param;
4710 continue;
4711 }
4712
4713 // no improvement found-> means we're either already at a minimum or
4714 // step is too wide
4715 step >>= 1;
4716 }
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004717 *param = best_param;
4718 }
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004719 // For rotzoom model enforce the constraints on mat[4] and mat[5]
4720 if (wm->wmtype == ROTZOOM) {
4721 param_mat[5] = param_mat[2];
4722 param_mat[4] = -param_mat[3];
4723 }
Sarah Parkerecb0afc2016-09-06 19:09:13 -07004724}
4725
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004726static void convert_to_params(const double *params, int32_t *model) {
4727 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004728 int alpha_present = 0;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004729 model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4730 model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
4731 model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004732 GM_TRANS_DECODE_FACTOR;
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004733 model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
Sarah Parkere5299862016-08-16 14:57:37 -07004734 GM_TRANS_DECODE_FACTOR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004736 for (i = 2; i < 6; ++i) {
4737 const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
Debargha Mukherjee5f305852016-11-03 15:47:21 -07004738 model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
Sarah Parkerc4bcb502016-09-07 13:24:53 -07004739 model[i] =
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004740 (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
4741 alpha_present |= (model[i] != 0);
4742 model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
4743 }
4744 for (; i < 8; ++i) {
4745 model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
4746 model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
4747 GM_ROW3HOMO_DECODE_FACTOR;
Sarah Parkere5299862016-08-16 14:57:37 -07004748 alpha_present |= (model[i] != 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004749 }
4750
4751 if (!alpha_present) {
Sarah Parkere5299862016-08-16 14:57:37 -07004752 if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
4753 model[0] = 0;
4754 model[1] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755 }
4756 }
4757}
4758
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004759static void convert_model_to_params(const double *params,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004760 Global_Motion_Params *model) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004761 convert_to_params(params, model->motion_params.wmmat);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 model->gmtype = get_gmtype(model);
4763 model->motion_params.wmtype = gm_to_trans_type(model->gmtype);
4764}
4765#endif // CONFIG_GLOBAL_MOTION
4766
Yaowu Xuf883b422016-08-30 14:01:10 -07004767static void encode_frame_internal(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768 ThreadData *const td = &cpi->td;
4769 MACROBLOCK *const x = &td->mb;
Yaowu Xuf883b422016-08-30 14:01:10 -07004770 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004771 MACROBLOCKD *const xd = &x->e_mbd;
4772 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4773 int i;
4774
Yaowu Xuf883b422016-08-30 14:01:10 -07004775 x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
4776 x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
Dengca8d24d2016-10-17 14:06:35 +08004777#if CONFIG_SIMP_MV_PRED
4778 cm->setup_mi(cm);
4779#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004780
4781 xd->mi = cm->mi_grid_visible;
4782 xd->mi[0] = cm->mi;
4783
Yaowu Xuf883b422016-08-30 14:01:10 -07004784 av1_zero(*td->counts);
4785 av1_zero(rdc->coef_counts);
4786 av1_zero(rdc->comp_pred_diff);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004787
4788#if CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07004789 aom_clear_system_state();
4790 av1_zero(cpi->global_motion_used);
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004791 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
4792 set_default_gmparams(&cm->global_motion[i]);
4793 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004794 if (cpi->common.frame_type == INTER_FRAME && cpi->Source) {
4795 YV12_BUFFER_CONFIG *ref_buf;
4796 int frame;
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004797 double erroradvantage = 0;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004798 double params[8] = { 0, 0, 1, 0, 0, 1, 0, 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07004799 for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
4800 ref_buf = get_ref_frame_buffer(cpi, frame);
4801 if (ref_buf) {
4802 if (compute_global_motion_feature_based(GLOBAL_MOTION_MODEL,
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004803 cpi->Source, ref_buf, params)) {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004804 convert_model_to_params(params, &cm->global_motion[frame]);
4805 if (cm->global_motion[frame].gmtype > GLOBAL_ZERO) {
Sarah Parkerf41a06b2016-10-25 14:42:47 -07004806 refine_integerized_param(
4807 &cm->global_motion[frame].motion_params,
4808#if CONFIG_AOM_HIGHBITDEPTH
4809 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
4810#endif // CONFIG_AOM_HIGHBITDEPTH
4811 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4812 ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
4813 cpi->Source->y_height, cpi->Source->y_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004814 // compute the advantage of using gm parameters over 0 motion
Sarah Parkerf9a961c2016-09-06 11:25:04 -07004815 erroradvantage = av1_warp_erroradv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004816 &cm->global_motion[frame].motion_params,
Yaowu Xuf883b422016-08-30 14:01:10 -07004817#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004818 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Yaowu Xuf883b422016-08-30 14:01:10 -07004819#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004820 ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
4821 ref_buf->y_stride, cpi->Source->y_buffer, 0, 0,
4822 cpi->Source->y_width, cpi->Source->y_height,
4823 cpi->Source->y_stride, 0, 0, 16, 16);
4824 if (erroradvantage > GLOBAL_MOTION_ADVANTAGE_THRESH)
Debargha Mukherjee8db4c772016-11-07 12:54:21 -08004825 // Not enough advantage in using a global model. Make identity.
4826 set_default_gmparams(&cm->global_motion[frame]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004827 }
4828 }
4829 }
4830 }
4831 }
4832#endif // CONFIG_GLOBAL_MOTION
4833
4834 for (i = 0; i < MAX_SEGMENTS; ++i) {
4835 const int qindex = cm->seg.enabled
Yaowu Xuf883b422016-08-30 14:01:10 -07004836 ? av1_get_qindex(&cm->seg, i, cm->base_qindex)
Yaowu Xuc27fc142016-08-22 16:08:15 -07004837 : cm->base_qindex;
4838 xd->lossless[i] = qindex == 0 && cm->y_dc_delta_q == 0 &&
4839 cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
4840 }
4841
4842 if (!cm->seg.enabled && xd->lossless[0]) x->optimize = 0;
4843
4844 cm->tx_mode = select_tx_mode(cpi, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07004845 av1_frame_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004846
Yaowu Xuf883b422016-08-30 14:01:10 -07004847 av1_initialize_rd_consts(cpi);
4848 av1_initialize_me_consts(cpi, x, cm->base_qindex);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004849 init_encode_frame_mb_context(cpi);
4850
4851 cm->use_prev_frame_mvs =
4852 !cm->error_resilient_mode && cm->width == cm->last_width &&
4853 cm->height == cm->last_height && !cm->intra_only && cm->last_show_frame;
Thomas Daviesf6936102016-09-05 16:51:31 +01004854
4855#if CONFIG_DELTA_Q
4856 // Fix delta q resolution for the moment
4857 cm->delta_q_res = DEFAULT_DELTA_Q_RES;
4858#endif
4859
Yaowu Xuc27fc142016-08-22 16:08:15 -07004860#if CONFIG_EXT_REFS
4861 // NOTE(zoeliu): As cm->prev_frame can take neither a frame of
4862 // show_exisiting_frame=1, nor can it take a frame not used as
4863 // a reference, it is probable that by the time it is being
4864 // referred to, the frame buffer it originally points to may
4865 // already get expired and have been reassigned to the current
4866 // newly coded frame. Hence, we need to check whether this is
4867 // the case, and if yes, we have 2 choices:
4868 // (1) Simply disable the use of previous frame mvs; or
4869 // (2) Have cm->prev_frame point to one reference frame buffer,
4870 // e.g. LAST_FRAME.
4871 if (cm->use_prev_frame_mvs && !enc_is_ref_frame_buf(cpi, cm->prev_frame)) {
4872 // Reassign the LAST_FRAME buffer to cm->prev_frame.
4873 const int last_fb_buf_idx = get_ref_frame_buf_idx(cpi, LAST_FRAME);
4874 cm->prev_frame = &cm->buffer_pool->frame_bufs[last_fb_buf_idx];
4875 }
4876#endif // CONFIG_EXT_REFS
4877
4878 // Special case: set prev_mi to NULL when the previous mode info
4879 // context cannot be used.
4880 cm->prev_mi =
4881 cm->use_prev_frame_mvs ? cm->prev_mip + cm->mi_stride + 1 : NULL;
4882
4883#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07004884 x->txb_split_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004885#if CONFIG_REF_MV
Yaowu Xuf883b422016-08-30 14:01:10 -07004886 av1_zero(x->blk_skip_drl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004887#endif
4888#endif
4889
4890 if (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
4891 cpi->td.var_root[0] == NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004892 av1_setup_var_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004893
4894 {
Yaowu Xuf883b422016-08-30 14:01:10 -07004895 struct aom_usec_timer emr_timer;
4896 aom_usec_timer_start(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004897
4898#if CONFIG_FP_MB_STATS
4899 if (cpi->use_fp_mb_stats) {
4900 input_fpmb_stats(&cpi->twopass.firstpass_mb_stats, cm,
4901 &cpi->twopass.this_frame_mb_stats);
4902 }
4903#endif
4904
4905 // If allowed, encoding tiles in parallel with one thread handling one tile.
4906 // TODO(geza.lore): The multi-threaded encoder is not safe with more than
4907 // 1 tile rows, as it uses the single above_context et al arrays from
4908 // cpi->common
Yaowu Xuf883b422016-08-30 14:01:10 -07004909 if (AOMMIN(cpi->oxcf.max_threads, cm->tile_cols) > 1 && cm->tile_rows == 1)
4910 av1_encode_tiles_mt(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004911 else
4912 encode_tiles(cpi);
4913
Yaowu Xuf883b422016-08-30 14:01:10 -07004914 aom_usec_timer_mark(&emr_timer);
4915 cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004916 }
4917
4918#if 0
4919 // Keep record of the total distortion this time around for future use
4920 cpi->last_frame_distortion = cpi->frame_distortion;
4921#endif
4922}
4923
Yaowu Xuf883b422016-08-30 14:01:10 -07004924void av1_encode_frame(AV1_COMP *cpi) {
4925 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004926
4927 // In the longer term the encoder should be generalized to match the
4928 // decoder such that we allow compound where one of the 3 buffers has a
4929 // different sign bias and that buffer is then the fixed ref. However, this
4930 // requires further work in the rd loop. For now the only supported encoder
4931 // side behavior is where the ALT ref buffer has opposite sign bias to
4932 // the other two.
4933 if (!frame_is_intra_only(cm)) {
4934 if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4935 cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
4936 (cm->ref_frame_sign_bias[ALTREF_FRAME] ==
4937 cm->ref_frame_sign_bias[LAST_FRAME])) {
4938 cpi->allow_comp_inter_inter = 0;
4939 } else {
4940 cpi->allow_comp_inter_inter = 1;
4941
4942#if CONFIG_EXT_REFS
4943 cm->comp_fwd_ref[0] = LAST_FRAME;
4944 cm->comp_fwd_ref[1] = LAST2_FRAME;
4945 cm->comp_fwd_ref[2] = LAST3_FRAME;
4946 cm->comp_fwd_ref[3] = GOLDEN_FRAME;
4947 cm->comp_bwd_ref[0] = BWDREF_FRAME;
4948 cm->comp_bwd_ref[1] = ALTREF_FRAME;
4949#else
4950 cm->comp_fixed_ref = ALTREF_FRAME;
4951 cm->comp_var_ref[0] = LAST_FRAME;
4952 cm->comp_var_ref[1] = GOLDEN_FRAME;
4953#endif // CONFIG_EXT_REFS
4954 }
4955 } else {
4956 cpi->allow_comp_inter_inter = 0;
4957 }
4958
4959 if (cpi->sf.frame_parameter_update) {
4960 int i;
4961 RD_OPT *const rd_opt = &cpi->rd;
4962 FRAME_COUNTS *counts = cpi->td.counts;
4963 RD_COUNTS *const rdc = &cpi->td.rd_counts;
4964
4965 // This code does a single RD pass over the whole frame assuming
4966 // either compound, single or hybrid prediction as per whatever has
4967 // worked best for that type of frame in the past.
4968 // It also predicts whether another coding mode would have worked
4969 // better than this coding mode. If that is the case, it remembers
4970 // that for subsequent frames.
4971 // It does the same analysis for transform size selection also.
4972 //
4973 // TODO(zoeliu): To investigate whether a frame_type other than
4974 // INTRA/ALTREF/GOLDEN/LAST needs to be specified seperately.
4975 const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi);
4976 int64_t *const mode_thrs = rd_opt->prediction_type_threshes[frame_type];
4977 const int is_alt_ref = frame_type == ALTREF_FRAME;
4978
4979 /* prediction (compound, single or hybrid) mode selection */
4980 if (is_alt_ref || !cpi->allow_comp_inter_inter)
4981 cm->reference_mode = SINGLE_REFERENCE;
4982 else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
4983 mode_thrs[COMPOUND_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT] &&
4984 check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
4985 cm->reference_mode = COMPOUND_REFERENCE;
4986 else if (mode_thrs[SINGLE_REFERENCE] > mode_thrs[REFERENCE_MODE_SELECT])
4987 cm->reference_mode = SINGLE_REFERENCE;
4988 else
4989 cm->reference_mode = REFERENCE_MODE_SELECT;
4990
4991#if CONFIG_DUAL_FILTER
4992 cm->interp_filter = SWITCHABLE;
4993#endif
4994
4995 encode_frame_internal(cpi);
4996
4997 for (i = 0; i < REFERENCE_MODES; ++i)
4998 mode_thrs[i] = (mode_thrs[i] + rdc->comp_pred_diff[i] / cm->MBs) / 2;
4999
5000 if (cm->reference_mode == REFERENCE_MODE_SELECT) {
5001 int single_count_zero = 0;
5002 int comp_count_zero = 0;
5003
5004 for (i = 0; i < COMP_INTER_CONTEXTS; i++) {
5005 single_count_zero += counts->comp_inter[i][0];
5006 comp_count_zero += counts->comp_inter[i][1];
5007 }
5008
5009 if (comp_count_zero == 0) {
5010 cm->reference_mode = SINGLE_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005011 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005012 } else if (single_count_zero == 0) {
5013 cm->reference_mode = COMPOUND_REFERENCE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005014 av1_zero(counts->comp_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005015 }
5016 }
5017
Jingning Han9777afc2016-10-20 15:17:43 -07005018#if CONFIG_VAR_TX
5019 if (cm->tx_mode == TX_MODE_SELECT && cpi->td.mb.txb_split_count == 0)
5020 cm->tx_mode = ALLOW_32X32;
5021#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005022 if (cm->tx_mode == TX_MODE_SELECT) {
5023 int count4x4 = 0;
5024 int count8x8_lp = 0, count8x8_8x8p = 0;
5025 int count16x16_16x16p = 0, count16x16_lp = 0;
5026 int count32x32 = 0;
5027 for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
Jingning Han2adcfb12016-10-27 11:19:53 -07005028 // counts->tx_size[max_depth][context_idx][this_depth_level]
5029 count4x4 += counts->tx_size[0][i][0];
5030 count4x4 += counts->tx_size[1][i][0];
5031 count4x4 += counts->tx_size[2][i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005032
Jingning Han2adcfb12016-10-27 11:19:53 -07005033 count8x8_lp += counts->tx_size[1][i][1];
5034 count8x8_lp += counts->tx_size[2][i][1];
5035 count8x8_8x8p += counts->tx_size[0][i][1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005036
Jingning Han2adcfb12016-10-27 11:19:53 -07005037 count16x16_16x16p += counts->tx_size[1][i][2];
5038 count16x16_lp += counts->tx_size[2][i][2];
5039 count32x32 += counts->tx_size[2][i][3];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005040 }
5041#if CONFIG_EXT_TX && CONFIG_RECT_TX
5042 count4x4 += counts->tx_size_implied[0][TX_4X4];
5043 count4x4 += counts->tx_size_implied[1][TX_4X4];
5044 count4x4 += counts->tx_size_implied[2][TX_4X4];
5045 count4x4 += counts->tx_size_implied[3][TX_4X4];
5046 count8x8_lp += counts->tx_size_implied[2][TX_8X8];
5047 count8x8_lp += counts->tx_size_implied[3][TX_8X8];
5048 count8x8_8x8p += counts->tx_size_implied[1][TX_8X8];
5049 count16x16_lp += counts->tx_size_implied[3][TX_16X16];
5050 count16x16_16x16p += counts->tx_size_implied[2][TX_16X16];
5051 count32x32 += counts->tx_size_implied[3][TX_32X32];
5052#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5053 if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 &&
5054#if CONFIG_SUPERTX
5055 cm->counts.supertx_size[TX_16X16] == 0 &&
5056 cm->counts.supertx_size[TX_32X32] == 0 &&
5057#endif // CONFIG_SUPERTX
5058 count32x32 == 0) {
5059 cm->tx_mode = ALLOW_8X8;
5060 reset_skip_tx_size(cm, TX_8X8);
5061 } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 &&
5062 count8x8_lp == 0 && count16x16_lp == 0 &&
5063#if CONFIG_SUPERTX
5064 cm->counts.supertx_size[TX_8X8] == 0 &&
5065 cm->counts.supertx_size[TX_16X16] == 0 &&
5066 cm->counts.supertx_size[TX_32X32] == 0 &&
5067#endif // CONFIG_SUPERTX
5068 count32x32 == 0) {
5069 cm->tx_mode = ONLY_4X4;
5070 reset_skip_tx_size(cm, TX_4X4);
5071 } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) {
5072 cm->tx_mode = ALLOW_32X32;
5073 } else if (count32x32 == 0 && count8x8_lp == 0 &&
5074#if CONFIG_SUPERTX
5075 cm->counts.supertx_size[TX_32X32] == 0 &&
5076#endif // CONFIG_SUPERTX
5077 count4x4 == 0) {
5078 cm->tx_mode = ALLOW_16X16;
5079 reset_skip_tx_size(cm, TX_16X16);
5080 }
5081 }
5082#endif
5083 } else {
5084 encode_frame_internal(cpi);
5085 }
5086}
5087
5088static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi,
5089 const MODE_INFO *above_mi, const MODE_INFO *left_mi,
5090 const int intraonly) {
5091 const PREDICTION_MODE y_mode = mi->mbmi.mode;
5092 const PREDICTION_MODE uv_mode = mi->mbmi.uv_mode;
5093 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
5094
5095 if (bsize < BLOCK_8X8) {
5096 int idx, idy;
5097 const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
5098 const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
5099 for (idy = 0; idy < 2; idy += num_4x4_h)
5100 for (idx = 0; idx < 2; idx += num_4x4_w) {
5101 const int bidx = idy * 2 + idx;
5102 const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
5103 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005104 const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
5105 const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005106 ++counts->kf_y_mode[a][l][bmode];
5107 } else {
5108 ++counts->y_mode[0][bmode];
5109 }
5110 }
5111 } else {
5112 if (intraonly) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005113 const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
5114 const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005115 ++counts->kf_y_mode[above][left][y_mode];
5116 } else {
5117 ++counts->y_mode[size_group_lookup[bsize]][y_mode];
5118 }
5119 }
5120
5121 ++counts->uv_mode[y_mode][uv_mode];
5122}
5123
5124#if CONFIG_VAR_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005125static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
Jingning Hanc8b89362016-11-01 10:28:53 -07005126 FRAME_COUNTS *counts, TX_SIZE tx_size, int depth,
Jingning Han9777afc2016-10-20 15:17:43 -07005127 int blk_row, int blk_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005128 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5129 const int tx_row = blk_row >> 1;
5130 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005131 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5132 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005133 int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
Jingning Hanc8b89362016-11-01 10:28:53 -07005134 xd->left_txfm_context + tx_row,
5135 mbmi->sb_type, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005136 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5137
Yaowu Xuc27fc142016-08-22 16:08:15 -07005138 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5139
5140 if (tx_size == plane_tx_size) {
5141 ++counts->txfm_partition[ctx][0];
5142 mbmi->tx_size = tx_size;
5143 txfm_partition_update(xd->above_txfm_context + tx_col,
5144 xd->left_txfm_context + tx_row, tx_size);
5145 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005146 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5147 const int bs = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005148 int i;
Jingning Hana9336322016-11-02 15:45:07 -07005149
Yaowu Xuc27fc142016-08-22 16:08:15 -07005150 ++counts->txfm_partition[ctx][1];
Jingning Han9777afc2016-10-20 15:17:43 -07005151 ++x->txb_split_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005152
5153 if (tx_size == TX_8X8) {
5154 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5155 mbmi->tx_size = TX_4X4;
5156 txfm_partition_update(xd->above_txfm_context + tx_col,
5157 xd->left_txfm_context + tx_row, TX_4X4);
5158 return;
5159 }
5160
5161 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005162 int offsetr = (i >> 1) * bs;
5163 int offsetc = (i & 0x01) * bs;
5164 update_txfm_count(x, xd, counts, sub_txs, depth + 1, blk_row + offsetr,
5165 blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005166 }
5167 }
5168}
5169
Jingning Han9777afc2016-10-20 15:17:43 -07005170static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
5171 BLOCK_SIZE plane_bsize, int mi_row,
5172 int mi_col, FRAME_COUNTS *td_counts) {
5173 MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005174 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5175 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005176 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005177 const int bh = tx_size_high_unit[max_tx_size];
5178 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005179 int idx, idy;
5180
5181 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5182 xd->left_txfm_context =
5183 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5184
5185 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005186 for (idx = 0; idx < mi_width; idx += bw)
Jingning Hanc8b89362016-11-01 10:28:53 -07005187 update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
5188 idy, idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005189}
5190
5191static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
5192 int blk_col) {
5193 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
5194 const int tx_row = blk_row >> 1;
5195 const int tx_col = blk_col >> 1;
Jingning Hanf65b8702016-10-31 12:13:20 -07005196 const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
5197 const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005198 const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
5199
Yaowu Xuc27fc142016-08-22 16:08:15 -07005200 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
5201
5202 if (tx_size == plane_tx_size) {
5203 mbmi->tx_size = tx_size;
5204 txfm_partition_update(xd->above_txfm_context + tx_col,
5205 xd->left_txfm_context + tx_row, tx_size);
5206
5207 } else {
Jingning Hana9336322016-11-02 15:45:07 -07005208 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
5209 const int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210 int i;
5211
5212 if (tx_size == TX_8X8) {
5213 mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
5214 mbmi->tx_size = TX_4X4;
5215 txfm_partition_update(xd->above_txfm_context + tx_col,
5216 xd->left_txfm_context + tx_row, TX_4X4);
5217 return;
5218 }
5219
5220 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005221 for (i = 0; i < 4; ++i) {
Jingning Hana9336322016-11-02 15:45:07 -07005222 int offsetr = (i >> 1) * bsl;
5223 int offsetc = (i & 0x01) * bsl;
5224 set_txfm_context(xd, sub_txs, blk_row + offsetr, blk_col + offsetc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005225 }
5226 }
5227}
5228
Urvang Joshi52648442016-10-13 17:27:51 -07005229static void tx_partition_set_contexts(const AV1_COMMON *const cm,
5230 MACROBLOCKD *xd, BLOCK_SIZE plane_bsize,
5231 int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005232 const int mi_width = num_4x4_blocks_wide_lookup[plane_bsize];
5233 const int mi_height = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han70e5f3f2016-11-09 17:03:07 -08005234 TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Jingning Hana9336322016-11-02 15:45:07 -07005235 const int bh = tx_size_high_unit[max_tx_size];
5236 const int bw = tx_size_wide_unit[max_tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005237 int idx, idy;
5238
5239 xd->above_txfm_context = cm->above_txfm_context + mi_col;
5240 xd->left_txfm_context =
5241 xd->left_txfm_context_buffer + (mi_row & MAX_MIB_MASK);
5242
5243 for (idy = 0; idy < mi_height; idy += bh)
Jingning Hana9336322016-11-02 15:45:07 -07005244 for (idx = 0; idx < mi_width; idx += bw)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005245 set_txfm_context(xd, max_tx_size, idy, idx);
5246}
5247#endif
5248
Urvang Joshi52648442016-10-13 17:27:51 -07005249static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
5250 TOKENEXTRA **t, RUN_TYPE dry_run, int mi_row,
5251 int mi_col, BLOCK_SIZE bsize,
5252 PICK_MODE_CONTEXT *ctx, int *rate) {
5253 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005254 MACROBLOCK *const x = &td->mb;
5255 MACROBLOCKD *const xd = &x->e_mbd;
5256 MODE_INFO **mi_8x8 = xd->mi;
5257 MODE_INFO *mi = mi_8x8[0];
5258 MB_MODE_INFO *mbmi = &mi->mbmi;
5259 const int seg_skip =
5260 segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP);
5261 const int mis = cm->mi_stride;
5262 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5263 const int mi_height = num_8x8_blocks_high_lookup[bsize];
Jingning Han94ea1aa2016-11-08 12:10:46 -08005264 const int is_inter = is_inter_block(mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005265
Yaowu Xuc27fc142016-08-22 16:08:15 -07005266 x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
5267
Yushin Cho77bba8d2016-11-04 16:36:56 -07005268#if CONFIG_PVQ
5269 x->pvq_speed = 0;
Yushin Choc97f6d52016-11-09 14:05:57 -08005270 x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07005271#endif
5272
Jingning Han94ea1aa2016-11-08 12:10:46 -08005273 if (!is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005274 int plane;
5275 mbmi->skip = 1;
5276 for (plane = 0; plane < MAX_MB_PLANE; ++plane)
Angie Chiangff6d8902016-10-21 11:02:09 -07005277 av1_encode_intra_block_plane((AV1_COMMON *)cm, x,
5278 AOMMAX(bsize, BLOCK_8X8), plane, 1);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005279 if (!dry_run)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005280 sum_intra_stats(td->counts, mi, xd->above_mi, xd->left_mi,
5281 frame_is_intra_only(cm));
5282
hui su5db97432016-10-14 16:10:14 -07005283 // TODO(huisu): move this into sum_intra_stats().
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005284 if (!dry_run && bsize >= BLOCK_8X8) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005285 FRAME_COUNTS *counts = td->counts;
hui su5db97432016-10-14 16:10:14 -07005286 (void)counts;
5287#if CONFIG_FILTER_INTRA
Urvang Joshib100db72016-10-12 16:28:56 -07005288 if (mbmi->mode == DC_PRED
5289#if CONFIG_PALETTE
5290 && mbmi->palette_mode_info.palette_size[0] == 0
5291#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005292 ) {
5293 const int use_filter_intra_mode =
5294 mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
5295 ++counts->filter_intra[0][use_filter_intra_mode];
5296 }
Urvang Joshib100db72016-10-12 16:28:56 -07005297 if (mbmi->uv_mode == DC_PRED
5298#if CONFIG_PALETTE
5299 && mbmi->palette_mode_info.palette_size[1] == 0
5300#endif // CONFIG_PALETTE
hui su5db97432016-10-14 16:10:14 -07005301 ) {
5302 const int use_filter_intra_mode =
5303 mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
5304 ++counts->filter_intra[1][use_filter_intra_mode];
5305 }
5306#endif // CONFIG_FILTER_INTRA
5307#if CONFIG_EXT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07005308 if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
5309 int p_angle;
Yaowu Xuf883b422016-08-30 14:01:10 -07005310 const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005311 p_angle =
5312 mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xuf883b422016-08-30 14:01:10 -07005313 if (av1_is_intra_filter_switchable(p_angle))
Yaowu Xuc27fc142016-08-22 16:08:15 -07005314 ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter];
5315 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005316#endif // CONFIG_EXT_INTRA
hui su5db97432016-10-14 16:10:14 -07005317 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005318
Urvang Joshib100db72016-10-12 16:28:56 -07005319#if CONFIG_PALETTE
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005320 if (bsize >= BLOCK_8X8 && !dry_run) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005321 for (plane = 0; plane <= 1; ++plane) {
5322 if (mbmi->palette_mode_info.palette_size[plane] > 0) {
5323 mbmi->palette_mode_info.palette_first_color_idx[plane] =
5324 xd->plane[plane].color_index_map[0];
5325 // TODO(huisu): this increases the use of token buffer. Needs stretch
5326 // test to verify.
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005327 av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005328 }
5329 }
5330 }
Urvang Joshib100db72016-10-12 16:28:56 -07005331#endif // CONFIG_PALETTE
Jingning Hane67b38a2016-11-04 10:30:00 -07005332#if CONFIG_VAR_TX
5333 mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
5334#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005335 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005336 } else {
5337 int ref;
5338 const int is_compound = has_second_ref(mbmi);
5339
5340 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5341 for (ref = 0; ref < 1 + is_compound; ++ref) {
5342 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
5343 assert(cfg != NULL);
Yaowu Xuf883b422016-08-30 14:01:10 -07005344 av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
5345 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005346 }
5347 if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
Yaowu Xuf883b422016-08-30 14:01:10 -07005348 av1_build_inter_predictors_sby(xd, mi_row, mi_col,
5349 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005350
Yaowu Xuf883b422016-08-30 14:01:10 -07005351 av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
5352 AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005353
Yue Chencb60b182016-10-13 15:18:22 -07005354#if CONFIG_MOTION_VAR
5355 if (mbmi->motion_mode == OBMC_CAUSAL) {
Yue Chen894fcce2016-10-21 16:50:52 -07005356 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357 }
Yue Chencb60b182016-10-13 15:18:22 -07005358#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07005359
Angie Chiangff6d8902016-10-21 11:02:09 -07005360 av1_encode_sb((AV1_COMMON *)cm, x, AOMMAX(bsize, BLOCK_8X8));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005361#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005362 if (mbmi->skip) mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005363#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005364 if (is_rect_tx(mbmi->tx_size))
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005365 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005366 else
5367#endif
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005368 av1_tokenize_sb_vartx(cpi, td, t, dry_run, mi_row, mi_col,
5369 AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005370#else
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005371 av1_tokenize_sb(cpi, td, t, dry_run, AOMMAX(bsize, BLOCK_8X8), rate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005372#endif
5373 }
5374
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005375 if (!dry_run) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005376#if CONFIG_VAR_TX
5377 TX_SIZE tx_size =
5378 is_inter && !mbmi->skip ? mbmi->min_tx_size : mbmi->tx_size;
5379#else
5380 TX_SIZE tx_size = mbmi->tx_size;
5381#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005382 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 &&
Jingning Han94ea1aa2016-11-08 12:10:46 -08005383 !(is_inter && (mbmi->skip || seg_skip))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005384 const int tx_size_ctx = get_tx_size_context(xd);
5385 const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
5386 : intra_tx_size_cat_lookup[bsize];
Jingning Hane67b38a2016-11-04 10:30:00 -07005387 const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
Jingning Han4e1737a2016-10-25 16:05:02 -07005388 const int depth = tx_size_to_depth(coded_tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389#if CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005390 assert(IMPLIES(is_rect_tx(tx_size), is_rect_tx_allowed(xd, mbmi)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07005391#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5392#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07005393#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chen49587a72016-09-28 17:09:47 -07005394 if (is_rect_tx_allowed(xd, mbmi)) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005395 td->counts->rect_tx[tx_size_cat][is_rect_tx(tx_size)]++;
Yue Chena1e48dc2016-08-29 17:29:33 -07005396 }
Jingning Hane67b38a2016-11-04 10:30:00 -07005397 if (!is_rect_tx_allowed(xd, mbmi) || !is_rect_tx(tx_size)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005398#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Jingning Han9777afc2016-10-20 15:17:43 -07005399 if (is_inter) {
5400 tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
5401 } else {
Jingning Han4e1737a2016-10-25 16:05:02 -07005402 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Hane67b38a2016-11-04 10:30:00 -07005403 if (tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005404 }
Yue Chena1e48dc2016-08-29 17:29:33 -07005405#if CONFIG_EXT_TX && CONFIG_RECT_TX
5406 }
5407#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005408#endif
Jingning Handc9ad312016-10-20 12:00:15 -07005409#if !CONFIG_VAR_TX
Jingning Han4e1737a2016-10-25 16:05:02 -07005410 ++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
Jingning Handc9ad312016-10-20 12:00:15 -07005411#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005412 } else {
Urvang Joshi454280d2016-10-14 16:51:44 -07005413 int i, j;
Jingning Hane67b38a2016-11-04 10:30:00 -07005414 TX_SIZE intra_tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005415 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005416 if (is_inter) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005417 if (xd->lossless[mbmi->segment_id]) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005418 intra_tx_size = TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005419 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005420 intra_tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005421 }
5422#if CONFIG_EXT_TX && CONFIG_RECT_TX
5423 ++td->counts->tx_size_implied[max_txsize_lookup[bsize]]
Jingning Hane67b38a2016-11-04 10:30:00 -07005424 [txsize_sqr_up_map[tx_size]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005425#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
5426 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005427 intra_tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005428 }
5429
Urvang Joshi454280d2016-10-14 16:51:44 -07005430 for (j = 0; j < mi_height; j++)
5431 for (i = 0; i < mi_width; i++)
5432 if (mi_col + i < cm->mi_cols && mi_row + j < cm->mi_rows)
Jingning Hane67b38a2016-11-04 10:30:00 -07005433 mi_8x8[mis * j + i]->mbmi.tx_size = intra_tx_size;
Jingning Han9777afc2016-10-20 15:17:43 -07005434
5435#if CONFIG_VAR_TX
Jingning Hane67b38a2016-11-04 10:30:00 -07005436 mbmi->min_tx_size = get_min_tx_size(intra_tx_size);
5437 if (intra_tx_size != max_txsize_lookup[bsize]) ++x->txb_split_count;
Jingning Han9777afc2016-10-20 15:17:43 -07005438#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005439 }
Jingning Han9777afc2016-10-20 15:17:43 -07005440
Jingning Hane67b38a2016-11-04 10:30:00 -07005441 ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07005442 ++td->counts
5443 ->tx_size_totals[txsize_sqr_map[get_uv_tx_size(mbmi, &xd->plane[1])]];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005444#if CONFIG_EXT_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005445 if (get_ext_tx_types(tx_size, bsize, is_inter) > 1 && cm->base_qindex > 0 &&
5446 !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005447 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005448 int eset = get_ext_tx_set(tx_size, bsize, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005449 if (eset > 0) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005450 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005451 ++td->counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
Yaowu Xuc27fc142016-08-22 16:08:15 -07005452 [mbmi->tx_type];
5453 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005454 ++td->counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005455 }
5456 }
5457 }
5458#else
Jingning Hane67b38a2016-11-04 10:30:00 -07005459 if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07005460 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
Jingning Han94ea1aa2016-11-08 12:10:46 -08005461 if (is_inter) {
Jingning Hane67b38a2016-11-04 10:30:00 -07005462 ++td->counts->inter_ext_tx[tx_size][mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005463 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005464 ++td->counts->intra_ext_tx[tx_size]
clang-format67948d32016-09-07 22:40:40 -07005465 [intra_mode_to_tx_type_context[mbmi->mode]]
5466 [mbmi->tx_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -07005467 }
5468 }
5469#endif // CONFIG_EXT_TX
5470 }
5471
5472#if CONFIG_VAR_TX
Jingning Han94ea1aa2016-11-08 12:10:46 -08005473 if (cm->tx_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_8X8 && is_inter &&
5474 !(mbmi->skip || seg_skip)) {
Yue Chena1e48dc2016-08-29 17:29:33 -07005475#if CONFIG_EXT_TX && CONFIG_RECT_TX
5476 if (is_rect_tx(mbmi->tx_size)) {
5477 set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, xd);
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005478 } else {
5479 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005480 }
Peter de Rivaz74d0ad82016-10-19 11:43:11 +01005481#else
5482 if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
Yue Chena1e48dc2016-08-29 17:29:33 -07005483#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
Yaowu Xuc27fc142016-08-22 16:08:15 -07005484 } else {
Jingning Hane67b38a2016-11-04 10:30:00 -07005485 TX_SIZE tx_size = mbmi->tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005486 // The new intra coding scheme requires no change of transform size
Jingning Han94ea1aa2016-11-08 12:10:46 -08005487 if (is_inter)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005488#if CONFIG_EXT_TX && CONFIG_RECT_TX
5489 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005490 tx_size = AOMMIN(tx_mode_to_biggest_tx_size[cm->tx_mode],
Yaowu Xuc27fc142016-08-22 16:08:15 -07005491 max_txsize_lookup[bsize]);
5492 if (txsize_sqr_map[max_txsize_rect_lookup[bsize]] <= tx_size)
5493 tx_size = max_txsize_rect_lookup[bsize];
5494 if (xd->lossless[mbmi->segment_id]) tx_size = TX_4X4;
5495 }
5496#else
Jingning Han4ca8b1c2016-11-08 10:05:08 -08005497 tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005498#endif
5499 else
Jingning Hane67b38a2016-11-04 10:30:00 -07005500 tx_size = (bsize >= BLOCK_8X8) ? tx_size : TX_4X4;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005501 mbmi->tx_size = tx_size;
Jingning Han1b1dc932016-11-09 10:55:30 -08005502 set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005503 }
5504#endif
5505}
5506
5507#if CONFIG_SUPERTX
5508static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
5509 if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
5510#if CONFIG_EXT_INTER
5511 if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
5512#endif // CONFIG_EXT_INTER
5513 return 0;
5514}
5515
Urvang Joshi52648442016-10-13 17:27:51 -07005516static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
5517 int mi_row, int mi_col, BLOCK_SIZE bsize,
5518 PC_TREE *pc_tree) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005519 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005520
5521 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5522 const PARTITION_TYPE partition = pc_tree->partitioning;
5523 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5524#if CONFIG_EXT_PARTITION_TYPES
5525 int i;
5526#endif
5527
5528 assert(bsize >= BLOCK_8X8);
5529
5530 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return 1;
5531
5532 switch (partition) {
5533 case PARTITION_NONE: return check_intra_b(&pc_tree->none); break;
5534 case PARTITION_VERT:
5535 if (check_intra_b(&pc_tree->vertical[0])) return 1;
5536 if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
5537 if (check_intra_b(&pc_tree->vertical[1])) return 1;
5538 }
5539 break;
5540 case PARTITION_HORZ:
5541 if (check_intra_b(&pc_tree->horizontal[0])) return 1;
5542 if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
5543 if (check_intra_b(&pc_tree->horizontal[1])) return 1;
5544 }
5545 break;
5546 case PARTITION_SPLIT:
5547 if (bsize == BLOCK_8X8) {
5548 if (check_intra_b(pc_tree->leaf_split[0])) return 1;
5549 } else {
5550 if (check_intra_sb(cpi, tile, mi_row, mi_col, subsize,
5551 pc_tree->split[0]))
5552 return 1;
5553 if (check_intra_sb(cpi, tile, mi_row, mi_col + hbs, subsize,
5554 pc_tree->split[1]))
5555 return 1;
5556 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col, subsize,
5557 pc_tree->split[2]))
5558 return 1;
5559 if (check_intra_sb(cpi, tile, mi_row + hbs, mi_col + hbs, subsize,
5560 pc_tree->split[3]))
5561 return 1;
5562 }
5563 break;
5564#if CONFIG_EXT_PARTITION_TYPES
5565 case PARTITION_HORZ_A:
5566 for (i = 0; i < 3; i++) {
5567 if (check_intra_b(&pc_tree->horizontala[i])) return 1;
5568 }
5569 break;
5570 case PARTITION_HORZ_B:
5571 for (i = 0; i < 3; i++) {
5572 if (check_intra_b(&pc_tree->horizontalb[i])) return 1;
5573 }
5574 break;
5575 case PARTITION_VERT_A:
5576 for (i = 0; i < 3; i++) {
5577 if (check_intra_b(&pc_tree->verticala[i])) return 1;
5578 }
5579 break;
5580 case PARTITION_VERT_B:
5581 for (i = 0; i < 3; i++) {
5582 if (check_intra_b(&pc_tree->verticalb[i])) return 1;
5583 }
5584 break;
5585#endif // CONFIG_EXT_PARTITION_TYPES
5586 default: assert(0);
5587 }
5588 return 0;
5589}
5590
5591static int check_supertx_b(TX_SIZE supertx_size, PICK_MODE_CONTEXT *ctx) {
5592 return ctx->mic.mbmi.tx_size == supertx_size;
5593}
5594
5595static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
5596 PC_TREE *pc_tree) {
5597 PARTITION_TYPE partition;
5598 BLOCK_SIZE subsize;
5599
5600 partition = pc_tree->partitioning;
5601 subsize = get_subsize(bsize, partition);
5602 switch (partition) {
5603 case PARTITION_NONE: return check_supertx_b(supertx_size, &pc_tree->none);
5604 case PARTITION_VERT:
5605 return check_supertx_b(supertx_size, &pc_tree->vertical[0]);
5606 case PARTITION_HORZ:
5607 return check_supertx_b(supertx_size, &pc_tree->horizontal[0]);
5608 case PARTITION_SPLIT:
5609 if (bsize == BLOCK_8X8)
5610 return check_supertx_b(supertx_size, pc_tree->leaf_split[0]);
5611 else
5612 return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
5613#if CONFIG_EXT_PARTITION_TYPES
5614 case PARTITION_HORZ_A:
5615 return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
5616 case PARTITION_HORZ_B:
5617 return check_supertx_b(supertx_size, &pc_tree->horizontalb[0]);
5618 case PARTITION_VERT_A:
5619 return check_supertx_b(supertx_size, &pc_tree->verticala[0]);
5620 case PARTITION_VERT_B:
5621 return check_supertx_b(supertx_size, &pc_tree->verticalb[0]);
5622#endif // CONFIG_EXT_PARTITION_TYPES
5623 default: assert(0); return 0;
5624 }
5625}
5626
Urvang Joshi52648442016-10-13 17:27:51 -07005627static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005628#if CONFIG_EXT_INTER
5629 int mi_row_ori, int mi_col_ori,
5630#endif // CONFIG_EXT_INTER
5631 int mi_row_pred, int mi_col_pred,
5632 BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
5633 // Used in supertx
5634 // (mi_row_ori, mi_col_ori): location for mv
5635 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
Urvang Joshi52648442016-10-13 17:27:51 -07005636 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637 MACROBLOCK *const x = &td->mb;
5638 MACROBLOCKD *const xd = &x->e_mbd;
5639 MODE_INFO *mi_8x8 = xd->mi[0];
5640 MODE_INFO *mi = mi_8x8;
5641 MB_MODE_INFO *mbmi = &mi->mbmi;
5642 int ref;
5643 const int is_compound = has_second_ref(mbmi);
5644
5645 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5646
5647 for (ref = 0; ref < 1 + is_compound; ++ref) {
5648 YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, mbmi->ref_frame[ref]);
Yaowu Xuf883b422016-08-30 14:01:10 -07005649 av1_setup_pre_planes(xd, ref, cfg, mi_row_pred, mi_col_pred,
5650 &xd->block_refs[ref]->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005651 }
5652
5653 if (!b_sub8x8)
Yaowu Xuf883b422016-08-30 14:01:10 -07005654 av1_build_inter_predictors_sb_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005655#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005656 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005657#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005658 mi_row_pred, mi_col_pred, bsize_pred);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005659 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005660 av1_build_inter_predictors_sb_sub8x8_extend(xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005661#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005662 mi_row_ori, mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005663#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07005664 mi_row_pred, mi_col_pred,
5665 bsize_pred, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005666}
5667
Urvang Joshi52648442016-10-13 17:27:51 -07005668static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005669 const TileInfo *const tile, int block,
5670 int mi_row_ori, int mi_col_ori, int mi_row_pred,
5671 int mi_col_pred, int mi_row_top, int mi_col_top,
5672 uint8_t *dst_buf[3], int dst_stride[3],
5673 BLOCK_SIZE bsize_top, BLOCK_SIZE bsize_pred,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005674 RUN_TYPE dry_run, int b_sub8x8, int bextend) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005675 // Used in supertx
5676 // (mi_row_ori, mi_col_ori): location for mv
5677 // (mi_row_pred, mi_col_pred, bsize_pred): region to predict
5678 // (mi_row_top, mi_col_top, bsize_top): region of the top partition size
5679 // block: sub location of sub8x8 blocks
5680 // b_sub8x8: 1: ori is sub8x8; 0: ori is not sub8x8
5681 // bextend: 1: region to predict is an extension of ori; 0: not
5682
5683 MACROBLOCK *const x = &td->mb;
Urvang Joshi52648442016-10-13 17:27:51 -07005684 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005685 MACROBLOCKD *const xd = &x->e_mbd;
5686 int r = (mi_row_pred - mi_row_top) * MI_SIZE;
5687 int c = (mi_col_pred - mi_col_top) * MI_SIZE;
5688 const int mi_width_top = num_8x8_blocks_wide_lookup[bsize_top];
5689 const int mi_height_top = num_8x8_blocks_high_lookup[bsize_top];
5690
5691 if (mi_row_pred < mi_row_top || mi_col_pred < mi_col_top ||
5692 mi_row_pred >= mi_row_top + mi_height_top ||
5693 mi_col_pred >= mi_col_top + mi_width_top || mi_row_pred >= cm->mi_rows ||
5694 mi_col_pred >= cm->mi_cols)
5695 return;
5696
5697 set_offsets_extend(cpi, td, tile, mi_row_pred, mi_col_pred, mi_row_ori,
5698 mi_col_ori, bsize_pred);
5699 xd->plane[0].dst.stride = dst_stride[0];
5700 xd->plane[1].dst.stride = dst_stride[1];
5701 xd->plane[2].dst.stride = dst_stride[2];
5702 xd->plane[0].dst.buf = dst_buf[0] +
5703 (r >> xd->plane[0].subsampling_y) * dst_stride[0] +
5704 (c >> xd->plane[0].subsampling_x);
5705 xd->plane[1].dst.buf = dst_buf[1] +
5706 (r >> xd->plane[1].subsampling_y) * dst_stride[1] +
5707 (c >> xd->plane[1].subsampling_x);
5708 xd->plane[2].dst.buf = dst_buf[2] +
5709 (r >> xd->plane[2].subsampling_y) * dst_stride[2] +
5710 (c >> xd->plane[2].subsampling_x);
5711
5712 predict_superblock(cpi, td,
5713#if CONFIG_EXT_INTER
5714 mi_row_ori, mi_col_ori,
5715#endif // CONFIG_EXT_INTER
5716 mi_row_pred, mi_col_pred, bsize_pred, b_sub8x8, block);
5717
Yaowu Xu5bb8f5b2016-11-02 15:31:29 -07005718 if (!dry_run && !bextend) {
5719#if CONFIG_SUPERTX
5720 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
5721#else
5722 update_stats(&cpi->common, td, mi_row_pred, mi_col_pred);
5723#endif
5724 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005725}
5726
Urvang Joshi52648442016-10-13 17:27:51 -07005727static void extend_dir(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005728 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5729 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005730 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005731 uint8_t *dst_buf[3], int dst_stride[3], int dir) {
5732 // dir: 0-lower, 1-upper, 2-left, 3-right
5733 // 4-lowerleft, 5-upperleft, 6-lowerright, 7-upperright
5734 MACROBLOCKD *xd = &td->mb.e_mbd;
5735 const int mi_width = num_8x8_blocks_wide_lookup[bsize];
5736 const int mi_height = num_8x8_blocks_high_lookup[bsize];
5737 int xss = xd->plane[1].subsampling_x;
5738 int yss = xd->plane[1].subsampling_y;
5739 int b_sub8x8 = (bsize < BLOCK_8X8) ? 1 : 0;
5740
5741 BLOCK_SIZE extend_bsize;
5742 int unit, mi_row_pred, mi_col_pred;
5743
5744 if (dir == 0 || dir == 1) { // lower and upper
5745 extend_bsize = (mi_width == 1 || bsize < BLOCK_8X8 || xss < yss)
5746 ? BLOCK_8X8
5747 : BLOCK_16X8;
5748 unit = num_8x8_blocks_wide_lookup[extend_bsize];
5749 mi_row_pred = mi_row + ((dir == 0) ? mi_height : -1);
5750 mi_col_pred = mi_col;
5751
5752 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5753 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005754 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005755
5756 if (mi_width > unit) {
5757 int i;
5758 for (i = 0; i < mi_width / unit - 1; i++) {
5759 mi_col_pred += unit;
5760 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5761 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005762 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5763 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005764 }
5765 }
5766 } else if (dir == 2 || dir == 3) { // left and right
5767 extend_bsize = (mi_height == 1 || bsize < BLOCK_8X8 || yss < xss)
5768 ? BLOCK_8X8
5769 : BLOCK_8X16;
5770 unit = num_8x8_blocks_high_lookup[extend_bsize];
5771 mi_row_pred = mi_row;
5772 mi_col_pred = mi_col + ((dir == 3) ? mi_width : -1);
5773
5774 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5775 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005776 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005777
5778 if (mi_height > unit) {
5779 int i;
5780 for (i = 0; i < mi_height / unit - 1; i++) {
5781 mi_row_pred += unit;
5782 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5783 mi_col_pred, mi_row_top, mi_col_top, dst_buf,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005784 dst_stride, top_bsize, extend_bsize, dry_run, b_sub8x8,
5785 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005786 }
5787 }
5788 } else {
5789 extend_bsize = BLOCK_8X8;
5790 mi_row_pred = mi_row + ((dir == 4 || dir == 6) ? mi_height : -1);
5791 mi_col_pred = mi_col + ((dir == 6 || dir == 7) ? mi_width : -1);
5792
5793 predict_b_extend(cpi, td, tile, block, mi_row, mi_col, mi_row_pred,
5794 mi_col_pred, mi_row_top, mi_col_top, dst_buf, dst_stride,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005795 top_bsize, extend_bsize, dry_run, b_sub8x8, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005796 }
5797}
5798
Urvang Joshi52648442016-10-13 17:27:51 -07005799static void extend_all(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005800 const TileInfo *const tile, int block, BLOCK_SIZE bsize,
5801 BLOCK_SIZE top_bsize, int mi_row, int mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005802 int mi_row_top, int mi_col_top, RUN_TYPE dry_run,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005803 uint8_t *dst_buf[3], int dst_stride[3]) {
5804 assert(block >= 0 && block < 4);
5805 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, 0);
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, 1);
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, 2);
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, 3);
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, 4);
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, 5);
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, 6);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005819 extend_dir(cpi, td, tile, block, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005820 mi_col_top, dry_run, dst_buf, dst_stride, 7);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005821}
5822
5823// This function generates prediction for multiple blocks, between which
5824// discontinuity around boundary is reduced by smoothing masks. The basic
5825// smoothing mask is a soft step function along horz/vert direction. In more
5826// complicated case when a block is split into 4 subblocks, the basic mask is
5827// first applied to neighboring subblocks (2 pairs) in horizontal direction and
5828// then applied to the 2 masked prediction mentioned above in vertical direction
5829// If the block is split into more than one level, at every stage, masked
5830// prediction is stored in dst_buf[] passed from higher level.
Urvang Joshi52648442016-10-13 17:27:51 -07005831static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005832 const TileInfo *const tile, int mi_row,
5833 int mi_col, int mi_row_top, int mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005834 RUN_TYPE dry_run, BLOCK_SIZE bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005835 BLOCK_SIZE top_bsize, uint8_t *dst_buf[3],
5836 int dst_stride[3], PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07005837 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005838 MACROBLOCK *const x = &td->mb;
5839 MACROBLOCKD *const xd = &x->e_mbd;
5840
5841 const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
5842 const int hbs = num_8x8_blocks_wide_lookup[bsize] / 2;
5843 const PARTITION_TYPE partition = pc_tree->partitioning;
5844 const BLOCK_SIZE subsize = get_subsize(bsize, partition);
5845#if CONFIG_EXT_PARTITION_TYPES
5846 const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
5847#endif
5848
5849 int i;
5850 uint8_t *dst_buf1[3], *dst_buf2[3], *dst_buf3[3];
5851 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5852 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5853 DECLARE_ALIGNED(16, uint8_t, tmp_buf3[MAX_MB_PLANE * MAX_TX_SQUARE * 2]);
5854 int dst_stride1[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5855 int dst_stride2[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5856 int dst_stride3[3] = { MAX_TX_SIZE, MAX_TX_SIZE, MAX_TX_SIZE };
5857
5858 assert(bsize >= BLOCK_8X8);
5859
5860 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
5861
Yaowu Xuf883b422016-08-30 14:01:10 -07005862#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005863 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5864 int len = sizeof(uint16_t);
5865 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
5866 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_TX_SQUARE * len);
5867 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_TX_SQUARE * len);
5868 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
5869 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_TX_SQUARE * len);
5870 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_TX_SQUARE * len);
5871 dst_buf3[0] = CONVERT_TO_BYTEPTR(tmp_buf3);
5872 dst_buf3[1] = CONVERT_TO_BYTEPTR(tmp_buf3 + MAX_TX_SQUARE * len);
5873 dst_buf3[2] = CONVERT_TO_BYTEPTR(tmp_buf3 + 2 * MAX_TX_SQUARE * len);
5874 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07005875#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005876 dst_buf1[0] = tmp_buf1;
5877 dst_buf1[1] = tmp_buf1 + MAX_TX_SQUARE;
5878 dst_buf1[2] = tmp_buf1 + 2 * MAX_TX_SQUARE;
5879 dst_buf2[0] = tmp_buf2;
5880 dst_buf2[1] = tmp_buf2 + MAX_TX_SQUARE;
5881 dst_buf2[2] = tmp_buf2 + 2 * MAX_TX_SQUARE;
5882 dst_buf3[0] = tmp_buf3;
5883 dst_buf3[1] = tmp_buf3 + MAX_TX_SQUARE;
5884 dst_buf3[2] = tmp_buf3 + 2 * MAX_TX_SQUARE;
Yaowu Xuf883b422016-08-30 14:01:10 -07005885#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005886 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005887#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005888
Urvang Joshi52648442016-10-13 17:27:51 -07005889 if (!dry_run && bsize < top_bsize) {
5890 // Explicitly cast away const.
5891 FRAME_COUNTS *const frame_counts = (FRAME_COUNTS *)&cm->counts;
5892 frame_counts->partition[ctx][partition]++;
5893 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005894
5895 for (i = 0; i < MAX_MB_PLANE; i++) {
5896 xd->plane[i].dst.buf = dst_buf[i];
5897 xd->plane[i].dst.stride = dst_stride[i];
5898 }
5899
5900 switch (partition) {
5901 case PARTITION_NONE:
5902 assert(bsize < top_bsize);
5903 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5904 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005905 bsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005906 extend_all(cpi, td, tile, 0, bsize, top_bsize, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005907 mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005908 break;
5909 case PARTITION_HORZ:
5910 if (bsize == BLOCK_8X8) {
5911 // Fisrt half
5912 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5913 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005914 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005915 if (bsize < top_bsize)
5916 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005917 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005918
5919 // Second half
5920 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
5921 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005922 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005923 if (bsize < top_bsize)
5924 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005925 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005926
5927 // Smooth
5928 xd->plane[0].dst.buf = dst_buf[0];
5929 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005930 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005931 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5932 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
5933 0);
5934 } else {
5935 // First half
5936 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5937 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005938 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005939 if (bsize < top_bsize)
5940 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005941 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005942 else
5943 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005944 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005945
5946 if (mi_row + hbs < cm->mi_rows) {
5947 // Second half
5948 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
5949 mi_col, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005950 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005951 if (bsize < top_bsize)
5952 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005953 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005954 dst_stride1);
5955 else
5956 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005957 mi_col, mi_row_top, mi_col_top, dry_run, dst_buf1,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005958 dst_stride1, 1);
5959
5960 // Smooth
5961 for (i = 0; i < MAX_MB_PLANE; i++) {
5962 xd->plane[i].dst.buf = dst_buf[i];
5963 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07005964 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005965 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
5966 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
5967 PARTITION_HORZ, i);
5968 }
5969 }
5970 }
5971 break;
5972 case PARTITION_VERT:
5973 if (bsize == BLOCK_8X8) {
5974 // First half
5975 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
5976 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005977 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005978 if (bsize < top_bsize)
5979 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005980 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005981
5982 // Second half
5983 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
5984 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005985 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005986 if (bsize < top_bsize)
5987 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07005988 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005989
5990 // Smooth
5991 xd->plane[0].dst.buf = dst_buf[0];
5992 xd->plane[0].dst.stride = dst_stride[0];
Yaowu Xuf883b422016-08-30 14:01:10 -07005993 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005994 xd, dst_buf[0], dst_stride[0], dst_buf1[0], dst_stride1[0], mi_row,
5995 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
5996 0);
5997 } else {
5998 // bsize: not important, not useful
5999 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6000 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006001 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006002 if (bsize < top_bsize)
6003 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006004 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006005 else
6006 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006007 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006008
6009 if (mi_col + hbs < cm->mi_cols) {
6010 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6011 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006012 dst_stride1, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006013 if (bsize < top_bsize)
6014 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006015 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6016 dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006017 else
6018 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006019 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf1,
6020 dst_stride1, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006021
6022 for (i = 0; i < MAX_MB_PLANE; i++) {
6023 xd->plane[i].dst.buf = dst_buf[i];
6024 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006025 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006026 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6027 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6028 PARTITION_VERT, i);
6029 }
6030 }
6031 }
6032 break;
6033 case PARTITION_SPLIT:
6034 if (bsize == BLOCK_8X8) {
6035 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6036 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006037 BLOCK_8X8, dry_run, 1, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006038 predict_b_extend(cpi, td, tile, 1, mi_row, mi_col, mi_row, mi_col,
6039 mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006040 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006041 predict_b_extend(cpi, td, tile, 2, mi_row, mi_col, mi_row, mi_col,
6042 mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006043 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006044 predict_b_extend(cpi, td, tile, 3, mi_row, mi_col, mi_row, mi_col,
6045 mi_row_top, mi_col_top, dst_buf3, dst_stride3,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006046 top_bsize, BLOCK_8X8, dry_run, 1, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006047
6048 if (bsize < top_bsize) {
6049 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006050 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006051 extend_all(cpi, td, tile, 1, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006052 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006053 extend_all(cpi, td, tile, 2, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006054 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006055 extend_all(cpi, td, tile, 3, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006056 mi_row_top, mi_col_top, dry_run, dst_buf3, dst_stride3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006057 }
6058 } else {
6059 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006060 mi_col_top, dry_run, subsize, top_bsize, dst_buf,
6061 dst_stride, pc_tree->split[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006062 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6063 predict_sb_complex(cpi, td, tile, mi_row, mi_col + hbs, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006064 mi_col_top, dry_run, subsize, top_bsize, dst_buf1,
6065 dst_stride1, pc_tree->split[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006066 if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols)
6067 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col, mi_row_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006068 mi_col_top, dry_run, subsize, top_bsize, dst_buf2,
6069 dst_stride2, pc_tree->split[2]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006070 if (mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols)
6071 predict_sb_complex(cpi, td, tile, mi_row + hbs, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006072 mi_row_top, mi_col_top, dry_run, subsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006073 top_bsize, dst_buf3, dst_stride3,
6074 pc_tree->split[3]);
6075 }
6076 for (i = 0; i < MAX_MB_PLANE; i++) {
6077 if (bsize == BLOCK_8X8 && i != 0)
6078 continue; // Skip <4x4 chroma smoothing
6079 if (mi_row < cm->mi_rows && mi_col + hbs < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006080 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006081 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i],
6082 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6083 PARTITION_VERT, i);
6084 if (mi_row + hbs < cm->mi_rows) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006085 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006086 xd, dst_buf2[i], dst_stride2[i], dst_buf3[i], dst_stride3[i],
6087 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6088 PARTITION_VERT, i);
Yaowu Xuf883b422016-08-30 14:01:10 -07006089 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006090 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6091 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6092 PARTITION_HORZ, i);
6093 }
6094 } else if (mi_row + hbs < cm->mi_rows && mi_col < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006095 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006096 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i],
6097 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6098 PARTITION_HORZ, i);
6099 }
6100 }
6101 break;
6102#if CONFIG_EXT_PARTITION_TYPES
6103 case PARTITION_HORZ_A:
6104 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6105 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006106 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006107 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006108 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006109
6110 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6111 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006112 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006113 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006114 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006115
6116 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6117 mi_col, mi_row_top, mi_col_top, dst_buf2, dst_stride2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006118 top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006119 if (bsize < top_bsize)
6120 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006121 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006122 else
6123 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006124 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006125
6126 for (i = 0; i < MAX_MB_PLANE; i++) {
6127 xd->plane[i].dst.buf = dst_buf[i];
6128 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006129 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006130 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6131 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6132 i);
6133 }
6134 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006135 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006136 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6137 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6138 i);
6139 }
6140
6141 break;
6142 case PARTITION_VERT_A:
6143
6144 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6145 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006146 bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006147 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006148 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006149
6150 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6151 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006152 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006153 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006154 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006155
6156 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6157 mi_col + hbs, mi_row_top, mi_col_top, dst_buf2,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006158 dst_stride2, top_bsize, subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006159 if (bsize < top_bsize)
6160 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006161 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006162 else
6163 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006164 mi_row_top, mi_col_top, dry_run, dst_buf2, dst_stride2, 2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006165
6166 for (i = 0; i < MAX_MB_PLANE; i++) {
6167 xd->plane[i].dst.buf = dst_buf[i];
6168 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006169 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006170 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6171 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6172 i);
6173 }
6174 for (i = 0; i < MAX_MB_PLANE; i++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006175 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006176 xd, dst_buf[i], dst_stride[i], dst_buf2[i], dst_stride2[i], mi_row,
6177 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6178 i);
6179 }
6180 break;
6181 case PARTITION_HORZ_B:
6182
6183 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6184 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006185 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006186 if (bsize < top_bsize)
6187 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006188 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006189 else
6190 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006191 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006192
6193 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col, mi_row + hbs,
6194 mi_col, mi_row_top, mi_col_top, dst_buf1, dst_stride1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006195 top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006196 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006197 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006198
6199 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6200 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006201 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006202 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006203 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006204 dst_stride2);
6205
6206 for (i = 0; i < MAX_MB_PLANE; i++) {
6207 xd->plane[i].dst.buf = dst_buf1[i];
6208 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006209 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006210 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6211 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6212 PARTITION_VERT, i);
6213 }
6214 for (i = 0; i < MAX_MB_PLANE; i++) {
6215 xd->plane[i].dst.buf = dst_buf[i];
6216 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006217 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006218 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6219 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_HORZ,
6220 i);
6221 }
6222 break;
6223 case PARTITION_VERT_B:
6224
6225 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
6226 mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006227 subsize, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006228 if (bsize < top_bsize)
6229 extend_all(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006230 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006231 else
6232 extend_dir(cpi, td, tile, 0, subsize, top_bsize, mi_row, mi_col,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006233 mi_row_top, mi_col_top, dry_run, dst_buf, dst_stride, 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006234
6235 predict_b_extend(cpi, td, tile, 0, mi_row, mi_col + hbs, mi_row,
6236 mi_col + hbs, mi_row_top, mi_col_top, dst_buf1,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006237 dst_stride1, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006238 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row, mi_col + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006239 mi_row_top, mi_col_top, dry_run, dst_buf1, dst_stride1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006240
6241 predict_b_extend(cpi, td, tile, 0, mi_row + hbs, mi_col + hbs,
6242 mi_row + hbs, mi_col + hbs, mi_row_top, mi_col_top,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006243 dst_buf2, dst_stride2, top_bsize, bsize2, dry_run, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006244 extend_all(cpi, td, tile, 0, bsize2, top_bsize, mi_row + hbs,
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006245 mi_col + hbs, mi_row_top, mi_col_top, dry_run, dst_buf2,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006246 dst_stride2);
6247
6248 for (i = 0; i < MAX_MB_PLANE; i++) {
6249 xd->plane[i].dst.buf = dst_buf1[i];
6250 xd->plane[i].dst.stride = dst_stride1[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006251 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006252 xd, dst_buf1[i], dst_stride1[i], dst_buf2[i], dst_stride2[i],
6253 mi_row, mi_col, mi_row_top, mi_col_top, bsize, top_bsize,
6254 PARTITION_HORZ, i);
6255 }
6256 for (i = 0; i < MAX_MB_PLANE; i++) {
6257 xd->plane[i].dst.buf = dst_buf[i];
6258 xd->plane[i].dst.stride = dst_stride[i];
Yaowu Xuf883b422016-08-30 14:01:10 -07006259 av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07006260 xd, dst_buf[i], dst_stride[i], dst_buf1[i], dst_stride1[i], mi_row,
6261 mi_col, mi_row_top, mi_col_top, bsize, top_bsize, PARTITION_VERT,
6262 i);
6263 }
6264 break;
6265#endif // CONFIG_EXT_PARTITION_TYPES
6266 default: assert(0);
6267 }
6268
6269#if CONFIG_EXT_PARTITION_TYPES
6270 if (bsize < top_bsize)
6271 update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
6272#else
6273 if (bsize < top_bsize && (partition != PARTITION_SPLIT || bsize == BLOCK_8X8))
6274 update_partition_context(xd, mi_row, mi_col, subsize, bsize);
6275#endif // CONFIG_EXT_PARTITION_TYPES
6276}
6277
Urvang Joshi52648442016-10-13 17:27:51 -07006278static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006279 const TileInfo *const tile, int mi_row, int mi_col,
6280 BLOCK_SIZE bsize, int *tmp_rate, int64_t *tmp_dist,
6281 TX_TYPE *best_tx, PC_TREE *pc_tree) {
Urvang Joshi52648442016-10-13 17:27:51 -07006282 const AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006283 MACROBLOCK *const x = &td->mb;
6284 MACROBLOCKD *const xd = &x->e_mbd;
6285 int plane, pnskip, skippable, skippable_uv, rate_uv, this_rate,
6286 base_rate = *tmp_rate;
6287 int64_t sse, pnsse, sse_uv, this_dist, dist_uv;
6288 uint8_t *dst_buf[3];
6289 int dst_stride[3];
6290 TX_SIZE tx_size;
6291 MB_MODE_INFO *mbmi;
6292 TX_TYPE tx_type, best_tx_nostx;
6293#if CONFIG_EXT_TX
6294 int ext_tx_set;
6295#endif // CONFIG_EXT_TX
6296 int tmp_rate_tx = 0, skip_tx = 0;
6297 int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
6298
6299 set_skip_context(xd, mi_row, mi_col);
6300 set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006301 update_state_sb_supertx(cpi, td, tile, mi_row, mi_col, bsize, 1, pc_tree);
Yaowu Xuf883b422016-08-30 14:01:10 -07006302 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006303 for (plane = 0; plane < MAX_MB_PLANE; plane++) {
6304 dst_buf[plane] = xd->plane[plane].dst.buf;
6305 dst_stride[plane] = xd->plane[plane].dst.stride;
6306 }
Debargha Mukherjeeceebb702016-10-11 05:26:50 -07006307 predict_sb_complex(cpi, td, tile, mi_row, mi_col, mi_row, mi_col, 1, bsize,
Yaowu Xuc27fc142016-08-22 16:08:15 -07006308 bsize, dst_buf, dst_stride, pc_tree);
6309
6310 set_offsets_without_segment_id(cpi, tile, x, mi_row, mi_col, bsize);
6311 set_segment_id_supertx(cpi, x, mi_row, mi_col, bsize);
6312
6313 mbmi = &xd->mi[0]->mbmi;
6314 best_tx_nostx = mbmi->tx_type;
6315
6316 *best_tx = DCT_DCT;
6317
6318 // chroma
6319 skippable_uv = 1;
6320 rate_uv = 0;
6321 dist_uv = 0;
6322 sse_uv = 0;
6323 for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
6324#if CONFIG_VAR_TX
6325 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6326 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6327 const struct macroblockd_plane *const pd = &xd->plane[plane];
6328 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006329 RD_STATS this_rd_stats;
Angie Chiangc0feea82016-11-03 15:36:18 -07006330 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006331
6332 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006333 tx_size =
6334 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006335 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006336 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
6337
Yaowu Xuf883b422016-08-30 14:01:10 -07006338 av1_subtract_plane(x, bsize, plane);
6339 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, plane, 0,
Angie Chiangb5dda482016-11-02 16:19:58 -07006340 get_plane_block_size(bsize, pd), coeff_ctx,
6341 &this_rd_stats);
6342
6343 this_rate = this_rd_stats.rate;
6344 this_dist = this_rd_stats.dist;
6345 pnsse = this_rd_stats.sse;
6346 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006347#else
6348 tx_size = max_txsize_lookup[bsize];
Debargha Mukherjee2f123402016-08-30 17:43:38 -07006349 tx_size =
6350 uv_txsize_lookup[bsize][tx_size][cm->subsampling_x][cm->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07006351 av1_subtract_plane(x, bsize, plane);
6352 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6353 &pnsse, INT64_MAX, plane, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006354#endif // CONFIG_VAR_TX
6355
6356 rate_uv += this_rate;
6357 dist_uv += this_dist;
6358 sse_uv += pnsse;
6359 skippable_uv &= pnskip;
6360 }
6361
6362 // luma
6363 tx_size = max_txsize_lookup[bsize];
Yaowu Xuf883b422016-08-30 14:01:10 -07006364 av1_subtract_plane(x, bsize, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006365#if CONFIG_EXT_TX
6366 ext_tx_set = get_ext_tx_set(tx_size, bsize, 1);
6367#endif // CONFIG_EXT_TX
6368 for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
6369#if CONFIG_VAR_TX
6370 ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
6371 ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
6372 const struct macroblockd_plane *const pd = &xd->plane[0];
6373 int coeff_ctx = 1;
Angie Chiangb5dda482016-11-02 16:19:58 -07006374 RD_STATS this_rd_stats;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006375#endif // CONFIG_VAR_TX
Angie Chiangb5dda482016-11-02 16:19:58 -07006376
Yaowu Xuc27fc142016-08-22 16:08:15 -07006377#if CONFIG_EXT_TX
6378 if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
6379#else
6380 if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
6381#endif // CONFIG_EXT_TX
6382 mbmi->tx_type = tx_type;
6383
6384#if CONFIG_VAR_TX
Angie Chiangc0feea82016-11-03 15:36:18 -07006385 av1_init_rd_stats(&this_rd_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006386
Yaowu Xuf883b422016-08-30 14:01:10 -07006387 av1_get_entropy_contexts(bsize, tx_size, pd, ctxa, ctxl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006388 coeff_ctx = combine_entropy_contexts(ctxa[0], ctxl[0]);
Angie Chiangb5dda482016-11-02 16:19:58 -07006389 av1_tx_block_rd_b(cpi, x, tx_size, 0, 0, 0, 0, bsize, coeff_ctx,
6390 &this_rd_stats);
6391
6392 this_rate = this_rd_stats.rate;
6393 this_dist = this_rd_stats.dist;
6394 pnsse = this_rd_stats.sse;
6395 pnskip = this_rd_stats.skip;
Yaowu Xuc27fc142016-08-22 16:08:15 -07006396#else
Yaowu Xuf883b422016-08-30 14:01:10 -07006397 av1_txfm_rd_in_plane_supertx(x, cpi, &this_rate, &this_dist, &pnskip,
6398 &pnsse, INT64_MAX, 0, bsize, tx_size, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006399#endif // CONFIG_VAR_TX
6400
6401#if CONFIG_EXT_TX
6402 if (get_ext_tx_types(tx_size, bsize, 1) > 1 &&
6403 !xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
6404 if (ext_tx_set > 0)
6405 this_rate +=
6406 cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
6407 }
6408#else
6409 if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
6410 this_rate != INT_MAX) {
6411 this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
6412 }
6413#endif // CONFIG_EXT_TX
6414 *tmp_rate = rate_uv + this_rate;
6415 *tmp_dist = dist_uv + this_dist;
6416 sse = sse_uv + pnsse;
6417 skippable = skippable_uv && pnskip;
6418 if (skippable) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006419 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006420 x->skip = 1;
6421 } else {
6422 if (RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist) <
6423 RDCOST(x->rdmult, x->rddiv, 0, sse)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07006424 *tmp_rate += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006425 x->skip = 0;
6426 } else {
6427 *tmp_dist = sse;
Yaowu Xuf883b422016-08-30 14:01:10 -07006428 *tmp_rate = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07006429 x->skip = 1;
6430 }
6431 }
6432 *tmp_rate += base_rate;
6433 rd_tx = RDCOST(x->rdmult, x->rddiv, *tmp_rate, *tmp_dist);
6434 if (rd_tx < bestrd_tx * 0.99 || tx_type == DCT_DCT) {
6435 *best_tx = tx_type;
6436 bestrd_tx = rd_tx;
6437 tmp_rate_tx = *tmp_rate;
6438 tmp_dist_tx = *tmp_dist;
6439 skip_tx = x->skip;
6440 }
6441 }
6442 *tmp_rate = tmp_rate_tx;
6443 *tmp_dist = tmp_dist_tx;
6444 x->skip = skip_tx;
6445#if CONFIG_VAR_TX
6446 for (plane = 0; plane < 1; ++plane)
6447 memset(x->blk_skip[plane], x->skip,
6448 sizeof(uint8_t) * pc_tree->none.num_4x4_blk);
6449#endif // CONFIG_VAR_TX
6450 xd->mi[0]->mbmi.tx_type = best_tx_nostx;
6451}
6452#endif // CONFIG_SUPERTX